Volver a la wiki

Endpoint: GET /api/agent/local-token (Frontend recoge token local descifrado)

Resumen

Endpoint que permite al frontend web (usuario logueado) recuperar el token de autenticación local de un Agent perteneciente a su misma organización. El token se devuelve descifrado, listo para que el frontend lo use en requests a localhost:5050.

Aislamiento multi-tenant: solo usuarios de la misma organización que el Agent pueden acceder a su token.

Inerte en Fase 1: el frontend aún no lo llama.

Especificación

Ruta

GET /api/agent/local-token?agent_id=<agent_id>

Autenticación

Query Parameters

Response

200 OK (éxito):

{
  "local_token": "<opaco>"  // token descifrado (era local_token_enc en BD)
}

403 Forbidden (sin sesión, sin permiso, o no es tu organización):

{
  "error": "Session authentication required"  // o "No organization in context"
}

404 Not Found (Agent no existe en tu org, o no ha depositado token aún):

{
  "error": "Agent not found"  // o "Agent has not registered a local token yet"
}

Implementación

Fichero

terminal/api/auth.py (líneas ~240–260, commit 61b0447).

Sub-componentes

  1. Portero global de sesión:

    • Verifica request.user logueado.
    • Rechaza requests anónimos (status 403).
  2. require_perm(request, "fleet", "view"):

    • Verifica que el usuario tenga permiso explícito.
    • Lanza excepción si falta (capturada por Django Ninja → 403).
  3. get_current_org(request):

    • Extrae la organización del usuario (o del contexto de la sesión).
    • Devuelve None si no hay org (response 403).
  4. Aislamiento por organización:

    agent = AgentInstance.objects.get(agent_id=agent_id, organization=org)
    • QuerySet filtrado por org del usuario (RLS efectivo).
    • Si el Agent pertenece a OTRA org, DoesNotExist → 404.
  5. Desciframiento:

    CredentialManager.decrypt_credential(agent.local_token_enc)
    • Usa la misma CredentialManager que cifró (Fernet simétrico).
    • Devuelve el token en claro (seguro: solo navegador web logueado lo recibe).
  6. Validación de existencia:

    • Si agent.local_token_enc está vacío, devuelve 404 (Agent no ha depositado token).

Flujo

  1. Frontend web (usuario logueado en sesión) quiere acceder al Agent local.
  2. Frontend envía GET /api/agent/local-token?agent_id=ag_xyz.
  3. Servidor verifica sesión + fleet:view + que ag_xyz sea del usuario.
  4. Servidor descifra AgentInstance.local_token_enc.
  5. Servidor responde con el token en claro.
  6. Frontend guarda el token en sesión/memoria y lo usa en requests a localhost:5050.

Seguridad

Testing

Cubierto en tests/api/test_terminal_local_token.py::TestGetLocalToken:

Fase 1 — Inerte

Este endpoint no es llamado por el frontend hasta la Fase 2, cuando se actualice la lógica de conexión local en la web.

Véase también

Subir