CBA side illustration
CBA Retail Branch and ATM Locator
Branch addresses, opening hours, accessibility and ATM availability. Public information, served as a governed resource so that every read is attributable to a delegation.
This service is an illustration built on the CBA side of the boundary. It is not a Raidiam product. It exists to show what a resource server can demand of an agent, and to show that a refusal can always be explained.
What an agent has to discover
Resourcehttps://rs-branch.demo.cba.raidiam.io
Authorization serverhttps://netbank.demo.cba.raidiam.io
Trust anchorhttps://authority.directory.cba.raidiam.io/authority/5a27c88b-97ed-4d37-a3c8-59c66b19aa25
Detail typesbranch_read
Scopesopenid, branch.read
Sender constrainingDPoP verified when presented, required for bound tokens
Mutabilityread only
Authorization detail types
branch_read
Authority to read branch locations, opening hours and ATM availability. It carries no access to any customer record and no ability to change anything.
Required members: type purpose
Optional members: none
{
"type": "branch_read",
"purpose": "Answer a customer question about opening hours"
}
Token claims this resource decides on
sub optional The customer on whose behalf the question is being asked, when there is one.
root_grant optional The delegation this read belongs to, recorded on every decision.
act optional The RFC 8693 actor chain, recorded on every decision.
authorization_details[branch_read] required The authority to read branch information.
Tools
Guardrails, published in advance
Every call carries a token from the named authorization server
Calls are accepted only with an access token issued by https://netbank.demo.cba.raidiam.io and addressed to this resource as its audience. A token minted for a different resource is refused even when it is otherwise valid.
Refusal reason missing_access_token, invalid_token · decided at authorization · policy id rs.authenticated_caller
What clears it: Read this metadata document, then request a token from the authorization server it names, with this resource as the audience.
Authority is the RFC 9396 detail type, not a scope
Each tool names one authorization_details type. The token must carry that type, or an umbrella type that narrows to it. Holding a scope, or holding authority for a neighbouring resource, does not admit the call.
Refusal reason insufficient_authority · decided at authorization · policy id rs.authority_gate
What clears it: Obtain a token carrying the detail type the tool names. Delegation only ever narrows, so the delegating envelope must already contain it.
A revoked delegation stops working before its tokens expire
Revocation arrives as a Shared Signals event and is applied to the delegation, not to a single token. Every token issued under a revoked delegation is refused from that moment, whatever its expiry says.
Refusal reason delegation_revoked · decided at authorization · policy id rs.revocation_honoured
What clears it: The customer must grant a fresh delegation. There is no way to appeal a revocation at the resource.
Sender constrained tokens are bound to the key that holds them
A DPoP proof is verified whenever one is presented, and is required whenever the access token names a key in its cnf.jkt claim. Each proof is accepted once, so a captured proof cannot be replayed.
Refusal reason dpop_proof_required, invalid_dpop_proof, dpop_key_mismatch, dpop_proof_replayed, access_token_not_dpop_bound · decided at authorization · policy id rs.dpop_binding
What clears it: Request the access token with a DPoP proof so the authorization server binds it to your key, then send a fresh proof with every call.
CBA Retail Branch and ATM Locator never changes state
This resource publishes read_only true and exposes no path that writes. A mutating tool is refused before it runs, regardless of the authority the caller presents, so an agent cannot widen its own position by writing here.
Refusal reason resource_is_read_only · decided at authorization · policy id rs.read_only_resource
What clears it: State changing instructions belong to the resource that owns the record. This one only reports.
A malformed request is refused with the reason it was malformed
Arguments are validated before any business rule runs, and the refusal names the argument at fault rather than returning a bare failure.
Refusal reason tool_error, invalid_amount, unknown_tool · decided at execution · policy id rs.request_validity
What clears it: Correct the named argument. The tool schemas are published in this document.
Public information, governed access
Nothing this resource returns is confidential. It still requires a token from the retail platform, because an estate that governs only its sensitive resources cannot say who asked it anything. Every read here is attributable to a delegation and appears in the decision log.
Refusal reason missing_authority · decided at authorization · policy id branch.public_data_is_still_governed
What clears it: Obtain a branch_read authority from the retail platform.
Only branches in the register
A branch identifier this register does not hold is refused as unknown, with the full list of identifiers it does hold, so a caller can correct itself in one step.
Refusal reason unknown_branch · decided at execution · policy id branch.known_branches_only
What clears it: Call find_branch first.
Observability
Every admission decision, allowed and refused, is recorded with the policy that decided it and the values it turned on. Read them at /decisions.