HomeJournalThis post

OAuth RAR for Least-Authority Agents

Design task-shaped agent authority with typed details, audiences, consent, token binding, and revocation.

JP
JP Casabianca
UI/UX designer and full-stack engineer · Bogotá

OAuth RAR lets a client ask for structured, typed authority instead of compressing a consequential agent task into a broad scope string.

This guide designs one payable-invoice request whose resource, account, action, amount, vendor, expiry, consent, token audience, and audit trail remain independently inspectable.

OAuth RAR starts from one payable task

Consider an accounting agent asked to pay invoice 784 to a named vendor from account A-17, up to 620 dollars, before a deadline. Ordinary scopes such as invoices.write or payments create are too broad to describe that intention. Rich Authorization Requests can carry typed authorization_details whose fields a profile defines.

Start from the business verb and its limits, then derive authority; do not begin from the application's existing role catalog. The grant should be useless for another invoice, vendor, funding account, amount, action, or resource server.

For OAuth RAR, the working artifact is a task-to-authority decomposition. It records subject, invoice, vendor, funding account, action, ceiling, currency, resource, and expiry. I would stop the release when one reusable write scope substitutes for the task; that failure means the evidence cannot support this step's claim.

A wrong-account request should be denied by a task-to-authority decomposition; capture subject, invoice, vendor, funding account, action, ceiling, currency, resource, and expiry. Stop when one reusable write scope substitutes for the task, because that outcome breaks the first boundary under test.

The exact implementation vocabulary here includes Rich Authorization Requests, so the term remains connected to a concrete decision rather than hidden in metadata.

Task-shaped authorization envelopeA broad agent request narrows through resource, action, account, amount, vendor, and expiry gates before one payment endpoint.resourceaccountvendoramountpay 784expiry
  • Request: Client submits validated details.
  • Explain: Consent names the concrete consequence.
  • Issue: Token binds audience and grant.
  • Enforce: Resource joins grant to current state.
Figure 1: Each field removes ambient authority before the command reaches the resource server.

Define a typed authorization-details profile

RFC 9396 defines the authorization_details parameter and the framework for typed objects, but the ecosystem still needs a precise profile. Name the type, required identifiers, allowed actions, amount representation, currency, location or account constraints, and validation rules. Use stable identifiers rather than display names, and reject unknown fields when they could widen interpretation.

Version the profile and publish examples for accepted and denied requests. The authorization server must understand the requested object; passing opaque JSON through consent creates the appearance of structure without enforceable semantics.

The decision surface for OAuth RAR is a versioned JSON profile and negative corpus. Its compact receipt contains type URI, field rules, canonicalization, examples, error codes, and compatibility policy. If the server stores authorization_details without validating its meaning, the route stays unresolved and returns to design before polish.

Consent-copy review should inspect a versioned JSON profile and negative corpus; an uninvolved reviewer must recover type URI, field rules, canonicalization, examples, error codes, and compatibility policy. Hold the next action when the server stores authorization_details without validating its meaning.

The primary references for this decision are RFC 9396 Rich Authorization Requests, RFC 8707 Resource Indicators, and RFC 9449 DPoP. RAR supplies typed authorization details, resource indicators bind the audience, and DPoP can bind a proof key. Those layers still require current ledger state and denial-first application policy before an agent may cause a financial effect.

The exact implementation vocabulary here includes authorization_details, so the term remains connected to a concrete decision rather than hidden in metadata.

Bind tokens to the resource server

Use resource indicators so the authorization request names the intended API audience. The issued access token should not be accepted by a neighboring ledger, CRM, or messaging service merely because they share an issuer. Validate issuer, audience, subject, client, expiry, and the structured authorization at the resource boundary.

Resource indicators narrow where a token works; authorization details narrow what it may do there. Keep both controls because a perfectly shaped payment grant presented to the wrong service is still an authority failure.

I would review OAuth RAR through an issuer-audience-action validation matrix, not a slide assembled after implementation. The saved evidence is requested resource, issued audience, presented host, token subject, authorization type, and decision. The explicit rejection rule is simple: a bearer token is accepted across every internal API.

