Secure Runtime Config

Estado: vigente desde 2026-05-05

Regla

El repo no debe contener secretos operativos reales. La aplicacion lee configuracion sensible desde variables de entorno o EnvironmentFile de systemd.

VPS

Ruta protegida:


/etc/ops-center/

Archivos:

  • auth.env: usuario bootstrap, token de servicio, proxy/cookie/auth.
  • db.env: conexion PostgreSQL de la app.

Permisos esperados:


root:root 600 /etc/ops-center/auth.env

root:root 600 /etc/ops-center/db.env

Systemd carga esos archivos mediante drop-ins:

  • ops-center.service.d/10-auth-hardening.conf
  • ops-center.service.d/20-db.conf
  • ops-dispatch-launcher.service.d/10-auth-hardening.conf
  • ops-templates-scheduler.service.d/10-db.conf

Variables

DB:


PGHOST=localhost

PGPORT=5432

PGDATABASE=ops_center

PGUSER=ops

PGPASSWORD=<secret>

Auth/servicio:


OPS_ADMIN_USER=<bootstrap-admin>

OPS_ADMIN_PASSWORD=<secret>

OPS_SERVICE_TOKEN=<secret>

OPS_CREDENTIALS_KEY=<base64-32-bytes>

TRUST_PROXY=true

OPS_ADMIN_PASSWORD solo se usa si no existe ningun app_users activo.

OPS_CREDENTIALS_KEY cifra la boveda de credenciales de agentes; no debe rotarse sin re-cifrar los registros existentes.

Rotacion token servicio

  1. Generar token fuerte.
  2. Actualizar /etc/ops-center/auth.env.
  3. Actualizar ops_settings.service_api_token.
  4. systemctl restart ops-center.service ops-dispatch-launcher.service.
  5. Smoke test con X-OPS-Service-Token.

No publicar el token en docs, commits, logs ni tickets.

Boveda de credenciales de agentes

Los usuarios pueden registrar credenciales desde Cuenta y acceso -> Credenciales.

Reglas:

  • El secreto se cifra en agent_credentials.secret_encrypted.
  • La API normal solo devuelve secret_preview y secret_fingerprint.
  • Las credenciales personal pertenecen a un usuario; las credenciales workspace son compartidas y requieren rol admin del workspace para crearse o modificarse.
  • La resolucion automatica por agent_slug solo usa credenciales workspace; una credencial personal solo se inyecta si una tarea/target la referencia de forma explicita.
  • usage separa credenciales de agent, deployment, server, provider y other.
  • Solo llamadas con X-OPS-Service-Token pueden resolver secretos para runtime.
  • El launcher llama a POST /api/agent-credentials/resolve por workspace_id y agent_slug.
  • El launcher inyecta las variables en el proceso hijo, sin escribirlas en logs.

Mapeo por defecto:

  • provider_slug=openai -> OPENAI_API_KEY
  • provider_slug=anthropic|claude -> ANTHROPIC_API_KEY
  • provider_slug=minimax -> MINIMAX_API_KEY
  • provider_slug=google|gemini -> GOOGLE_API_KEY

Se puede forzar otra variable con metadata.env_var.

Datos de despliegue

Los servidores/entornos se gestionan como deployment_targets:

  • Datos visibles: entorno, tipo, host, puerto, usuario, ruta, branch y healthcheck.
  • Se puede asociar una credencial cifrada con credential_id, pero debe ser scope=workspace y usage=deployment|server|other.
  • Las tareas y plantillas pueden referenciar deployment_target_id.
  • El contexto de dispatch recibe datos del target, pero no recibe claves en claro.
  • Si el target tiene credential_id, el launcher tambien solicita esa credencial al resolver env de runtime.

Regla operativa: cualquier tarea de despliegue debe tratarse como accion sensible. El agente debe registrar comandos/resultados y no ejecutar acciones destructivas sin Human Gate.

Tareas de despliegue

Una tarea puede referenciar deployment_target_id.

Cuando hay target:

  • La cola y el detalle muestran badge de despliegue.
  • El detalle muestra checklist derivado del target: alcance, gate, credenciales, rollback/backup, ejecucion, healthcheck y reporte final.
  • POST /api/tasks/:id/dispatch crea o exige Human Gate antes de encolar.
  • GET /api/dispatch/next entrega el checklist al launcher.
  • El launcher incluye ese checklist en el prompt y exige que el resultado final lo refleje en contexto/logs.

Human Gates

Las tareas con deployment_target_id o tags sensibles (prod, production, deploy, deployment, release, server, ssh, security, billing, client-comms, supervision) requieren aprobacion humana antes de entrar en dispatch.

Flujo:

  1. POST /api/tasks/:id/dispatch crea/retorna un gate pendiente y responde 409 human_gate_required si falta aprobacion.
  2. Admin o servicio aprueba con POST /api/tasks/:id/human-gate/approve.
  3. La aprobacion caduca segun ops_settings.human_gate_approval_hours (24h por defecto).
  4. GET /api/dispatch/next y POST /api/dispatch/claim ignoran o bloquean tareas sensibles sin gate aprobado.

Auditoria

Las operaciones sensibles escriben eventos append-only en audit_events.

Incluye:

  • Invitaciones creadas, aceptadas y revocadas.
  • Usuarios, empresas, workspaces y miembros.
  • Credenciales creadas, rotadas/actualizadas y revocadas.
  • Deployment targets creados, actualizados y eliminados.
  • Human Gates solicitados, aprobados y rechazados.
  • Dispatch encolado, completado o fallido.
  • Cambios de settings.

La auditoria no almacena secretos: campos con nombres tipo secret, token, password, key, credential, hash o encrypted se redactan en metadata.

Consulta:

  • GET /api/audit-events devuelve eventos del workspace activo para roles admin u owner.
  • include_global=true solo funciona para administradores de plataforma.
  • La interfaz Cuenta y acceso -> Auditoria permite filtrar por accion, entidad, texto y limite.

Las migraciones de esquema con claves foraneas deben ejecutarse con rol propietario/superusuario (postgres) y APP_DB_ROLE=ops para dejar grants correctos al usuario de aplicacion.