CBA side illustration

CBA Retail Cards

Lists a customer's cards, freezes a card, and raises a transaction dispute. Freezing is permitted and raising a card limit is not, which is the distinction this resource exists to demonstrate.

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-cards.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 typescards_read, cards_manage
Scopesopenid, cards.read
Sender constrainingDPoP verified when presented, required for bound tokens
Mutabilityaccepts instructions

Authorization detail types

cards_read

Authority to list cards and read their state. It carries no ability to change a card.

Required members: type purpose

Optional members: none

{
  "type": "cards_read",
  "purpose": "Answer a customer question about their cards"
}

cards_manage

The type the state changing tools name. It is published so a refusal is checkable against a declared requirement rather than looking arbitrary. Holding the reading authority never yields this one.

Required members: type purpose

Optional members: none

{
  "type": "cards_manage",
  "purpose": "Granted separately by the customer."
}

Token claims this resource decides on

Tools

ToolPurposeRequiresEffect
list_cards List the cards held by the customer this delegation names. cards_read read only
freeze_card Freeze a card immediately. Protective and reversible by the customer. cards_manage changes state
dispute_txn Raise a dispute on a transaction. Protective, and creates a case a human works. cards_manage changes state

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.

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.

An agent can protect, and cannot expose

Freezing a card and raising a dispute reduce a customer's exposure and are reversible by a human. Raising a limit, reissuing to a new address and changing a PIN increase exposure, so they are not offered here at any authority. A compromised agent cannot reach them because the surface does not carry them.

Refusal reason not_offered · decided at execution · policy id cards.protective_actions_only

What clears it: Limit and reissue changes are made by the customer in NetBank or by a banker.

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.