Files
monlet/docs/ops/token-rotation.md
2026-05-27 10:01:59 +04:00

2.0 KiB
Raw Blame History

Token rotation

Monlet v1 uses a single shared Bearer token (MONLET_AUTH_TOKEN) for all agent and UI endpoints (ADR-0007). Per-agent tokens and dual-token acceptance are out of scope for v1.

Why rotation is disruptive in v1

The server validates exactly one token at a time. Agents that present the old token after the server has switched receive 401, which the agent treats as a non-retryable failure and drops the affected batch from its local spool (agent/internal/client/client.go, agent/internal/app/app.go). Events flushed during the mismatch window are lost — they are not re-spooled and not re-sent.

Plan rotations during a low-traffic window and either stop the agents first (so spooled events persist on disk until they restart with the new token) or accept the event-loss window.

When to rotate

  • A suspected leak (token committed, log exposure, lost laptop with config.toml).
  • Operator turnover.
  • Routine schedule (e.g., quarterly).

Procedure

  1. Generate a new token:

    openssl rand -hex 32
    
  2. Stop or pause agents (recommended). Either:

    • systemctl stop monlet-agent on each host; spooled events remain on disk and replay after restart, or
    • skip this step and accept that any events sent during steps 34 are lost on the 401.
  3. Restart server with the new MONLET_AUTH_TOKEN. Verify:

    curl -sf -H "Authorization: Bearer $NEW" http://server:8000/api/v1/agents | jq .
    
  4. Update agent config.toml ([server].token) on each host and start agents.

  5. Update Web UI (MONLET_API_TOKEN) and restart.

  6. Revoke the old token: remove the old value from secret stores, CI variables, and operator notes.

Notes

  • The token is the only auth in v1; protect it like a database password.
  • The token never appears in metrics labels, incident keys, or notification labels (ADR-0007, redaction policy).
  • The server redacts Authorization/Cookie-style headers before logging (monlet_server/redaction.py).