Pregunta
¿Cómo obtiene el Local Agent sus credenciales de vinculación con el SaaS al instalarse? ¿El .exe descargado lleva un token embebido? ¿Qué es el token local “not authorized” y cómo se autoriza un Agente recién instalado (register-local-token / local-token)?
Respuesta corta
El .exe no lleva ningún token embebido — es un binario genérico, idéntico para todos. Al instalarse no está vinculado a nadie. La vinculación la hace el navegador (con tu sesión de CreaRack) pasándole al Agente un JWT recién acuñado. Y ojo: hay dos tokens distintos que conviene no confundir.
Vinculación: cómo obtiene el JWT del SaaS
- Descargas e instalas el
.exe(genérico, sin credenciales). - Desde el Observatory, el navegador logueado acuña el JWT del Agente:
POST /api/agent/register(terminal/api/auth.py:122) exige sesión Django + que tu organización == el tenant → devuelve un access token + refresh token. - El navegador se lo entrega al Agente:
POST /saas/setup {token, refresh_token, saas_url}(terminal/agent/routes/saas.py:134). El Agente valida quesaas_urlcoincide con elOriginde la petición (anti-secuestro, sa4-G1), decodifica el JWT para sacaragent_id/tenant_idy llama aconfigure_from_login. - Almacenamiento: el
AuthManagercifra los tokens con Windows DPAPI en disco (terminal/agent/core/auth.py:118,CREDENTIALS_FILE) — atados a tu cuenta de Windows. A partir de ahí el Agente se reautentica solo (refresh proactivo + Layer 3).
El token local (“not authorized”)
Es otro token distinto, no el JWT del SaaS. Es la llave de la API HTTP local del Agente (127.0.0.1:5050):
- El Agente lo genera (
secrets.token_urlsafe(32)), lo cifra con DPAPI y lo deposita en el SaaS en cada conexión:POST /api/agent/register-local-token(elagent_idsale del token, no del body). - El frontend lo recoge del SaaS:
GET /api/agent/local-token(sesión +require_perm(fleet, view); solo la sesión del tenant dueño lo recibe) y lo manda comoAuthorization: Beareren cada llamada a la API local. - Si el navegador llama a la API local sin ese Bearer → 401 “not authorized”. Se autoriza solo en cuanto el circuito depositar → recoger → inyectar se completa.
- Por qué existe: cierra el DNS-rebinding/CSRF (Raíz 3). Sin ese token, cualquier web que visitaras podría pilotar tu Agente local (ejecutar comandos, SFTP, etc.). Solo quedan exentas (
EXEMPT_PATHS) las rutas de bootstrap y de estado de solo lectura.
Los dos tokens de un vistazo
| Token | Protege | Dónde se guarda |
|---|---|---|
| JWT del SaaS | Identifica al Agente ante el SaaS (WebSocket + REST) | DPAPI en disco del Agente |
| Token local | Protege la API del Agente ante el navegador | DPAPI en disco + depositado (cifrado Fernet) en el SaaS |
Véase también
- [[concept—general—terminal-ssh-como-se-conecta-el-navegador-al-local]]
- [[concept—general—como-detecta-el-frontend-si-el-local-agent-esta-co]]
Referenciado desde
- ¿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?
- Terminal SSH: como se conecta el navegador al Local Agent en localhost:5050 y como se establece la sesion SSH via WebSocket ws/terminal? Protocolo crearack:// y persistencia de sesiones.