Volver a la wiki

Endpoint: POST /api/agent/register-local-token (Agent deposita token local cifrado)

Resumen

Endpoint que permite al Agent depositar de forma segura su token de autenticación para la API HTTP local (localhost:5050). El token se cifra con CredentialManager (Fernet) antes de guardarse en AgentInstance.local_token_enc.

Inerte en Fase 1: ningún cliente lo usa hasta la Fase 2 (frontend) y Fase 3 (Agent .exe).

Especificación

Ruta

POST /api/agent/register-local-token

Autenticación

Request Body

{
  "local_token": "string"  // token opaco generado por el Agent (p.ej. UUID o JWT local)
}

Response

200 OK (éxito):

{
  "status": "stored"
}

400 Bad Request (falta local_token):

{
  "error": "Missing local_token"
}

401 Unauthorized (JWT inválido/expirado, o refresh token en lugar de access token):

{
  "error": "Invalid or expired token"
}

404 Not Found (Agent no existe en BD):

{
  "error": "Agent not found"
}

Implementación

Fichero

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

Sub-componentes

  1. get_agent_from_request(request) — helper compartido que extrae y valida el Agent JWT.

    • Rechaza refresh tokens (solo access tokens autentican datos del Agent).
    • Devuelve dict con agent_id, org_id, etc., o None si es inválido.
  2. CredentialManager.encrypt_credential(local_token) — cifra con Fernet.

    • Fuente: core.security.credential_manager (Plan Hardening E).
    • Garantiza que el token nunca se guarda en claro.
  3. Salvaguarda en base de datos: agent.local_token_enc = ... + agent.save(update_fields=[...]).

    • Actualiza solo local_token_enc y updated_at (efficient update).
  4. Logging: logger.info(f"Local token registered for agent {agent_id}").

    • Auditoría sin exponer el token.

Flujo

  1. Agent genera un token local (UUID o JWT firmado localmente con su keypair).
  2. Agent obtiene su access token JWT (via POST /api/agent/auth o mantiene uno en sesión).
  3. Agent envía POST /api/agent/register-local-token con:
    • Header: Authorization: Bearer <access_token>
    • Body: {"local_token": "<opaco>"}
  4. Servidor extrae agent_id del JWT.
  5. Servidor busca AgentInstance(agent_id=...).
  6. Servidor cifra el token y lo guarda en local_token_enc.
  7. Servidor responde 200 OK.

Seguridad

Testing

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

Fase 1 — Inerte

Este endpoint no es llamado por ningún cliente hasta:

Véase también

Subir