¿Cómo detecta el frontend si el Local Agent está corriendo? ¿Cómo se construye la URL del agente (localhost:5050) y qué CORS/orígenes acepta el agente local?
Pregunta
¿Cómo detecta el frontend si el Local Agent está corriendo? ¿Cómo se construye la URL del agente (localhost:5050) y qué CORS/orígenes acepta el agente local?
Respuesta corta
El frontend hace un fetch a http://127.0.0.1:5050/info (o /). Si responde, el Agente está vivo y del JSON saca el agent_id para el bootstrap. Si el fetch falla (conexión rechazada), no hay Agente corriendo.
Detección
GET /infodevuelve JSON con{version, saas:{authenticated, agent_id, saas_url}, sentinel, sessions…}(terminal/agent/routes/health.py). Es un endpoint de bootstrap exento (EXEMPT_PATHS): no exige el token local, porque su función es precisamente arrancar el circuito.- Importante (sa4-G3): el payload anónimo de
/e/infoNO incluyetenant_id, soloagent_id(health.py:37-44). Servir el par{agent_id, tenant_id}sin token alimentaba un bypass de reauth (sa2-G1). El interceptor del frontend solo necesitaagent_id.
Construcción de la URL y CORS
- La URL es fija:
http://127.0.0.1:5050(equivalentehttp://localhost:5050). No se descubre por red — el Agente siempre escucha en el loopback del propio PC del usuario. - CORS: el Agente solo acepta orígenes permitidos (
allowed_origins_for,core/local_token.py): el SaaS al que está vinculado (p.ej.https://crearack.com) más el Docker dev-local (http://localhost:8000/http://127.0.0.1:8000).allow_credentials=False. Gracias a incluir el dev-local, un Agente vinculado a producción sigue siendo detectable desde la versión local en Docker (fix 2.3.1). - Mixed-content: la página del SaaS es
httpsy el Agente eshttp://localhost. Los navegadores tratanlocalhost/127.0.0.1como excepción segura (potentially trustworthy origin), así que el fetch no se bloquea por contenido mixto. - PNA/LNA (desde Agent 2.20.1): además del CORS normal, Chromium exige un segundo permiso — Private/Local Network Access — cuando una web pública (
https://crearack.com) llama a una dirección “más privada” como127.0.0.1. El navegador manda un preflight conAccess-Control-Request-Private-Network, y sin el header de respuesta el middleware CORS empaquetado (starlette) contestaba400 "Disallowed CORS private-network"— el emparejamiento moría en silencio. El fix añadeallow_private_network=Trueal middleware (local_token.py, con guarda por firma de starlette para no romper builds con una versión vieja que no soporta el parámetro) y declaratargetAddressSpace: "loopback"en cadafetchdel interceptor (agent_auth.js) — el vocabulario del enum cambió entre especificaciones ("local"en la PNA vieja,"loopback"en la LNA actual), así que se detecta una vez con untry/catchsobre el constructor deRequesty se usa el valor que el navegador acepte.
El primer agente de una organización
El SaaS solo conoce agentes ya registrados (/api/agent/status los consulta en su propia base de datos). Para el primer agente de una org, esa fuente no sirve — el agente ya corre en el PC del usuario pero el SaaS aún no lo ha visto nunca. Antes de Agent 2.20.1, los gestos de emparejamiento (?setup_agent en la URL, botón “Download Agent”) esperaban a que /api/agent/status confirmara el agente online, y ese gate nunca se cumplía para el primero — el emparejamiento inicial era imposible desde el navegador (bug medido en la F2 de Dos Casas).
El fix (ObservatorySentinel.js, función _probeLocalAgent()) añade un sondeo directo a http://127.0.0.1:5050/info en esos mismos gestos con contexto explícito, precisamente para no disparar el aviso de permiso LNA del navegador sin motivo. Si el sondeo local responde 200, se procede al emparejamiento aunque el SaaS todavía no vea el agente registrado.
Tras detectarlo
El frontend obtiene el token local del SaaS (GET /api/agent/local-token) y lo inyecta como Authorization: Bearer en cada llamada a la API local (interceptor agent_auth.js). A partir de ahí puede abrir consolas SSH, lanzar discovery, etc. Ver la página sobre las credenciales del Local Agent.
Véase también
- [[concept—general—terminal-ssh-como-se-conecta-el-navegador-al-local]]
- [[concept—general—como-obtiene-el-local-agent-sus-credenciales-de-vi]]