Guides
Authentication
Two planes, two mechanisms. The admin plane — opening accounts, registering trust roots, activating policy — is operated by a human or a service and takes a bearer token. The agent plane is spoken by autonomous agents, and an agent does not hold a session: it carries its authority in the envelope.
The agent plane
An agent proves two separate things on every intent, and they fail differently.
- agentagent:// URI
Who is acting. The URI names the agent, e.g.
agent://example.com/agent/clerk_01h455vb4pex5vsknk084sn02q. It must be bound to a party in the ledger. An unbound URI is a401 unknown_agent; a malformed one is a422 invalid_agent_uri.- attestationPASETO v4.public
What it may do. A signed capability attestation, issued by a trust root the service recognizes. A bad signature, an expired token, the wrong audience, or an untrusted issuer is a
403 attestation.
The two are checked independently and in that order: identity first, then authority. An agent that is known but attests to a capability the action does not map to is a 422 capability_mapping — it is who it says it is, and it may not do this.
There is no login, no session, and no refresh. The attestation is minted out of band, carried in the envelope, and verified on every submission. A stateless agent does not survive its own transaction; the record of what it was permitted to do does.
Reads are the mirror image. A submission carries its attestation inside the envelope, but a party-scoped read — a balance, a transaction lookup, your open obligations — carries it at the transport layer, as Authorization: Bearer <attestation>, and returns only what that party may see. Hold the attestation on the client and it rides every such read; hold none and the read fails locally, before a request leaves, rather than as a bare call the service would only reject.
Carry identity and authority in the envelope
1use axorum_client::{AxorumClient, IntentDraft};23let client = AxorumClient::builder("https://ledger.example.com").build()?;45let draft = IntentDraft::new(6 "agent://example.com/agent/clerk_01h455vb4pex5vsknk084sn02q",7 attestation, // "v4.public.eyJhZ2VudCI6…" — minted by your trust root8 transaction,9 action,10);
The admin plane
Administrative routes take a bearer token in the Authorization header — a separate credential from any agent's attestation. Keep it out of source and out of logs: it can activate a policy, and the policy is what every verdict is judged against.
The typed admin client is a distinct client, held apart from the agent plane on purpose. It ships today in the Rust SDK (and the axorum CLI). The TypeScript and Python clients speak the agent plane; to drive the admin routes from them, send the token as Authorization: Bearer <token> on the admin/… paths directly.
Admin token
1let client = AdminClient::builder("https://ledger.example.com")2 .token(std::env::var("AXORUM_ADMIN_TOKEN")?)3 .build()?;