Decisión: Activar enforcement del Bearer local del Agent (Raíz 3 cerrada)
Resumen
Fecha: 2026-06-11 (Sesión 129)
Cierre: Raíz 3 de la Auditoría Suprema (dominio terminal del Agent local)
Versión Agent: 2.1.1 → 2.1.2
Status: ✅ Implementado y verificado E2E
El enforcement del Bearer local (AGENT_LOCAL_AUTH_ENFORCE) pasa de OFF (default en 2.1.1, por prudencia) a ON (default en 2.1.2, tras verificación completa del circuito E2E).
Contexto: por qué decidimos esperar en 2.1.1
La Fase 3 de auth local del Agent requería que:
- El Agent deposite su token en el SaaS (servidor CreaRack) durante el registro/vinculación.
- El frontend (navegador del tenant) solicite ese token vía
GET /api/agent/local-token(sesión autenticada + permisofleet:view). - El frontend inyecte el token como
Beareren llamadas HTTP locales al Agent (puerto 5050). - El Agent valide ese Bearer antes de procesar comandos.
En 2.1.1 (s128), activamos (1) pero dejamos (4) opcional — el Agent aceptaba llamadas sin Bearer. Razón: detectamos un bug en el interceptor del frontend (agente_auth.js) que hacía fallar el paso (2). Si hubiera sido obligatorio, se habría bloqueado todo en cascada.
Decisión en 2.1.2
Tras verificar E2E que el circuito funciona:
- ✅ El Agent deposita el token durante
connector._register_local_token(). - ✅ El SaaS lo custodia y lo entrega solo a la sesión del tenant propietario.
- ✅ El frontend lo recupera sin errores (bug del interceptor corregido).
- ✅ El Agent lo valida y acepta llamadas legítimas.
- ✅ Se rechaza acceso desde JavaScript malicioso en el navegador (sin token válido).
Consecuencia: activamos AGENT_LOCAL_AUTH_ENFORCE=1 por defecto. Los 12 riesgos ALTA de la Raíz 3 se cierran:
| Riesgo | Mitigación |
|---|---|
DNS-rebinding (navegador abre http://127.0.0.1:5050) | Exige Bearer válido del SaaS. |
| CSRF (formulario en web ajena + navegador con sesión del tenant) | Exige Bearer en cada petición (CSRF no lo roba). |
| Navegador malicioso ejecutando comandos locales | Sin Bearer de la sesión legítima, rechazado. |
Escape hatch (marcha atrás sin recompilar)
Si un cliente experimentara un problema con el circuito:
AGENT_LOCAL_AUTH_ENFORCE=0
Desactiva la exigencia del Bearer sin perder el depósito del token. El Agent sigue custodiándolo, pero no lo valida (postura defensiva temporal, p.ej. durante troubleshooting).
Cambios técnicos
terminal/agent/core/local_token.py
# Antes (2.1.1):
LOCAL_AUTH_ENFORCE = os.environ.get("AGENT_LOCAL_AUTH_ENFORCE", "").strip().lower() in ("1", "true", "yes", "on")
# Default: OFF (False)
# Ahora (2.1.2):
LOCAL_AUTH_ENFORCE = os.environ.get("AGENT_LOCAL_AUTH_ENFORCE", "1").strip().lower() not in ("0", "false", "no", "off")
# Default: ON (True) — escape con "=0"
static/js/modules/agent_auth.js (bug fix)
// Antes (2.1.1):
const agentId = (info.saas_info && info.saas_info.agent_id) || info.agent_id;
// info.saas_info era undefined → agentId = undefined → token = null → 401 con enforcement ON
// Ahora (2.1.2):
const agentId = (info.saas && info.saas.agent_id) || info.agent_id;
// Léxicamente, /info expone el agent_id bajo la clave `saas` (health.py _get_debug_info)
Verificación pre-deployment
- ✅ 7 tests verdes en
tests/agent/test_agent_local_auth.py:test_auth_required_on_by_default(): verifica que el flag está ON.test_auth_required_escape_hatch(): verifica que=0lo desactiva.
- ✅ Ruff linting: sin errores.
- ✅ E2E en Docker: status 200 + token entregado correctamente.
Impacto operacional
Para los clientes:
- El Agent sigue funcionando si ya tiene un token depositado (caso normal).
- Si hay problemas,
AGENT_LOCAL_AUTH_ENFORCE=0es la marcha atrás (sin recompilar). - El SaaS debe haber desplegado la corrección del interceptor antes de publicar el Agent 2.1.2.
Para el equipo de Edu (build + release):
- Esperar a que crearack.com despliegue (agent_auth.js corregido).
- Ejecutar
build_agent.bat(genera 2.1.2). - Smoke tests: dashboard + consola SSH + discovery.
- Publicar
agent-v2.1.2, borrar versión anterior.
Cierre de auditoría
Raíz 3 (dominio terminal del Agent local) pasa de ABIERTA a CERRADA:
- ✅ 12 ALTA (DNS-rebinding, CSRF, navegador malicioso) → mitigados.
- ✅ Circuito E2E verificado.
- ✅ Tests + linting + E2E + escape hatch documentados.
Véase también
- [[concept—saas—multi-tenancy]]
- [[entity—terminal—service—agente-auth-local]]
- [[runbook—agent—bearer-token-troubleshooting]]
- [[incident—20260610—agent-2-1-1-interceptor-bug]]
- [[concept—security—dns-rebinding-csrf]]