Skip to main content

Module agent_credentials

Module agent_credentials 

Source
Expand description

Per-agent M2M Cognito credential fetch/cache — the client side of per-agent credential binding (the relay side is designed in the private cloud repo).

Historically every agent under one AgentMux login shared the same account-level MUXBUS_TOKEN for every /reactive/* call. This module gets each agent its own bound Cognito client_credentials identity instead:

  1. provision_agent_client(): calls POST /agents/provision using the human’s own PKCE token, receiving a Cognito client_id/client_secret scoped to exactly this (account, agent_id) pair. One-time per agent (idempotent server-side; cached locally in db_agent_credentials).
  2. ensure_agent_credential(): returns a live access_token for that agent, provisioning on first use and re-fetching via client_credentials whenever the cached token has expired. A client the cloud no longer recognizes is dropped and re-provisioned (CredentialFailure::Unrecognized).

Callers (cloud_subscriber.rs) fall back to the shared MUXBUS_TOKEN whenever this returns None — provisioning failure must never block message delivery; that agent simply uses the account-level token.

Enums§

CredentialFailure 🔒
A failed provisioning or token fetch, split by what it says about the stored credential (docs/specs/SPEC_CLOUD_SETTINGS_DISCOVERY_2026_09_27.md §3.4).

Constants§

CREDENTIAL_HTTP_TIMEOUT 🔒
Per-request timeout for the two HTTP calls in this module. The shared http client (built via reqwest::Client::new() in cloud_subscriber::run_loop) carries no default timeout, and both calls here are awaited inline in the per-agent InjectAvailable loop — without an explicit override, a stalled provisioning or Cognito token endpoint would hang the whole loop indefinitely, blocking pings and delivery for every OTHER registered agent too. reagentx P1 on PR #2342.
CREDENTIAL_RETRY_COOLDOWN 🔒
How long to skip re-attempting this agent’s credential pipeline (provisioning OR token fetch) after either step fails, before trying again. InjectAvailable broadcasts for ANY injection to ANY agent, so without this an agent whose pipeline can’t currently succeed (quota exceeded, malformed agent_id, provisioning/token endpoint down) gets a fresh network round-trip on every single broadcast — an unthrottled retry storm, unlike the broker’s single-flight-guarded scheduler used for the shared token. reagentx P2 on PR #2342 (round 1: provisioning only; round 2: also covers fetch_m2m_token, the gap round 1 left open for an already-provisioned agent whose token endpoint is failing).

Statics§

CREDENTIAL_COOLDOWN 🔒

Functions§

credential_cooldown 🔒
credential_recently_failed 🔒
drop_unrecognized_credential 🔒
Delete this agent’s stored credential when the cloud no longer recognizes its client, so the next use re-provisions instead of retrying the dead one every cooldown forever.
ensure_agent_credential
Get a live per-agent access token, provisioning the Cognito client on first use. Returns None (never an error) on any failure — provisioning being down or an agent not yet migrated must degrade to the caller’s shared-token fallback, not block delivery.
ensure_agent_credential_at 🔒
ensure_agent_credential’s body, with the relay base URL and the human’s token (only awaited when provisioning) injectable for tests.
fetch_m2m_token 🔒
Fetches a fresh client_credentials access token and caches it. client_credentials tokens carry no refresh token — expiry just means re-fetching from scratch with the (already-provisioned) client secret.
invalidate_binding_mismatched_credential
Same token invalidation as invalidate_cached_token, PLUS a CREDENTIAL_RETRY_COOLDOWN failure record — for a 403 (binding mismatch) specifically, not a plain 401 (expired token).
invalidate_cached_token
Clear a per-agent credential’s cached access token — called by cloud_subscriber when a request using it comes back 401 even though the credential looked locally valid (revoked/rotated server-side out-of-band). Without this, the next InjectAvailable round retries the exact same rejected token forever. Best-effort: a store error here just means the stale token survives until its local expiry, matching the pre-existing failure mode rather than introducing a new one. reagentx P1 on PR #2342.
provision_agent_client 🔒
Calls POST /agents/provision (authenticated with the human’s own PKCE token — an M2M agent credential can never provision another one) and caches the returned client_id/client_secret.
provision_rejection_is_unrecognized 🔒
Does /agents/provision refusing with status mean the stored row for this agent’s client can’t be used? 401/403 do; 429, 5xx and the rest are worth retrying as they are.
record_credential_failure 🔒
token_rejection_is_unrecognized 🔒
Does a client_credentials token endpoint’s rejection mean “no such client”? OAuth 2.0 (RFC 6749 §5.2) answers an unknown or unauthenticated client with invalid_client on a 400 or 401.
user_token 🔒
The human’s own PKCE token, which provisioning is authenticated with.