A replayed proof should fail against an issuer-audience-action validation matrix, with requested resource, issued audience, presented host, token subject, authorization type, and decision retained for comparison. Reopen the design if a bearer token is accepted across every internal API.

The exact implementation vocabulary here includes least-authority agents, so the term remains connected to a concrete decision rather than hidden in metadata.

FieldQuestionEnforcer
resourceWhich API?Token + server
actionsWhich verb?Endpoint policy
accountWhose funds?Ledger
limitHow much?Command handler
Figure 2: Structured fields carry distinct enforcement duties.

Render consent as a concrete consequence

The consent screen should translate the typed request into ordinary language: pay this vendor, for this invoice, from this account, up to this amount, before this time. Show the requesting application and acting subject, then permit decline or a safe narrowing when the profile supports it.

Never reduce the display to a generic “allow payments” label. If the authorization server changes a requested detail during approval, return the granted object explicitly so the client and resource server do not assume the original request survived unchanged.

This part of OAuth RAR becomes testable through a field-to-consent copy map. Preserve requested details, displayed consequence, user choice, granted details, copy revision, and timestamp. Treat the step as failed whenever consent hides identifiers or ceilings behind a friendly summary, even when the visual result appears convincing.

Emergency degradation should remove payment authority from a field-to-consent copy map; the fallback receipt is requested details, displayed consequence, user choice, granted details, copy revision, and timestamp. Treat consent hides identifiers or ceilings behind a friendly summary as an explicit failed state.

The exact implementation vocabulary here includes resource indicators, so the term remains connected to a concrete decision rather than hidden in metadata.

Make the agent prove possession

Short expiry reduces exposure, but a stolen bearer token can still be used before it expires. DPoP can bind presentation to a client-held key and specific HTTP request properties when the deployment can protect that key and validate proofs correctly. Record nonce, replay, clock-skew, and key-rotation policy.

Proof-of-possession does not repair an overbroad grant, compromised client runtime, or malicious approved action; it addresses token replay. Keep the controls named separately so incident responders know whether to revoke a grant, rotate a key, or investigate the task source.

For OAuth RAR, the working artifact is a token threat-to-control table. It records token binding mode, key ID, proof validation, replay result, rotation, and failure response. I would stop the release when DPoP is described as complete agent safety; that failure means the evidence cannot support this step's claim.

A wrong-account request should be denied by a token threat-to-control table; capture token binding mode, key ID, proof validation, replay result, rotation, and failure response. Stop when DPoP is described as complete agent safety, because that outcome breaks the first boundary under test.

Enforce details at every consequential endpoint

The payment endpoint should join token authorization_details with current server records. Confirm invoice and vendor identity, funding-account access, remaining amount, currency, status, deadline, and idempotency before creating an effect. Do not trust duplicated display data from the client when authoritative records exist.

If the invoice changes after consent, stop and request new authority rather than stretching the old object. Least-authority agents require enforcement close to the command because downstream services are where an apparently small identifier mismatch becomes real money movement.

The decision surface for OAuth RAR is an endpoint policy decision log. Its compact receipt contains normalized command, matched grant, current record versions, policy result, idempotency key, and effect ID. If only the authorization server inspects structured limits, the route stays unresolved and returns to design before polish.

Consent-copy review should inspect an endpoint policy decision log; an uninvolved reviewer must recover normalized command, matched grant, current record versions, policy result, idempotency key, and effect ID. Hold the next action when only the authorization server inspects structured limits.

  1. 1Request

    Client submits validated details.

  2. 2Explain

    Consent names the concrete consequence.

  3. 3Issue

    Token binds audience and grant.

  4. 4Enforce

    Resource joins grant to current state.

Figure 3: Consent and enforcement close the same typed request.

Handle delegation, expiry, and revocation

Name whether the agent acts as the user, a workload, or a delegated service and preserve that chain in audit events. Expire task-shaped grants quickly, revoke them when the invoice is cancelled or the session loses trust, and make retries fail with a recoverable authorization state rather than a generic server error.

