Seguridad
Cómo se aísla el código de cada tenant, cómo se guardan los secretos, qué permite la red y cómo se controlan el acceso por shell y los tokens de API.
Aislamiento#
Cada servicio corre en su propio sandbox en nodos compartidos:
- gVisor (runtime por defecto) intercepta las syscalls en espacio de usuario, así que el contenedor nunca habla directamente con el kernel del host.
- Kata Containers ejecuta un servicio en una microVM ligera con su propio kernel. Los builds siempre corren en Kata; elígelo para servicios que necesiten un kernel completo (
runtimeClass: kata). - Cada entorno de proyecto es un namespace de Kubernetes con una cuota de recursos. La memoria nunca se sobreasigna; la CPU puede compartirse hasta 3×; la E/S de disco tiene un tope por namespace.
- Solo nuestros componentes de sistema corren con un runtime de contenedores convencional.
Los nodos están en centros de datos de Hetzner en Finlandia (UE). Los datos no salen de la UE.
Red#
- Los namespaces están aislados con una política de red de denegación por defecto: los servicios de proyectos distintos no pueden alcanzarse entre sí; los servicios de entornos distintos del mismo proyecto tampoco.
- El tráfico entrante llega a un servicio solo a través de sus dominios públicos (TLS terminado en el edge) o de un proxy TCP que hayas creado explícitamente.
- El tráfico saliente está abierto salvo el puerto 25 (SMTP): usa una API de correo o el puerto de envío de un proveedor (587) con autenticación.
- Los nodos aceptan conexiones entrantes solo en 80, 443, SSH para operadores y el rango de los proxies TCP.
Secretos y variables#
Los valores de las variables se cifran en reposo con AES-256-GCM; la clave vive solo en el entorno del plano de control, no en la base de datos. Los valores se descifran cuando se renderiza un despliegue y se pasan al nodo por un WebSocket autenticado que el propio nodo abrió (los nodos no tienen puerto de API entrante). El panel muestra los valores a los miembros del espacio de trabajo; la CLI y el servidor MCP los enmascaran por defecto.
Los logs del build y los logs de runtime se guardan tal como tu proceso los escribió: no imprimas secretos.
Cuentas y tokens#
- El inicio de sesión es únicamente con OAuth de GitHub; no hay contraseñas que se puedan filtrar.
- Roles del espacio de trabajo:
owner,admin,member. Facturación, tokens y miembros requierenadmin. - Los tokens de API se guardan con hash, se muestran una sola vez, están acotados a un espacio de trabajo con
readowritey pueden tener fecha de expiración. Los tokens de proyecto están acotados a un entorno y no pueden leer la facturación ni otros proyectos. - Cada mutación se escribe en el registro de auditoría del espacio de trabajo con actor, destino e IP.
Acceso por shell#
skiffly ssh y la pestaña Terminal abren un shell dentro de un contenedor en ejecución de tu servicio. La sesión va de tu cliente a la API por WebSocket con tu token, y de la API al nodo por la conexión propia del nodo; el contenedor nunca se expone a internet. Las sesiones requieren el rol member (y el scope write en el caso de los tokens), se limitan a cinco por usuario y 30 minutos de inactividad, y quedan en el registro de auditoría como service.exec.
GitHub#
Los repositorios privados se clonan con tokens de instalación de corta duración de la GitHub App de Skiffly; no se guarda ningún personal access token. Los pull requests desde forks nunca se despliegan en entornos de vista previa.
Respaldos#
Los volúmenes se respaldan a diario mediante snapshots en almacenamiento de objetos cifrado y alojado en la UE, con retención 7/4/3 (diaria/semanal/mensual); Postgres y MySQL reciben además dumps lógicos en la misma ejecución. Por ahora, las restauraciones se hacen a través de soporte. Ver Volúmenes y bases de datos.
Reportar#
¿Encontraste algo? Escribe a security@skiffly.dev. Por favor, no hagas pruebas contra los servicios de otros clientes.