Skyward es una plataforma de Governance, Risk and Compliance (GRC) construida como un monorepo desplegado en Cloudflare Workers. La arquitectura sigue un modelo local-first con sincronización en tiempo real mediante WebSockets.
Este documento resume la arquitectura técnica relevante para un ejercicio de pentesting sobre la plataforma. El foco está puesto en los límites de confianza, los componentes expuestos, los canales de comunicación en tiempo real y los activos que participan en autenticación, autorización y persistencia.
Users y Contraseñas (Enviados por correo)
La plataforma está organizada como un monorepo desplegado principalmente sobre Cloudflare Workers, con un patrón local-first para el dashboard basado en Zero Sync. Además, existen Cloudflare Durable Objects para agentes de larga duración y Cloudflare Workflows para tareas asíncronas.
Desde una perspectiva de seguridad, los componentes más relevantes son:
- Dashboard: cliente React que consume la API y mantiene un canal de sincronización con Zero.
- API: Worker Hono que expone endpoints HTTP, tRPC legado, endpoints de Zero (
/z/*), archivos y proxy hacia agentes. - Zero Sync: capa de sincronización en tiempo real con almacenamiento local en cliente y reconciliación contra backend.
- Agents service: Worker dedicado que expone agentes por WebSocket y ejecuta lógica stateful sobre Durable Objects.
- Workflows: procesos asíncronos que realizan tareas de larga duración y side effects.
- PostgreSQL / réplica Zero: almacenamiento transaccional principal y la infraestructura de sincronización/réplica usada por Zero.
| Componente | Tecnología |
|---|---|
| Runtime | Cloudflare Workers |
| Frontend | React 19, React Router v7, Tailwind CSS v4 |
| API | Hono (REST) |
| Database | PostgreSQL + Drizzle ORM |
| AI/LLM | Vercel AI SDK + OpenAI |
| Authentication | WorkOS |
| Agents | Cloudflare Durable Objects |
| Background Jobs | Cloudflare Workflows |
| Real-time Sync | Zero Sync (Rocicorp) (Lo unico que no está en cloudflare) |
El dashboard corre en el navegador y mantiene tres interacciones relevantes:
- HTTP autenticado hacia la API para obtener sesión, token de Zero, archivos y endpoints auxiliares.
- Sync engine de Zero para sincronización reactiva y sockets administrados por la librería de Zero (https://zero.rocicorp.dev/docs/queries).
- WebSocket de agentes a través de la API hacia el servicio de agentes, hosteado por Cloudflare Workers (Durable objects), enviando token y contexto de tracing en la conexión.
La API centraliza:
- CORS y validaciones de origen.
- Endpoints de zero
/z/get-queries,/z/pull,/z/mutate,/z/push - Proxy en la ruta
agents/*hacia el servicio dedicado de agentes. - Endpoints de archivos, webhooks, tRPC y 1 REST endpoint.
El servicio de agentes está separado del API Worker principal, API Worker funciona como Proxy de conexión al servico de Agents, el que recibe conexiones WebSocket. Antes de aceptar una conexión se valida que el agente solicitado esté dentro de un allowlist y extrae el token JWT desde query params para observabilidad y contexto.
Información importante de Zero: https://zero.rocicorp.dev/docs/queries
Zero mantiene una copia local de datos en el cliente y sincroniza por canales persistentes con el backend. Las mutaciones pueden ocurrir de forma optimista en cliente y luego confirmarse en servidor. El modelo de confianza depende de:
- un JWT emitido por la API de Skyward (trpc, mediante
zeroToken). - Contexto de usuario/organización embebido en ese token.
- Filtros de tenant y permisos incluidos en queries sincronizadas y mutators.
- Endpoints
mutateyget-queriesde la API.
- PostgreSQL es la fuente de verdad transaccional.
- Zero usa servicios de réplica/sincronización para mantener el motor de vistas sincronizadas.
- Mutadores "compartidos" se ejecutan del lado del, y los server mutators agregan side effects diferidos, (logs, notificaciones, envios de correos, y automatizaciones)
flowchart LR
user[Usuario autenticado]
subgraph browser[Browser / Dashboard React]
dashboard[Dashboard]
localdb[(Cache local Zero\nmem/idb)]
agentHook[Hooks de agentes]
end
subgraph edge[Cloudflare Edge]
api[API Worker\nHono]
agentsProxy[Proxy /agents/*]
agentsSvc[Agents Worker\nDurable Objects]
workflows[Workflows Worker]
end
subgraph zeroInfra[Zero Sync Infra]
zeroServer[Zero Sync Server]
replication[Replication Manager]
viewSyncer[View Syncer]
replica[(Replica / CVR / Change DB)]
end
subgraph data[Data Layer]
postgres[(PostgreSQL)]
files[(Object storage / files)]
external[Servicios externos\nSlack / email / terceros]
end
user --> dashboard
dashboard -->|HTTPS + cookies / JWT| api
dashboard -->|Sync engine / sockets| zeroServer
dashboard --> localdb
agentHook -->|WebSocket con token| api
api --> agentsProxy
agentsProxy --> agentsSvc
api -->|/z/get-queries y /z/mutate| zeroServer
zeroServer --> replica
zeroServer --> postgres
replication --> postgres
replication --> replica
viewSyncer --> replica
viewSyncer --> postgres
api --> postgres
api --> files
api --> external
agentsSvc --> workflows
workflows --> postgres
workflows --> files
workflows --> external
agentsSvc --> external
- Cookie de sesión del dashboard. (Emitida por WorkOS)
- Emisión de
zeroTokenpara sincronización. (Emitida por API Skyward) - Uso de token en query string para agentes WebSocket.
- JWT de Zero con claims de usuario, organización y privilegios.
- Cookies de sesión del dashboard.
- Datos sincronizados localmente en IndexedDB/memoria del navegador.
- Contenido documental, evidencias, resultados de agentes y reportes.
- Datos multi-tenant almacenados en PostgreSQL.
- Señales operacionales enviadas a observabilidad.
- La aplicación utiliza sincronización reactiva y por tanto el cliente puede retener datos localmente más tiempo que una app HTTP tradicional.
- La autorización no vive en un solo punto: se reparte entre tokens, synced queries, mutators compartidos, server mutators y permisos reactivos del dashboard.
- Los agentes y Durable Objects introducen una segunda superficie stateful distinta del motor de sincronización Zero.
Se recomienda incluir explícitamente:
- autenticación y administración de sesión,
- autorización multi-tenant,
- pruebas sobre Zero Sync y su canal de sockets,
- pruebas sobre Durable Objects y WebSockets de agentes,
- revisión de exposición de archivos/evidencias,
- validación de SSRF, IDOR, privilege escalation y replay en endpoints asíncronos,
- validación de persistencia local de datos sensibles en navegador.