Skip to main content

Module agent_tokens

Module agent_tokens 

Source
Expand description

Per-agent local identity token, keyed by the agent’s UID (db_agents.id).

Identity M1 of docs/specs/SPEC_AGENT_IDENTITY_CARRIED_NOT_DERIVED_2026_09_23.md (§6, §9.1). See db_agent_tokens in migrations.rs (OBJECT_SCHEMA_VERSION v37).

What it is. A secret the server generates for one agent and hands to that agent’s process environment at spawn (AGENTMUX_AGENT_TOKEN, set by build_persistent_spawn_env). Only the server and the agent it spawned ever hold the value, which is what will let a later phase (M4) map token → UID on a request and treat that as the caller’s identity, instead of trusting an agent_id the request body asserts. Spec §2 rule 2: identity is proven, not asserted.

What it is not. Not the cloud Cognito M2M credential in muxbus/agent_credentials.rs — that one needs a prior human login and falls back to a shared token by design, both of which disqualify it (spec §0.3). This is minted locally, with no network and no fallback.

Lifetime. Long-lived for the agent’s lifetime and revoked when the agent is deleted (purge_agent_dependents), never renewed on a timer: spec §6.3 — expiry mid-task turns a healthy agent silent, and renewal is a liveness dependency on the very path being secured. Persisted here, in the server’s own store, so an srv restart does not strand every running agent with a token nothing can verify (same section). This is the server persisting its own secret where only the server reads it — not a name-keyed, agent-readable file in shared space, which §6.3 rules out.

Keyed by UID, not name. db_agent_jekt_keys and the registry entry files are keyed by display name, so two agents sharing a name share one credential (spec §6.3). This table cannot have that defect: db_agents.id is a PRIMARY KEY, and every non-template row is a UUID.

Read since M4a through TokenIndex: a request carrying X-Agent-Token is attributed to the UID the token was minted for (spec §6.5.3). Attribution only — an unknown token is treated as absent, never refused.

Structs§

TokenIndex
token → UID, in memory, so attributing a request never reads the store (spec §10.1). Attached to the channel’s object store only (Store::attach_token_index) and kept in step with db_agent_tokens by the two statements that change it — mint (agent_token_ensure) and revoke (purge_agent_dependents) — each under the store’s connection lock, so the index never disagrees with a committed row (spec §6.5.3: purge is a sequence of autocommit statements, not a transaction, so the index follows the token statement itself, not the purge’s result).
TokenMaps 🔒

Functions§

random_token 🔒
32 bytes of CSPRNG randomness from random_seed_bytes, hex-encoded (64 chars); hex rather than base64 so the value is safe in any environment-variable or shell context without quoting.