Authorization & Signed Agent Intents
Authenticating the caller is not enough — a value-moving request must prove the caller may act on this specific resource, and an agent-initiated action must prove the agent itself authorized the exact operation. Passport enforces both.
Two gates
- Caller authentication — a valid ISSUER or HOLDER API key.
- Resource authorization — an ISSUER key may act on any resource; a HOLDER key may act only on agents it owns, escrows it is a party to, or rails it authorized. Resolved by one primitive so the check cannot be forgotten per route.
Signer provenance (fail closed)
A "verified" signature is only meaningful if it is verified against a key the platform already trusts. Every signature check resolves its key from an env-configured, database-registry, or (non-production only) genesis-benchmark source via verifyPinnedSignature(). A public_key supplied in a request body is accepted for backward compatibility but is never used as the verification key; if it differs from the pinned key the request is rejected with a 401 and a signature_provenance_rejected security event. When no pinned key is configured, the check fails closed in production (or whenever ENFORCE_SIGNATURES=1, e.g. staging).
Signed agent intents
Agent-initiated value routes (AMM swap/fractionalize, escrow release) require a HOLDER caller to attach an intent: an Ed25519 signature over the canonical operation, verified against the agent's registered enrollment key. The intent binds the action, the resource, the exact params (pool/token/amount, batch, assay certificate), a one-time nonce, and an expires_at timestamp. Tampered params, an expired intent, or a replayed nonce are rejected.
# canonical (signable) form — signature over utf8(canonicalJson(...))
{
"action": "amm.swap",
"agent_commitment": "<64-hex>",
"resource_kind": "agent",
"resource_id": "<64-hex>",
"params": { "pool_id": "POOL-ANGEL-MAU-GOLD", "input_token": "ANGEL", "input_amount": 10 },
"nonce": "<unique>",
"expires_at": "2026-01-01T00:05:00.000Z"
}
POST /api/v1/reserves/amm/swap
{ "pool_id": "...", "agent_commitment": "...", "input_token": "ANGEL", "input_amount": 10,
"intent": { ...canonical fields..., "signature": "<128-hex>" } }An ISSUER key remains an authorized alternative for delegated operations (no intent required). Intents are single-use; each nonce is consumed once.
Non-regressable
A test enumerates every mutating route under reserves/ and raillab/ and fails, by name, if a route has no recognized authorization marker — so a new unguarded value route cannot ship silently. Routes authorized by a signature verified inside their service (or public by design) are explicitly allowlisted. A second meta-test enumerates every direct verify( call site and fails unless it delegates to verifyPinnedSignature() or is approved with a justification — so a self-asserted-signer bypass cannot silently return.
Related: System Posture.