The standards, and how a federation makes an agent identity resolvable rather than configured.
Every standard below is in play in this estate, and each one links to something you can run. The argument is one sentence: an agent's identity, capability envelope, certification status and lifecycle state are published once and resolved by every consumer at runtime, so approval publishes and suspension withdraws, and no consumer holds a stale copy it has to be told to purge.
Every claim on this page links to a proof you can run. Where a proof cannot run today, the page says so rather than asserting it.
Illustrative reference model. Brands, divisions and authentication patterns are modelled from public information so the federation feels like CBA’s own estate. Structure is illustrative and is not a statement about CBA’s real systems.
How a resolution works
The mechanics in five steps, with the endpoints and the specification terms named. Below it, the same flow with the real signed statements resolved live, so the picture can be checked against the wire.
person_addA newcomerpartner · app · agent
shieldYour systemchecks before it trusts
verified_userThe authoritythe bank · the trust anchor
1
“Here's who I am” — signed.
The newcomer publishes a signed note about itself at a public address. Nothing secret.
GET /.well-known/openid-federation
2
“Do you vouch for them?”
Your system doesn't keep a list of partners. It just asks the one authority you already trust.
resolve, don't register
3
“Yes, and here's what they may do.”
A signed answer comes back: this newcomer is real, and here is the policy that limits them.
signed entity statement · metadata_policy
4
Check the signatures up to the anchor.
Your system follows the signed notes up to the one authority it pinned in advance. All valid? Good.
verify the trust chain → /federation/chain.json
5
Trusted: live, this request.
No form, no database row. Need to cut them off? Stop vouching at the authority: gone on the next check.
resolved per request · fail-closed
Read it top to bottom: a stranger becomes a known, governed party, without anyone hand-building a connection or keeping a shared database.
And the rules only ever get tighter on the way down.
The bank's group: the most anyone may do
A region / division: narrows it
The newcomer: gets the overlap
Each level down the chain can only shrink what's allowed, never widen it. A child can't grant itself more than its parent allowed. That's what makes delegation safe.
Now the only “hard” part: that “signed note” is just a JWT.
Three parts separated by dots: a header, the claims, and a signature. Here's a real one from this deployment, in plain terms:
Header how it's signed
{ "alg": "PS256", "typ": "entity-statement+jwt" } // the signature algorithm
Claims who & what
{ "iss": "the bank", "sub": "the bank", // iss==sub → self-issued "jwks": { …public keys… }, "authority_hints": [ "the anchor" ] // who can vouch for me }
Signature proof
⟨signed⟩// verifiable with the keys above: proves it's really them
That's the whole primitive. Everything else (chains, policy, resolve) is just collecting and checking notes like this one.
The same resolution, with the real signed statements
Now the wire itself: the real signed statements the directory returns, fetched and decoded in your browser. The entity's self issued configuration, the authority that vouches for it and stamps a base policy, a subordinate authority that can only narrow that policy, and the merged /resolve answer a consumer actually reads. Watch metadata_policy only ever shrink down the chain.
What the live directory looks like today, stated plainly. Nothing in the CBA directory resolves yet. Two federations exist, one authority is wired under CBA-Global, trust mark issuance already works and is publicly retrievable, and the single leaf present serves an HTML page at its federation well known instead of a signed statement, so resolution correctly refuses it. This page therefore shows refusals where there are refusals. A view that draws a green chain it did not resolve is worse than one that says resolution failed.
resolving…
The three way treatment, before anything else
Nothing on this page asks CBA to replace an authorization server. The seven platforms in this estate are reference implementations. They exist so an agent has somewhere real to authenticate, and each one stands in for the product CBA already runs on that stack. In the Formal Proof of Concept those become Ping and Entra, integrated by ID Partners. What Raidiam ships is the Trust Controller and the views over it.
Configured trust, and resolved trust
Configured trust
Resolved trust
attests an instance, narrows the envelope onto it, settles, and holds the invoice that exceeds the limit
What the run actually did
When the anchor is unreachable, does it fail open or closed?
Fail closed. Availability never degrades into trusting the unverified.
Trust is resolved per request. This is the question every security reviewer asks, and the numbers below are read off the real signed statement rather than asserted. If the runtime cannot be reached, the panel says the numbers are configured defaults rather than a measurement.
Authority, role, policy, resolved across the chain
A role is not an OAuth scope the client asked for. It is granted by an authority, it carries federation metadata policy, and every member inherits that policy down the chain. That is what makes a capability envelope governable: change the role and every consumer admits something different, without the agent identity being touched and without any scope changing.
Every statement is signed. Verify any of them in the estate view: click an authority and read the policy it stamps on its members.
The agent identity model, in three tiers
Agent Provider the manufacturer: an organisation plus an authorization server, a federation entity, issuing client attestation
└ Agent Identity a software statement under an owning business unit, federation resolvable. Roles give metadata policy, which is the capability envelope.
└ Agent Instance attested at runtime, and never a directory record
This is the honest answer to whether it scales to a million agents. Identities are governed, and there are as many of those as there are distinct things an agent is allowed to be. Instances are attested, and there can be as many of those as the runtime spawns, because none of them touches the directory. In the accounts payable run, one governed identity produces one attested instance per invoice, each holding an envelope covering that invoice alone.
The capability roles in this estate
A capability role is the eligibility gate: it decides which RFC 9396 detail types an agent identity may ask for at all. The envelope actually delegated at runtime is the second gate, and delegation only ever narrows it.
Withdrawal, and how long it really takes
Suspending an agent is one change at the authority. The register stops listing it, the authority stops vouching, and every consumer fails closed on its next resolve. That is bounded, not instant, and calling it instant is the fastest way to lose a security reviewer.
Per edge withdrawal: turn one sub agent off
Revoke the invoice settlement edge. The orchestrator and every other identity keep working, and only that edge fails closed. In memory, auto restoring in about five minutes, and entirely separate from the whole principal path.
Rotate a key: vouched stays green, unvouched fails closed
On a demonstration authority we operate. A platform rotates its signing key and the authority re vouches the new kid, so the chain stays green with no downtime. A rogue platform that rotated without being re vouched fails closed. Real PS256 signatures, resolved live, and it auto restores.
Does it hold up? The right test is impossible, not merely tedious.
A control should remove a capability, not throttle it. Agent authorization here is built from standards that meet that bar today:
No bearer secret to steal. Tokens are sender constrained, and the instance key is attested in protected storage. A stolen token is useless without the key.
The call, not the role. RFC 9396 authorization details carry the exact operation: amount, counterparty, purpose. The resource server enforces the specific call rather than "has access to the tool".
Delegation that only narrows. RFC 8693 records a nested actor chain and attenuates the grant at each hop, and federation metadata policy narrows structurally down the chain.
Proof, not just logs. The signed token and the trust chain are independently verifiable artefacts. Who acted, under whose authority, checkable without trusting anyone's log.
A principal underneath. The agent traces to a named owning business unit through its software statement and its manufacturer's attestation. Identity with an owner, not just a key.
Honest on the edges. Where a call needs its body cryptographically bound rather than just the key and the endpoint, add HTTP Message Signatures or issue a token per operation. That is an addition on this foundation, not a rebuild. The concentration point is worth saying out loud too: the group authority is the trust anchor, the policy root and the withdrawal point at once, so a key compromise or sustained outage there is an estate wide event. The mitigations are real but operational: resolution fails closed to cached signed statements within their lifetime, the anchor's signing key belongs in an HSM with a vouched rollover procedure, and OpenID Federation supports multiple trust anchors per leaf, which is the specification level answer to root concentration and is not deployed here.
Build against it, in your terminal
It is an open standard over plain HTTP. These commands target this deployment. Run them as they are, read the real signed artefacts, then point the same calls at your own authorization server. Nothing here is secret; it is meant to be fetched.
1 · this entity's signed configuration, self issued and public
curl /.well-known/openid-federation
A signed JWT carrying the entity id, its jwks, its authority hints and its metadata.
2 · resolve the trust chain to the anchor
curl /federation/chain.json
Ordered steps: leaf configuration, then the subordinate statement, then the trust anchor, each verified. A valid:false at the subordinate step is the chain failing closed for an entity the anchor does not vouch for, which is correct behaviour rather than a fault.
3 · the protected resource metadata of an API, and the detail type it accepts
RFC 9728, naming the authorization servers it will accept a token from and the RFC 9396 detail type it admits.
Make your own authorization server a member. Publish an entity configuration at your /.well-known/openid-federation carrying your jwks, your metadata (for an openid_provider, include the OIDC Discovery fields or /resolve will refuse you) and authority_hints pointing at the anchor. Get the authority to vouch for you, then verify with call 2. The chain build is about twenty lines with a JOSE library: verify each statement against the level above, up to the pinned anchor.