Long-running workflows should pause for renewal instead of caching authority beyond its life. A new approval may produce a new grant and effect key; the business task can remain related while its authority epochs stay distinct.

I would review OAuth RAR through an authority lifecycle state machine, not a slide assembled after implementation. The saved evidence is actor chain, grant ID, issued and expiry times, revocation reason, renewal link, and final use. The explicit rejection rule is simple: a workflow treats expired authority as a transient network failure.

A replayed proof should fail against an authority lifecycle state machine, with actor chain, grant ID, issued and expiry times, revocation reason, renewal link, and final use retained for comparison. Reopen the design if a workflow treats expired authority as a transient network failure.

Connect identity, consent, and escalation

Audience validation protects the receiving MCP or API service, workload identity names the executing process, elicitation patterns make consent visible, and escalation rules decide when automation must stop. OAuth RAR sits between them as a structured grant, not a replacement.

Build one trace across all four controls so a reviewer can answer who asked, who approved, which resource accepted, what fields constrained the action, and why human review was or was not required. The join is the safety property; isolated green checks are insufficient.

This part of OAuth RAR becomes testable through a cross-system authority trace. Preserve workload subject, user subject, consent event, grant, audience decision, policy escalation, and effect. Treat the step as failed whenever identity and authority events cannot be correlated, even when the visual result appears convincing.

Emergency degradation should remove payment authority from a cross-system authority trace; the fallback receipt is workload subject, user subject, consent event, grant, audience decision, policy escalation, and effect. Treat identity and authority events cannot be correlated as an explicit failed state.

Related implementation evidence lives in MCP OAuth audience validation, agent workload identity, MCP elicitation consent UX, and designing AI review loops. Workload identity, audience validation, injection defenses, and activity logs surround the grant without replacing its typed limits. Join their audit identities to the exact invoice command instead of widening a token for operational convenience.

Release with a denial-first conformance suite

Test wrong resource, wrong account, different invoice, amount above ceiling, currency mismatch, expired token, replayed proof, modified request method, revoked grant, stale invoice, duplicated effect, and missing detail. Every denial should be safe, observable, and useful to the authorized caller without leaking protected records.

Then run the one permitted action and prove that the receipt contains exactly the approved consequence. OAuth RAR is successful when the allowed path is narrow and the neighboring denied paths are boring, deterministic, and easy to explain.

For OAuth RAR, the working artifact is a task-shaped authorization conformance suite. It records fixture, expected decision, actual code, audit ID, resource state, and recovery instruction. I would stop the release when testing demonstrates only that the approved payment works; that failure means the evidence cannot support this step's claim.

A wrong-account request should be denied by a task-shaped authorization conformance suite; capture fixture, expected decision, actual code, audit ID, resource state, and recovery instruction. Stop when testing demonstrates only that the approved payment works, because that outcome breaks the first boundary under test.

The fixture proves that a read-only, single-account grant cannot expand into a payment action.

Runnable artifact — rar-authority-envelope.test.mjs

import assert from "node:assert/strict";
const grant={resource:"https://ledger.example",actions:["read"],accounts:["a-17"],maxUsd:0};
const allow=(g,x)=>g.resource===x.resource&&g.actions.includes(x.action)&&g.accounts.includes(x.account)&&x.amount<=g.maxUsd;
assert.equal(allow(grant,{resource:"https://ledger.example",action:"read",account:"a-17",amount:0}),true);
assert.equal(allow(grant,{resource:"https://ledger.example",action:"pay",account:"a-17",amount:20}),false);
console.log("PASS: authority envelope narrowed");

Run node rar-authority-envelope.test.mjs. Expected receipt: PASS: authority envelope narrowed.

OAuth RAR should authorize one described resource action with explicit account, amount, vendor, and expiry constraints—not give an agent an ambient role. Reopen the profile when authorization-detail schemas, proof rules, or resource policy changes; safe failure must stay deterministic even while the allowed command evolves.