| Internet-Draft | OAuth Mission | July 2026 |
| McGuinness | Expires 7 January 2027 | [Page] |
An AI agent is typically given a mission: a task to pursue on a user's behalf. OAuth 2.0 issues access tokens for individual resource requests, but it has no durable, approved artifact that ties those tokens to the one task a user actually authorized. As a result, an agent's authority is a collection of independently obtained tokens with no shared, auditable boundary, and a user's approval is disconnected from what the agent later does.¶
This document defines a Mission: a structured, human-approved, integrity-bound authorization artifact for OAuth 2.0. A client submits a Mission Intent through Pushed Authorization Requests; the Authorization Server derives Rich Authorization Requests authorization details from it, binds the approved task and its derived authority to the Approver's consent through two integrity anchors, and records a durable Mission. Every access token derived under the Mission carries that authority and a "mission" claim, and issuance is gated on the Mission's lifecycle state. Optional capabilities represent delegation among agents with the OAuth Actor Profile and, as specified by a companion, let a single Mission be honored across trust domains. This is the issuance and governance "mission layer" left unspecified by agent-identity work for OAuth; runtime enforcement of each action is a separate, optional layer.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-mcguinness-oauth-mission/.¶
Source for this draft and an issue tracker can be found at https://github.com/mcguinness/mission-bound-authorization.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 7 January 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Agent-identity work such as [I-D.draft-klrc-aiagent-auth]
establishes how an AI agent authenticates and how a user delegates
authority to it: the agent is an OAuth 2.0 [RFC6749] client
identified by client_id, the delegating user is the access token
sub, and the
agent obtains tokens for the resources its task requires. That work
deliberately leaves three things out of scope: how an agent's task
(its "mission") is translated into authorization, how a user's
approval of that task is captured as a durable artifact, and how
later token issuance stays bound to what the user approved.¶
Without that layer the gap is invisible to every individual OAuth component. Each token is individually valid and each request individually in scope, yet nothing checks whether the task the user approved is still the one being pursued. A token issued for a task remains usable after the user's approval has lapsed or been withdrawn, because no OAuth object ties the token's validity to the task's authorization: the credential stays secure while the work it authorizes has quietly become unauthorized.¶
This document specifies that missing layer. It defines a Mission: a structured, human-approved, integrity-bound OAuth authorization artifact. The contribution is a single chain:¶
The client submits a structured Mission Intent describing the task (goal, target resources, constraints) instead of requesting raw scopes.¶
The Authorization Server (AS) derives authorization details ([RFC9396]), the Authority Set: the concrete authority the task needs.¶
At an approval event, the Approver consents to that
authority, and the AS commits the task as an intent_hash and
the authority as an authority_hash and records a durable
Mission.¶
Every access token the agent obtains under the Mission carries the
derived authorization details and a mission claim bearing
the authority_hash. A Resource Server enforces statelessly from
the token.¶
Token issuance and refresh are gated on Mission state, so revoking or expiring the Mission stops the agent from obtaining further authority.¶
The result is that a user approves a task once, and that approval,
not a per-request scope grant, bounds and outlives every token the
agent derives. Each token carries an authority_hash audit anchor back
to the consented authority; a holder of the full Authority Set can
verify it, and a holder of only a narrowed subset (a downstream or
cross-domain party) treats it as an audit anchor it cannot recompute
(Section 15.1).¶
This chain is the first of two deliberate security tiers. It gives task-bound issuance, auditability, and a revocation gate over future derivation, which is sufficient for a low-risk workflow whose exposure is bounded by short token lifetimes and narrow authority. It does not evaluate individual actions: an agent taking consequential autonomous actions needs the second tier, the runtime enforcement layer (Section 15.5), specified separately. A deployment chooses its tier deliberately, matching the enforcement it runs to the consequence of what its agents do.¶
OAuth already has objects near this need, but none is the approved
task. A scope value or an authorization_details entry
([RFC9396]) expresses authority but neither the task it serves nor a
lifecycle of its own. An access token is a short-lived projection; its
jti identifies the token, not the task. A refresh token preserves
the ability to obtain further tokens but commits no bounded, approved
authority. A consent record proves that an approval event happened; it
does not govern the resulting work as it continues. The Mission is the
durable object these project from: the approved task that bounds and
outlives them, and that every derived token refers back to.¶
Put plainly: Rich Authorization Requests express authority; a Mission
expresses an approved task with a lifecycle. The Mission is a separate
object because that approved-task lifecycle, not a new way to express
authority, is what OAuth lacks. A Mission is therefore not another
authorization_details type; it is the durable, approval-backed object
an Authority Set is derived for and gated by.¶
The Mission is the durable, AS-held object that commits the approved authority and owns the task's lifecycle. Two related things an agent produces around a task are deliberately not the Mission and carry no authority of their own.¶
The agent's plan, how it decomposes the task, chooses tools, and
delegates to sub-agents, is the agent's own strategy and is out of
scope for this document. It grants nothing: authority a sub-agent
exercises is carried by the act chain (Section 11), derived from
the Mission and only ever narrowed from it (Section 5.1), never created
by the plan.¶
The agent's execution, the tokens it derives, the calls it makes, and the decisions taken on them, references the Mission but cannot expand it. Revoking the Mission stops further derivation (Section 9); it does not undo actions already completed. Evaluating each action against the Mission at the point of use is the runtime layer's concern (Section 15.5), not this document's.¶
The invariant across all three: the plan and the execution draw on the Mission's authority; neither enlarges it.¶
This document is complementary to [I-D.draft-klrc-aiagent-auth]
and reuses its model: the agent is the OAuth client
(client_id); the delegating user or system is the token sub.
This document does not define agent identity, credentialing, or
posture; it defines the approved-task artifact those identities act
within. An agent authenticated and delegated per that specification
uses the mechanisms here to obtain Mission-bound tokens.¶
This profile targets OAuth deployments where authority serves a durable, user-approved task that spans more than one token, request, or audience: an agent pursuing a multi-step objective on a user's behalf, or a workflow whose audit must join activity across hops on a shared task. It is not intended for, and adds cost without benefit to, single-request user flows, machine-to-machine service credentials, or short-lived authorizations where the credential's lifetime is the task's lifetime; those use OAuth unchanged.¶
A Mission SHOULD be scoped to a concrete task, not to an agent's whole lifetime. A deployment SHOULD prefer narrow, per-task Missions, each separately approved and revocable, over a single broad standing Mission that accumulates authority across unrelated tasks. The durable object is the approved task: keeping it task-scoped is what makes its authority and audit meaningful and bounds the blast radius on compromise to one task. An agent pursuing many tasks holds many Missions, not one broad one.¶
This document is a self-contained, minimum-viable profile: it binds Missions to OAuth 2.0 and is implementable on its own, depending only on the OAuth and JOSE specifications it cites.¶
One normative dependency is on an in-progress individual draft, so
this document cannot advance ahead of it: the OAuth Actor Profile
([I-D.draft-mcguinness-oauth-actor-profile]) for the act chain. That
dependency is confined to the OPTIONAL Delegation capability, so the mandatory
single-domain core does not depend on it. Cross-domain projection, a
single hop that lets an Authorization Server in another trust domain
honor a Mission, is specified by the companion Mission Cross-Domain
Projection profile [I-D.draft-mcguinness-oauth-mission-cross-domain],
which carries the identity-chaining and ID-JAG dependencies with it.¶
Separate from this document, and not required to implement it, are
several capabilities now specified as OPTIONAL companion profiles: an
additional integrity anchor over a structured consent disclosure
(consent_rendering_hash, Section 15.1) is defined by Mission
Consent Evidence [I-D.draft-mcguinness-oauth-mission-consent-evidence];
mission expansion is defined by Mission Expansion
[I-D.draft-mcguinness-oauth-mission-expansion]; and a cross-domain
status or event-distribution mechanism for tighter revocation is defined
by Mission Status [I-D.draft-mcguinness-oauth-mission-status] and
Mission Lifecycle Signals [I-D.draft-mcguinness-oauth-mission-signals].
A deployment implements this document without any of them. Remaining
future work, not yet specified, includes: a substrate-neutral
generalization of the Mission model across non-OAuth authorization
substrates; the normative carriage of Mission context in Transaction
Tokens ([I-D.draft-ietf-oauth-transaction-tokens]), shown only
illustratively in the companion's end-to-end example; and, for a
community that wants cross-vendor agreement on what a task authorizes
within a vertical, an OPTIONAL derivation profile: a registry of
standard task types mapped to authority templates, so that two
vendors in that profile derive comparable Authority Sets. This document
deliberately does not standardize the derivation algorithm itself
(Section 5); a vertical profile is the appropriate
vehicle where portable derivation is genuinely needed.¶
The following are deliberately out of scope. Each is a recurring question for agent authorization; naming it here records that it was considered and where it belongs, not that it was overlooked.¶
Semantic / intent verification. This profile binds a token to an
approved authority and task; it does not evaluate whether a given
runtime action serves the Mission's purpose beyond matching the
approved authorization_details and constraints. Per-action
evaluation is the runtime layer's role (Section 15.5).
Verifying an agent's declared reasoning against the task is a further
attestation problem outside both layers.¶
Approval-free authorization upgrade. The Authority Set is committed at approval; this profile defines no mid-stream widening that bypasses consent. Widening requires a new approval, a successor Mission, as specified by Mission Expansion [I-D.draft-mcguinness-oauth-mission-expansion]; a widening that no consent authorizes remains out of scope.¶
Lifecycle event distribution. A Resource Server learns Mission state from the token lifetime or optional introspection (Section 10); this profile defines no push-based notification of Mission state changes. A Shared Signals ([RFC8935]) / CAEP profile for Mission lifecycle events is specified separately by the Mission Lifecycle Signals profile ([I-D.draft-mcguinness-oauth-mission-signals]), not here.¶
Human-in-the-loop suspension. The base lifecycle here is
active, revoked, expired (Section 9). A suspended state
with resume/complete transitions is defined as an OPTIONAL
extension by the Mission Status and Lifecycle profile
([I-D.draft-mcguinness-oauth-mission-status]); a
pending-human-approval state and a holding-token pause-and-resume
protocol remain future lifecycle work.¶
Multi-hop cross-domain provenance. A single cross-domain hop is specified by the companion ([I-D.draft-mcguinness-oauth-mission-cross-domain]); chaining a Mission across more than one trust-domain boundary, and the verifiable provenance that would require, are future work.¶
Decentralized agent identity. Agent identity and credentialing are out of scope ([I-D.draft-klrc-aiagent-auth], and workload identity efforts such as WIMSE); this profile governs the approved-task artifact those identities act within, not the identities themselves.¶
Cross-audience unlinkability. A single canonical Mission
Identifier and the authority_hash it shares deliberately let any
party correlate a
Mission's activity across audiences and resources. This is a design
choice, not an omission: a stable, correlatable anchor is what lets a
Resource Server, a cross-domain Resource AS, and an auditor bind
evidence to one approved Mission, which is a core goal of this
document and its companion profiles.
Pairwise or unlinkable presentation of Mission-bound authority works
against that anchor and is therefore future work, not a v1 property
(Section 16.1).¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
All JSON shown in this document is non-normative and illustrative; the member definitions in the surrounding text are authoritative.¶
The OAuth client acting on a user's behalf, identified by
client_id. Agent identity is established per
[I-D.draft-klrc-aiagent-auth] or ordinary OAuth client
authentication.¶
The user or system on whose behalf the Mission is approved,
identified by an (iss, sub) pair and carried in derived tokens'
sub claim.¶
The single accountable principal who approves the Mission at the approval event. Equal to the Subject for self-approval; different for administrator or delegated approval. This document records one accountable Approver; multi-party approval and the provenance of delegated approval authority are deferred (Section 6.2).¶
The OAuth AS that validates a Mission Intent, runs the approval
event, records the Mission, and derives tokens. It is the Mission's
issuer. "Mission Issuer", "issuer AS", "originating AS", and "AS" are used
interchangeably in this document.¶
An Authorization Server in another trust domain that honors a Mission it did not issue, minting its own tokens for its resources; it is never the Mission Issuer. Cross-domain projection is specified by the companion Mission Cross-Domain Projection profile ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
The structured description of the task the client submits (Section 4).¶
The set of authorization_details entries the AS derives from a
Mission Intent and the Approver approves
(Section 5). "Authority Set" names these concrete
entries; it does not mean an identity authority, a trust authority,
a legal authority, or an issuing authority.¶
The durable, immutable record created at the approval event (Section 7), identified by a Mission Identifier (Section 7.1).¶
An access token issued under a Mission, carrying its Mission-derived
authority (the full Authority Set or a narrowed subset) as
authorization_details and a mission claim
(Section 8).¶
An access token or refresh token issued under a Mission, carrying
its authority and the mission claim (or bound server-side, for
refresh tokens).¶
An implementation conforms in one of three roles.¶
A Mission Issuer (the Authorization Server) implements the core issuance surfaces:¶
derivation of mission_resource_access authorization details
(Section 5);¶
issuance of Mission-bound access tokens carrying the mission claim
(Section 8);¶
the subset rule (Section 5.1); and¶
A Mission-aware Resource Server implements Resource Server enforcement (Section 8.2).¶
A Mission Client implements the client surfaces:¶
submission of the Mission Intent via PAR only
(Section 4.1), never sending authorization_details
alongside mission_intent;¶
reading its granted authority from the token-response
authorization_details echo (Section 8); and¶
obtaining mission_id from the mission_id token-response parameter
or the mission claim's id (Section 6.1), treating it as a
reference, never a credential.¶
Beyond these mandatory roles, an implementation MAY additionally claim three OPTIONAL capabilities. Each is independent, and an implementation that supports none of them is still conformant:¶
Delegation (Section 11): issuing and consuming derived tokens
that carry the act delegation chain.¶
Introspection (Section 10): reporting Mission state through
the mission token introspection response member.¶
Cross-Domain: projecting a Mission so it is honored by an Authorization Server in another trust domain. Cross-domain projection is specified by the companion [I-D.draft-mcguinness-oauth-mission-cross-domain]; an implementation claiming this capability conforms to that document.¶
A conforming implementation names the optional capabilities it supports (for example, "Mission Issuer with Delegation and Cross-Domain"); each capability's defining section or document states its detailed requirements.¶
A token carrying a mission claim is not, by itself, Mission-bound
authorization. Conformance as a Mission Issuer requires the gates:
authority derived from the approved Intent and committed by the
anchors (Section 6), issuance bounded by the subset rule
(Section 5.1), and derivation gated on Mission state (Section 9).
An implementation that carries Mission metadata without these gates
conforms to no role in this document and MUST NOT be described as
implementing it.¶
The mission_bound_authorization_supported metadata (Section 13)
advertises Mission Issuer support only. It makes no assertion about any
Resource Server, which does not advertise through Authorization Server
metadata. The OPTIONAL capabilities are discovered first through
existing OAuth metadata ([RFC8414]): introspection_endpoint for
introspection, and grant_types_supported containing
urn:ietf:params:oauth:grant-type:token-exchange for delegation and
for the companion's cross-domain grant issuance. Absent such a signal,
a capability is discovered out of band or by attempt: a Token
Exchange, a cross-domain grant issuance, or an introspection request
fails if the issuer does not support it.¶
The smallest useful conforming deployment, noted here informatively,
is a Mission Issuer that derives in narrowing mode from the Intent's
proposed_authority (Section 5), emits only the
Common Constraints of Section 5.2, and implements none of
the OPTIONAL capabilities; a scope-only Resource Server still operates
at the coarse scope level (Section 8.2). This note names a
starting point and creates no new conformance class.¶
This document maps principals onto native OAuth constructs:¶
The Agent is the OAuth client, referenced by client_id. Agent
identity and credentialing are out of scope (see
[I-D.draft-klrc-aiagent-auth]).¶
The Subject and Approver are each an (iss,
sub) pair, matching the access token sub model of [RFC9068].¶
On a derived token the sub claim is the Subject's sub and the
token iss is the AS; within the issuing AS's namespace this
(iss, sub) pair is authoritative for the Subject, and Resource
Servers authorize against it. The Subject's home issuer is recorded
on the Mission as subject.iss for audit and is not carried on the
token; this document defines no runtime lookup of it (there is no
by-Mission status endpoint). Across trust domains, the companion's
cross-domain grant conveys Subject identity to the Resource AS through
its own subject-resolution claims
([I-D.draft-mcguinness-oauth-mission-cross-domain]), not through a
Mission lookup.¶
Issuer roles obey three invariants: a Mission has exactly one Mission
Issuer, its issuer; a Resource AS never creates or alters a Mission;
and a local token minted in another domain preserves the mission
claim unchanged ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
Principals are recorded at the approval event and are immutable. Two
principals are equal when their iss and sub are byte-equal.
Dynamic delegation (the actors an agent delegates to during
execution) is carried on derived tokens via the act chain
(Section 11), not on the immutable Mission record. Richer subject
identifier formats (for example, the formats of [RFC9493]) MAY be
layered in future versions and are not required here.¶
Agent (client) Mission Issuer (AS)
| |
| 1. PAR: mission_intent ------------>| derive authority
|<----------- request_uri ------------| (authz_details)
| |
| 2. authorization request ---------->| Approver consents
| | -> authority_hash
|<-------------- code ----------------| -> Mission active
| | (bound to the grant)
| |
| 3. token request ------------------>| gate: active?
|<----------- access token -----------| + authz_details
| | + mission claim
v
¶
The flow then leaves the AS: (4) the agent calls the Resource Server
with the token; the RS enforces the authorization_details
statelessly and MAY check the mission claim, with no callback to the
AS required. (5) A management revoke, or expires_at passing,
moves the Mission to revoked or expired, after which the AS refuses further
issuance and refresh; a deployment MAY additionally compose RFC 7009
[RFC7009] refresh-token revocation (Section 9.2). The end-to-end
example (Appendix A) walks this flow with concrete messages.¶
A Mission Intent is the proposal; the Mission is the approval; the
integrity anchors commit the moment of transition. Before the approval
event (Section 6) only the Intent exists, as untrusted client
input (Section 4.1); after it, only the Mission is
authoritative. A Mission Intent therefore has no protocol identifier
of its own: two submissions of the same Intent produce two distinct
pending requests, and a Mission acquires its Mission
Identifier (Section 7.1) only at activation. The approved Intent is
recorded on the Mission and committed by intent_hash
(Section 6.3); it describes the task but commits no
authority, which is committed separately by authority_hash over the
derived Authority Set (Section 5).¶
A Mission Intent is a JSON object describing the task. The client
submits it in place of scope, or alongside a narrowed scope. It
has the following members:¶
goal:REQUIRED. A string. A human-readable statement of the task, for rendering to the Approver. Maximum 4096 characters.¶
resources:REQUIRED. An array of strings. The target resources the task needs, each an absolute URI identifying a protected resource (an OAuth resource per [RFC8707]-style indicators or a Protected Resource per [RFC9728]).¶
constraints:OPTIONAL. An array of strings. Human-readable bounds on the task (for example, "read only invoices from 2026"). These inform derivation and consent rendering.¶
proposed_authority:OPTIONAL. An array of objects, each shaped as an [RFC9396]
authorization_details entry. The client's concrete authority
proposal for the task. It is untrusted input like the rest of the
Intent and is committed by intent_hash with it
(Section 6.3). When present, the AS MUST derive each
Authority Set entry as a subset (Section 5.1) of some
proposed_authority entry, and the deterministic-reproducibility
rule for narrowing-mode derivation applies
(Section 5); goal and constraints then serve
as rendering and bounding context over the proposed authority.¶
success_criteria:OPTIONAL. An array of strings. Human-readable
observable outcomes that indicate the task is complete. These are
disclosure and audit material only: they are rendered to the
Approver and committed by intent_hash (Section 6.3),
but carry no machine semantics and MUST NOT be used to derive,
widen, or gate authority.¶
purpose:OPTIONAL. A string. A URI identifying the purpose of the
task, recorded for disclosure and audit. Its semantics are
deployment- or registry-defined and opaque to this document; like
success_criteria it MUST NOT be used to derive, widen, or gate
authority. A deployment MAY consult it for out-of-band policy or
logging that does not affect the authority derived here.¶
expires_at:REQUIRED. A string. An RFC 3339 [RFC3339] date-time after which the AS MUST NOT derive tokens under the Mission.¶
controls:OPTIONAL. An object of machine-actionable bounds. This document defines the members below; others MAY be added by deployments or defined by companion profiles (an extension member follows the collision-resistant naming and fail-safe rules of Section 12):¶
acr:OPTIONAL. A string. An authentication context class for the
approval event: the approval authentication MUST be one the
deployment's policy maps as satisfying the named class. No global
ordering of acr values exists; the mapping is deployment policy.¶
max_derivations:OPTIONAL. A positive integer (1 or greater). A
bound on the number of derivations the issuer AS performs under the
Mission, enforced per Section 9. A value of 0 is invalid (it
would forbid even the initial issuance); to stop a Mission, revoke
it (Section 9.2). An AS MUST reject max_derivations below 1
with invalid_request. This is an issuer-AS
derivation cap, not an end-to-end credential cap: a cross-domain
issuance counts as one derivation, and tokens another domain mints
locally are not counted by the issuer, which cannot observe them
(Section 9; detail in
[I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
This document defines no cumulative consumption bounds (for example, a
budget, call-count, or activity-duration cap): every bound this
document defines is enforced by a party this document names. An
experimental companion defines cumulative consumption bounds as
controls extension members together with the runtime metering that
enforces them ([I-D.draft-mcguinness-mission-metering]). The
following table summarizes which party enforces each bound a Mission
carries and what holds when that enforcer is absent:¶
| Bound | Enforced by | When that enforcer is absent |
|---|---|---|
resource and actions
|
any Resource Server that enforces authorization_details (Section 8.2) |
a scope-only RS enforces only the coarse scope projection (Section 8.2) |
per-entry constraints
|
a Resource Server that understands and enforces the key (Section 8.2) | a Mission-aware RS fails closed; a scope-only RS does not evaluate them |
max_derivations
|
the issuer AS at each derivation (Section 9) | never absent at the issuer; it does not bound another domain's local minting (see the cross-domain companion) |
Example Mission Intent:¶
{
"goal": "Reconcile Q3 invoices and post adjustments under $500.",
"resources": ["https://erp.example.com"],
"constraints": [
"Read only invoices issued in 2026-Q3.",
"Post journal entries under $500."
],
"success_criteria": [
"All Q3 invoices reconciled.",
"Each posted adjustment references a source invoice."
],
"purpose": "urn:example:purpose:reconcile",
"expires_at": "2026-12-31T23:59:59Z",
"controls": {
"acr": "urn:example:acr:mfa",
"max_derivations": 200
}
}
¶
A client MUST submit a Mission Intent through a Pushed Authorization
Request [RFC9126] using the mission_intent request parameter. The
parameter value is the UTF-8 JSON [RFC8259] serialization of the
Mission Intent object, carried as an ordinary OAuth request-parameter
value (form-encoded in the application/x-www-form-urlencoded PAR
request body, like other OAuth parameters). The AS returns a
request_uri as usual, which the client uses to start authorization.
An AS that cannot parse mission_intent as a JSON object, or that
parses it but finds it structurally invalid against this document's
member definitions, MUST refuse the request with invalid_request.¶
A Mission Intent is closed at the top level: an AS MUST reject with
invalid_request a Mission Intent containing a top-level member this
document does not define. The top level is closed because its members
feed approval rendering and the intent_hash commitment: an undefined
member would enter what the Approver reads and what the anchor
commits. Extension data belongs under controls, so deployment-defined
semantics are explicit and cannot masquerade as core Intent semantics.
This closure also keeps issuer-output members, such as a client-planted
authority_hash, from entering through the Intent.¶
A different case is an Intent that is well-formed but from which the AS
cannot derive a valid Authority Set (for example, an unsupported
resource, action, or authorization details type, or a policy that bars
the requested authority). In that case the AS SHOULD refuse with
invalid_authorization_details ([RFC9396]), even though the client
did not submit authorization_details directly. This lets a client
distinguish a syntax error from an authority-derivation failure.¶
The Intent MUST arrive through PAR: an AS MUST reject with
invalid_request a mission_intent presented on a front-channel
authorization request that does not use a PAR-issued request_uri; a
stray mission_intent on a request that redeems a request_uri is
ignored, as specified below. The
prohibition applies regardless of carriage: a mission_intent carried
inside a signed request object is equally rejected; only PAR submission
is accepted. PAR
keeps the integrity-sensitive Intent off the untrusted front channel.
Because mission_intent is untrusted client input that the AS records,
derives from, and hashes, an AS MUST bound its total size and the
lengths of its arrays, refusing an Intent that exceeds the deployment's
limits with invalid_request, so an oversized Intent cannot exhaust the
AS at rendering, derivation, or hashing. The limits are
deployment-defined.¶
A client MUST NOT submit authorization_details directly together
with mission_intent; the AS derives authorization details from the
Intent (Section 5). A request carrying both MUST
be refused with invalid_request. This prohibition governs the raw
[RFC9396] request parameter; a client proposes concrete authority
inside the Intent, through proposed_authority
(Section 4). A client MAY submit scope and
resource ([RFC8707]) values; the AS treats them as a requested
subset and MUST NOT grant authority beyond what the Mission Intent
yields.¶
For a Mission request, the parameters pushed via PAR are authoritative.
The AS MUST ignore any mission_intent, authorization_details,
scope, or resource presented on the front-channel authorization
request that redeems the request_uri. The AS MUST NOT let such a
front-channel value widen the authority derived from the pushed Intent.¶
A Mission Intent is untrusted client input. Trust enters only when the AS validates it and the Approver consents to the rendered result. The AS MUST treat the submitted Intent as a proposal, never as authority. The AS MUST derive authority and bound it by policy regardless of what the client submitted. How a client produces the Mission Intent (for example, a "Mission Shaper" that derives it from a natural-language instruction) is out of scope for this document.¶
The approval event is the atomic transition at which the Approver
consents and the AS creates the Mission. It runs as an OAuth 2.0
[RFC6749] authorization-code flow initiated from the PAR-issued
request_uri (Section 4.1). Because the authorization code
is the artifact the Mission grant binds to (Section 6.1) and it
travels the front channel, the AS MUST bind the code to the requesting
client with PKCE ([RFC7636], S256 challenge method) or,
equivalently, issue a DPoP-bound authorization code ([RFC9449]). The
AS MUST reject a code redemption whose PKCE verifier or DPoP key does
not match the binding established for the request. This prevents
authorization-code injection from yielding the Mission grant.¶
At the approval event the AS MUST, in order:¶
Authenticate the Approver. If the Mission Intent's
controls.acr is present, the authentication MUST satisfy it.¶
Establish the Subject: the principal the task is for, recorded as
the Mission's subject and set as the sub of every derived token
(Section 8). When the Approver is the Subject
(self-approval), this is the authenticated Approver. When the
Approver is a different principal (for example, an administrator or
manager approving on a user's behalf), the AS MUST itself establish
the Subject's (iss, sub), and MUST authorize the Approver to
approve for that Subject under local policy. The AS MUST NOT take the
Subject from unauthenticated client input. This document defines no
wire parameter for the Subject; how the AS establishes it
(administrative selection, a directory, an authenticated reference)
is a deployment matter.¶
Render for consent the derived Authority Set in human-meaningful
terms, with the goal, constraints, expires_at, and any
controls bounds (notably max_derivations) as context. The object
the Approver consents to is the derived Authority Set, what the
agent may actually do, not the goal or Mission Intent: derivation
is local policy, and nothing commits that the derived authority
faithfully reflects the goal the Approver read, so the authority
itself MUST be what is rendered and consented to. An approval surface
that renders only the goal, success_criteria, or Mission Intent
and not the derived Authority Set does not conform. When the Approver
is not the Subject, the rendering MUST identify the Subject the
authority is granted for. When the Intent carried
proposed_authority (Section 4), the rendering MUST
distinguish the entries the client proposed from any narrowing or
restructuring the AS applied.¶
Compute the integrity anchors (Section 6.3):
authority_hash over the consented Authority Set and
intent_hash over the approved Mission Intent.¶
Create the Mission record (Section 7) in the active
state, atomically with issuance of the authorization code.¶
Client-supplied strings (goal, constraints, success_criteria)
MUST be rendered as inert text and MUST NOT be interpreted as markup.
The AS SHOULD mitigate Unicode direction-override and
confusable-character presentation in them. The rendering MUST visually
distinguish the AS-derived Authority Set from client-supplied text, so
crafted client text cannot pass as derived authority.¶
A deployment MUST declare a minimum approval-authentication strength
for Missions whose derived Authority Set carries high-risk authority:
irreversible, external-commitment, or privileged-administration
actions under the deployment's classification, or a consumption bound
([I-D.draft-mcguinness-mission-metering]). The approval
authentication for such a Mission MUST meet that minimum, and
controls.acr can raise the required strength but never lower it below
the floor. The material notices of the consent-evidence profile
identify these same high-risk classes
([I-D.draft-mcguinness-oauth-mission-consent-evidence]).¶
An Approver who declines, and an Approver whose authentication cannot
satisfy controls.acr or the declared approval-strength floor, yield
access_denied on the authorization
response ([RFC6749]). A token-endpoint resource value outside the
Authority Set yields invalid_target ([RFC8707]).¶
Rendering a bound is not the same as enforcing it, and a deployment MUST NOT let the rendering imply otherwise. Which party enforces each bound, and what holds when that enforcer is absent, is summarized in the enforcement table (Section 4). An AS SHOULD make clear to the Approver which rendered bounds its deployment actually enforces, so consent is not given to a limit that binds nowhere.¶
The authority_hash is the authority commitment: it binds, by
cryptographic digest, exactly the authority the Approver approved. It
commits the approved authority, not the way that authority was
rendered to the Approver; this profile commits no separate consent
disclosure object (see Section 15.1). If the derived Authority
Set changes between rendering and consent, the AS MUST recompute and
MUST refuse to activate unless the Approver consents to the changed
set. Every token derived under the
Mission carries this value (Section 8), so a party
holding the full Authority Set can verify a token's authority against
what was approved. A party holding only a narrowed subset cannot
recompute it and treats it as an audit anchor (see
Section 15.1).¶
The intent_hash commits the approved Mission Intent: the
task the Approver consented to, as recorded on the Mission. It makes
the recorded task tamper-evident: an auditor can verify the Mission's
intent against intent_hash and detect any later
alteration. intent_hash commits the task; authority_hash
commits the authority derived from it.¶
At the approval event the AS binds the Mission to the authorization
grant it issues: the authorization code, and the refresh token
issued from it. The binding is server-side and is what "the
referenced Mission" in Section 9 refers to. At each subsequent
derivation the AS resolves the Mission from the grant the client
presents: the authorization code at the token endpoint (the initial
exchange uses grant_type=authorization_code), the refresh
token on refresh, or the Mission-bound subject_token on Token
Exchange (the actor_token identifies the delegate, Section 11).
It then applies the gating of Section 9. A client does
not supply mission_id to obtain a derivation; an AS MUST NOT derive
Mission-bound authority from a client-supplied mission_id, because
the grant, not the identifier, determines the Mission. When the
authorization code expires unredeemed, no derivation is possible under
the Mission; the AS SHOULD revoke the Mission or allow it to expire.¶
A client learns its mission_id from the mission claim's id on
each issued token (Section 8.1) or from the token response. This
document defines mission_id as an OPTIONAL token-endpoint response
parameter: a string carrying the Mission Identifier, returned
alongside the issued token. It is an informational reference only:
presenting it authorizes nothing (Section 9), and a client MUST NOT derive authority from it.¶
This document records exactly one approver: the
accountable principal who approved the Mission. Two richer patterns
are deliberately out of scope and deferred:¶
Multi-party approval (M-of-N or dual control), where more than
one principal must approve. The number of approvers is orthogonal
to the consent commitment: however many principals approve the same
rendered Authority Set, the authority_hash is identical, as is
every token derived from it. Multi-party approval raises the
assurance of how approval was obtained; it does not change the
artifacts this document produces. A deployment requiring dual
control today can obtain the additional approvals out of band and
record one accountable Approver under the same authority_hash;
this document simply does not natively represent the co-approvers.¶
Approval-authority provenance (the standing policy or delegation an administrator or headless approval traces back to). This is governance state about who stands behind a delegated approval, not part of binding tokens to approved authority, and is left to a governance layer.¶
Both anchors are computed the same way over a domain-separated, issuer-bound envelope:¶
Construct the envelope, where typ selects the committed object
and value is that object:¶
{
"typ": "<mission-intent | mission-authority-set>",
"iss": "<the AS issuer URL>",
"value": <the committed object>
}
¶
For intent_hash, typ is mission-intent and value is the
approved Mission Intent object. For authority_hash, typ is
mission-authority-set and value is the Authority Set as a JSON
array of entries.¶
Encode as sha-256: followed by the base64url, no-padding,
encoding of the digest.¶
The typ field domain-separates the two anchors so a digest of one
object can never be mistaken for the other. The iss binding
prevents a committed object from being transplanted across
Authorization Servers.¶
The typ value space is an extension point (Section 12):
additional committed objects use this same envelope with a new typ
and the canonicalization below. This document defines no registry of
typ values; each committing specification defines its own and relies
on the typ domain separation. To keep that domain separation safe
without a registry, a new typ value MUST be a collision-resistant name
(for example, a short name prefixed within a namespace the defining
profile controls, following the Collision-Resistant Name guidance of
[RFC7519] Section 4.2). The mission- prefixed values defined by
profiles that extend this document share an author-coordinated
namespace for this reason.¶
SHA-256 is the only digest algorithm this document defines; the
sha-256: prefix identifies it. Algorithm agility is future work.¶
A verifier MUST reject an integrity anchor whose algorithm prefix it
does not recognize. A verifier MUST NOT treat an unrecognized prefix as
sha-256. This ensures that adding an algorithm later cannot be
exploited as a downgrade.¶
JCS [RFC8785] alone does not make two implementations agree on every byte. The following rules close the remaining gaps; they apply to computing an anchor and to comparing committed values:¶
The committed value is exactly the object the AS recorded on the
Mission: the approved intent for intent_hash, the
authority_set for authority_hash. An auditor reproduces a
digest from the record alone.¶
The AS MUST reject an input object containing duplicate JSON member names before canonicalization; such input is invalid.¶
JCS does not reorder array elements, and this document defines no element sorting, so array order is significant. The AS MUST emit each array in a fixed, reproducible order; that order is part of the canonical form.¶
URI-valued members are compared byte-for-byte unless a member's
definition specifies a normalization. The only normalization this
document defines is the RFC 3986 [RFC3986] comparison of the
resource-containment test (Section 5.1), which applies to that
comparison alone: the default resource equality test of Section 5.1
remains an exact match, and anchor computation is always byte-exact
over the recorded values.¶
Test vectors for both anchors are provided in Appendix B.¶
A Mission is the durable record created at the approval event. Its
members are immutable after creation except for its state, and it is
identified by a Mission Identifier (Section 7.1). Its members do
not repeat the mission prefix: the record is the Mission, and
prefixed names belong to surfaces that reference a Mission from
outside it, such as the mission_intent request parameter and the
mission_id response parameter. Member names are spelled out
(issuer, expires_at, created_at) and are spelled identically on every
surface that carries Mission facts; the compact JWT names (iss,
exp, iat) describe a signed artifact's own envelope, or identify
a party in an {iss, sub} object, never the
Mission. Operational issuance bookkeeping, such as
the derivation count gated under Section 9, is AS-side state about
the Mission, not a member of the immutable record. Like the mission
claim (Section 8.1), the record is open (Section 12): a
companion profile of this document MAY record additional members set at
creation using short names coordinated with it (for example, a lineage
member linking the Mission to a predecessor or parent); any other
extension MUST use collision-resistant names. The members below are the
ones this profile defines:¶
id:REQUIRED. A string. The canonical Mission Identifier (Section 7.1).¶
issuer:REQUIRED. A string. The issuer URL of the Mission Issuer
that approved the Mission. Equals the iss of tokens that AS
derives; for cross-domain tokens it remains the originating AS even
though the issuing iss differs
([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
state:REQUIRED. A string. The current lifecycle state: active, revoked,
or expired in this profile, or an additional state defined by a
companion profile, subject to the forward-compatibility rule of
Section 9.¶
intent:REQUIRED. An object. The approved Mission Intent.¶
authority_set:REQUIRED. An array. The consented Authority Set.¶
authority_hash:REQUIRED. A string. The consent commitment over the Authority Set (Section 6.3).¶
intent_hash:REQUIRED. A string. The integrity commitment over the approved Mission Intent (Section 6.3), making the recorded task tamper-evident.¶
subject:REQUIRED. An object. The Subject, an object with iss and
sub.¶
approver:REQUIRED. An object. The Approver,
an object with iss and sub. MAY equal subject.¶
client_id:REQUIRED. A string. The Agent (OAuth client) that submitted the Mission Intent.¶
policy_version:REQUIRED. A string. The derivation policy version in effect at the approval event.¶
approval_event_id:REQUIRED. A string. A unique identifier of the approval event, used as the approval idempotency key.¶
created_at:REQUIRED. A string. RFC 3339 timestamp of creation.¶
expires_at:REQUIRED. A string. Mirrors
intent.expires_at.¶
The audit horizon is the deployment-declared retention window for
the Mission record and its evidence: at least the Mission's lifetime
plus a declared post-expiry period. After the Mission reaches a
terminal state (revoked or expired), the record MUST be retained
for the audit horizon.¶
A Mission Identifier is an opaque URL-safe ASCII string of
[A-Za-z0-9_-] characters, with at least 128 bits of entropy, carrying no
semantic content. It MUST NOT be reused. The record and the mission
claim carry it as id; a surface that references a Mission from
outside carries it as mission_id, as in the token-response parameter
(Section 6.1).¶
{
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"state": "active",
"intent": { "goal": "Reconcile Q3 invoices ...",
"resources": ["https://erp.example.com"],
"expires_at": "2026-12-31T23:59:59Z" },
"authority_set": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
],
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ",
"intent_hash":
"sha-256:wQ7p4LHnX9Md0LqJ6sZJ8b8mZ3rN2xT5pV4lE6sQqYY",
"subject": { "iss": "https://idp.example.com",
"sub": "user_3p2q8mN1a0kV7tR" },
"approver": { "iss": "https://idp.example.com",
"sub": "user_3p2q8mN1a0kV7tR" },
"client_id": "s6BhdRkqt3",
"policy_version": "deploy-policy:v17",
"approval_event_id": "ape_8K2nP4qV9rL3tY6sB1z",
"created_at": "2026-10-15T14:32:11Z",
"expires_at": "2026-12-31T23:59:59Z"
}
¶
Access tokens issued under a Mission are JWTs per [RFC9068], which
fixes the required claims (including jti) and the at+jwt JOSE
header typ ([RFC9068] Sections 2.1 and 2.2); a Resource Server
MUST verify the typ per [RFC9068]. In addition to what that
profile requires, a derived token:¶
carries the token's Mission-derived authority as
authorization_details ([RFC9396]); this MAY be the full Authority
Set or a narrowed subset (Section 5.1);¶
carries a mission claim (Section 8.1);¶
sets sub to the Mission's Subject sub and client_id to the
Mission's client_id;¶
MUST set aud to identify the Resource Server(s) authorized to
consume the carried authorization_details, and MUST NOT include an
audience unrelated to that carried authority (see below);¶
MAY carry an act claim when the agent has delegated execution
(Section 11);¶
MAY carry a scope claim, subject to the rule below;¶
SHOULD be sender-constrained, via a cnf claim [RFC7800]:
DPoP [RFC9449] (cnf.jkt) or mTLS [RFC8705] (cnf.x5t#S256).¶
The AS MUST NOT include authorization_details exceeding the
Mission's Authority Set. On any issuance that narrows authority (for
example, a single-audience token), each emitted entry MUST be a
subset of a Mission Authority Set entry under Section 5.1.¶
The aud SHOULD be derived from the resource indicators
([RFC8707]), Protected Resource metadata ([RFC9728]), or the
deployment's resource-to-RS mapping. It identifies the Resource
Server(s) and need not be byte-equal to the resource values of the
authorization_details entries: an aud typically names an RS, API,
or security domain, while RAR entries may name resources, accounts,
tools, or locations beneath it. Bounding aud to the consuming
Resource Server(s) prevents a confused-deputy or token-redirection
attack: a multi-resource Authority Set otherwise yields a token an
unrelated Resource Server would accept even though it was obtained to
act elsewhere. A deployment SHOULD prefer per-RS (single-audience)
tokens, narrowed under Section 5.1. A client requests such a token at
the token endpoint with the [RFC8707] resource parameter (and MAY
further narrow with scope); the AS narrows the Authority Set under
Section 5.1 to the requested resource(s) and sets aud to the
corresponding Resource Server(s). This is the within-domain
counterpart of the audience-scoping the Mission Issuer applies when
projecting authority to a Resource AS
([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
Sender-constraining is a SHOULD for this primary token, aligned with [RFC9700]. It is stronger (MUST) for delegated tokens, which face higher replay exposure in the hands of a less-trusted delegate (Section 11); the companion sets the same MUST for the credentials that cross a trust domain ([I-D.draft-mcguinness-oauth-mission-cross-domain]). A deployment SHOULD sender-constrain the primary token as well where its threat model warrants.¶
The token-endpoint response conveys the granted authority to the
client. Because the client submits mission_intent rather than
authorization_details, the access token is otherwise the only place
the granted authority appears, and a client is not expected to parse
the access token for authority. The AS therefore MUST return the granted
authorization_details in the token-endpoint response, per
[RFC9396] Section 7, reflecting exactly the (possibly narrowed) set
assigned to the issued token. (A client does read the mission claim's
id from the token to learn its mission_id, per Section 6.1;
"not expected to parse for authority" refers only to the
authorization_details, which the response echoes.) The same applies to refresh and Token
Exchange responses.¶
For example, the agent narrows the canonical ERP Mission (the worked
example of Section 7) to a read-only token, presenting the
Mission's refresh token with the [RFC8707] resource parameter and
narrowing further with scope:¶
POST /token HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2Iiwi... grant_type=refresh_token &refresh_token=rt_4mN8qV2xP7sL1tY9zB3k &resource=https%3A%2F%2Ferp.example.com &scope=invoices.read¶
The issuance is a derivation, gated on the Mission being active
(Section 9). The response echoes the narrowed grant and the
mission_id reference (Section 6.1); the emitted entry is a
subset (Section 5.1) of the Mission's read entry, its constraints
carried intact:¶
{
"access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
"token_type": "DPoP",
"expires_in": 300,
"mission_id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"authorization_details": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} }
]
}
¶
Mission-bound refresh tokens MUST be sender-constrained or use refresh
token rotation. This matters most for a public client, since
Mission-state gating bounds a stolen refresh token's usefulness over
time but not while the Mission is still active. This strengthens
the refresh-token guidance of [RFC9700] Section 2.2.2, whose MUST
applies to public clients, to all Mission-bound refresh tokens.¶
The authentication context of the approval event (controls.acr,
Section 4) describes the Approver at approval time and is
recorded on the Mission, not on derived tokens; a derived token's
authority comes from the Mission, not from a fresh authentication, so
this document requires no acr or auth_time claim on it. An AS MAY
include acr and auth_time per [RFC9068] to convey the approval
context, but a consumer MUST NOT treat their absence as an
authentication downgrade.¶
authorization_details is the authoritative expression of a
Mission-bound token's authority. Any scope the token carries MUST be
derived from, and no broader than, the Authority Set. Specifically:¶
every scope value MUST correspond to authority already present in
authorization_details; and¶
a scope value MUST NOT convey authority, or relaxation of a constraint, that the Authority Set does not grant.¶
Because scope is a coarse string list, it cannot carry the per-entry
constraints; it is a compatibility projection, never the
authoritative form of the Mission's authority. The AS MUST NOT issue a
Mission-bound token whose scope exceeds the Authority Set.¶
A credential the Mission Issuer derives MUST have an exp that does
not exceed the Mission's expires_at, so that no credential outlives
the approved Mission (not merely that none is issued after expiry). How
this bound extends transitively to tokens minted in another trust
domain is specified by the companion
([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
The mission claim is a JSON object:¶
id:REQUIRED. A string. The Mission Identifier (Section 7.1).¶
issuer:REQUIRED. A string. The Mission's issuer (Section 7). A
credential's iss names the party that minted it; mission.issuer
names the party that approved and serves the Mission, and the two
deliberately differ for tokens minted in another trust domain
([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
authority_hash:REQUIRED. A string. The Mission's
authority_hash, binding the token to the consented authority.¶
The mission claim is an open object (Section 12): additional
members MAY appear alongside the three above. This document defines no
registry of mission members. A companion profile of this document MAY
use short member names coordinated with it; any other extension member
MUST use a collision-resistant name (for example, a name in a namespace
the extension controls, per the Collision-Resistant Name guidance of
[RFC7519] Section 4.2) and is defined by the profile that introduces
it. A consumer MUST ignore members it does not understand and MUST NOT
use any additional member to grant or widen authority; the three
members above remain authoritative.¶
Example decoded token payload:¶
{
"iss": "https://as.example.com",
"sub": "user_3p2q8mN1a0kV7tR",
"aud": "https://erp.example.com",
"client_id": "s6BhdRkqt3",
"iat": 1797840000,
"exp": 1797840300,
"jti": "at_9Kp2vN7sR1tY8mZ3qX5b",
"authorization_details": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
],
"cnf": { "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" },
"mission": {
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ"
}
}
¶
A Resource Server enforces from the token alone; no call to the AS is required. A Resource Server:¶
MUST validate the JWT per [RFC9068] and verify any
sender-constraint binding (cnf).¶
MUST treat authorization_details as the authoritative expression
of authority and enforce the entries whose resource it serves,
permitting only the listed actions subject to constraints.¶
MUST fail closed on any constraints key it does not understand, or
understands but cannot enforce, in an entry whose resource it
serves: it MUST refuse the request (for example, a 403 with
insufficient_scope [RFC6750], or the deployment's usual
insufficient-authority error) rather than grant access while ignoring
the key. A constraints member narrows authority, so treating an
unenforceable key as absent would silently widen the grant; an RS
MUST NOT reduce a constraint to disclosure-only.¶
MUST NOT, when a token also carries scope, grant on the basis of a
scope value any access broader than the corresponding
authorization_details entry permits; in particular, scope MUST NOT be used to bypass a constraint carried only in
authorization_details.¶
MUST NOT treat client_id as the identity of the acting party on a
delegated token. This profile keeps client_id equal to the
Mission's approved agent on every derived token (Section 11); the
immediate actor is the outermost act. An RS that authorizes or logs
the caller MUST process the act chain to identify the acting party,
or it will attribute a delegate's action to the approved agent.¶
This act-processing requirement binds a Mission-aware RS. Because a
Mission-unaware [RFC9068] RS reads client_id as the immediate
client and would misattribute, a deployment SHOULD NOT route
delegated tokens to an RS that authorizes or logs on client_id
without processing act.¶
MAY, for a Mission-governed resource, be configured to require the
mission claim, and MUST then reject a token that lacks it with
invalid_token. This prevents downgrade by omission: where the same
AS also issues ordinary tokens, a token bearing equivalent
authorization_details but no mission claim is governed by no
Mission state, revocation, or consent commitment, and MUST NOT be
accepted where Mission governance is required. A protected resource
MAY advertise this requirement through the
mission_bound_authorization_required protected resource metadata
member (Section 14).¶
MAY treat the mission claim as audit and correlation context.¶
SHOULD, when serving Mission-bound requests, log the mission
claim's id and the token jti with each served request, so its
access logs join to Mission evidence.¶
MAY recompute authority_hash (Section 6.3). A Resource
Server that performs it recomputes the anchor
over the full Authority Set it independently holds, compares the
result to mission.authority_hash, and MUST reject on mismatch. It
additionally verifies that each carried authorization_details entry
is a subset (Section 5.1) of that held set. A narrowed token matches by
the subset test, never by hashing its carried entries: the anchor is
computed only over the full Authority Set, so a Resource Server MUST NOT recompute it from a token's carried subset.¶
MAY, where the AS offers it, introspect the token (Section 10)
to observe the Mission's current state per request rather than
relying on the token lifetime to bound revocation latency. An RS that
introspects MUST still verify the token's sender-constraint (cnf)
locally and MUST NOT treat an active: true result as proof the
caller holds the bound key; the AS does not check possession at
introspection (Section 10).¶
A Mission-unaware Resource Server that authorizes only from scope
still operates within the Mission at the coarse scope level, because
the AS derived and bounded that scope by the Authority Set
(Section 8); but it does not enforce the per-entry
constraints, which scope cannot carry. A deployment that relies on
those constraints MUST route the protected operation through a
Resource Server that enforces authorization_details (or the runtime
layer that evaluates them).¶
A Mission is in one of three states:¶
active: tokens MAY be derived. The only state from which issuance
proceeds.¶
revoked: terminated by the Subject, Approver, or
policy. Terminal.¶
expired: expires_at has passed. Terminal.¶
The transitions are:¶
| From | Event | To |
|---|---|---|
| (none) | approval event |
active
|
active
|
revoke |
revoked
|
active
|
expires_at reached |
expired
|
These three states are the mandatory core of the Mission lifecycle
state space. This profile owns that state space; an OPTIONAL companion
profile MAY define an additional state for a lifecycle it introduces
(for example, a paused or a superseded state), but only active ever
permits issuance. To keep the state space extensible without a registry,
a consumer MUST apply this forward-compatibility rule wherever a Mission
state is reported, including the Mission record and the introspection
mission member: only the exact value active permits
derivation or continued reliance, and every other value, including a
value the consumer does not recognize, MUST be treated as non-active and
non-deriving. A consumer MUST NOT fail open on an unrecognized state.
This makes a state added by a companion profile fail safe for a consumer
that predates it.¶
The AS MUST refuse to derive a token, at the token endpoint, on
refresh, and on Token Exchange ([RFC8693]), unless the
referenced Mission is active. Issuance against a revoked or
expired Mission MUST fail with invalid_grant. Because derivation
is gated on Mission state, revoking or expiring a Mission stops all
further authority for the task, including refresh. The active check
MUST be evaluated atomically with issuance, as the derivation-count
check already is, so a revocation serialized before an issuance is
honored by that issuance.¶
When the Mission Intent sets controls.max_derivations, the AS MUST
maintain a per-Mission count of derivations and MUST refuse with
invalid_grant any derivation that would exceed the bound. A
derivation is one issuance operation the issuer AS performs for a
single request: the initial authorization-code exchange, a refresh, a
Token Exchange, or a cross-domain grant issuance
([I-D.draft-mcguinness-oauth-mission-cross-domain]). Each counts
as exactly one, regardless of how many artifacts it emits: a code
exchange that returns both an access token and a refresh token is one
derivation, and a refresh that rotates both is one. The exact rules:¶
A derivation that fails, including one refused for exceeding the bound, MUST NOT be counted.¶
The check and increment MUST be atomic with issuance, so concurrent derivations cannot collectively exceed the bound.¶
The count covers only derivations the issuer AS performs. Tokens another domain mints locally under the Mission are not counted by the issuer, which cannot observe them; the cross-domain issuance that authorized them was counted once, and the local issuer bounds its own minting by its policy ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
The AS maintains this count as internal bookkeeping; it is operational state, not part of the immutable Mission record.¶
Derived tokens SHOULD be short-lived so that a transition to
revoked or expired takes effect promptly without per-request
revocation checks.¶
A Mission is revoked when the AS receives an authorized revocation
for it. A deployment MUST provide an authenticated means for the
Subject, the Approver, or an administrator to revoke a Mission by
mission_id, independent of possession of any token (so a Mission
can be stopped even when no refresh token is held).¶
This document does not define the wire shape of that operation.
Revocation is a management-plane action by a party in the AS's own
trust domain, not a cross-party protocol exchange, and the lifecycle
gate that makes it effective (Section 9, Section 10)
already rides on existing endpoints, so no standardized endpoint is
required for interoperability. A standardized Mission management API,
with suspend/resume/complete operations, is specified separately
by Mission Status [I-D.draft-mcguinness-oauth-mission-status]; this
document does not require it.¶
A deployment MAY additionally treat [RFC7009] revocation of a Mission's refresh token as revoking the Mission. A deployment MUST NOT couple routine token revocation to Mission revocation unless it documents that behavior. Already-issued access tokens remain valid until they expire; a deployment requiring lower cutoff latency SHOULD use short token lifetimes.¶
The stateless baseline needs no status surface: a token is a
self-contained authorization and verification is stateless. A
deployment MAY additionally offer token introspection
(Section 10) so a Resource Server can observe Mission state
per request and cut off a revoked Mission without waiting out the
token lifetime. A canonical Mission Status surface (keyed by
mission_id) and signed status responses are specified separately as
an OPTIONAL companion profile by Mission Status
[I-D.draft-mcguinness-oauth-mission-status]; this document does not
require them.¶
Token validity and Mission validity are distinct: a token can outlive a transition of its Mission, by at most the token lifetime. A deployment whose consumers rely on Mission state beyond a token's lifetime SHOULD offer introspection (Section 10) or the Mission Status companion, so an authorized party can determine the Mission's current state rather than inferring it from token validity.¶
This section is OPTIONAL. The stateless baseline
(Section 8) needs no introspection; an AS that does not
offer it, and a Resource Server that does not use it, are unaffected.
It lets a Mission-state-aware Resource Server observe a Mission's
current state per request instead of waiting out a token's lifetime.
Because it can report Mission state for a token whose Mission is no
longer active, this section deviates from the SHOULD NOT of
[RFC7662] Sections 2.2 and 4 against including additional
information about an inactive token; that deviation is justified and
governed by the caller-authorization and minimization
rules below (Section 10.1).¶
An AS MAY support OAuth 2.0 Token Introspection [RFC7662] for
Mission-bound access tokens. When it does, the response for such a
token carries, in addition to the standard members, a mission
member: id, issuer, and authority_hash (as in the mission
claim, Section 8.1) plus, when the responding AS is the Mission
issuer, the current lifecycle state (string). The core states are active, revoked,
and expired (Section 9); a deployment that runs a companion
profile defining an additional state reports that state here, and a
consumer applies the forward-compatibility rule of Section 9 (only
active permits reliance; any other value, recognized or not, is
non-active). Only the issuer reports state
(Section 10.3).¶
The AS includes the mission member only when it has authenticated the
caller, the caller is authorized for the token
(Section 10.1), and the presented token
resolves to a Mission. For a malformed, unknown, individually expired, or
otherwise unresolvable token, the AS responds per [RFC7662]
(active: false) with no mission member; it does not reveal Mission
state for a token it cannot bind to a Mission. The case below
(active: false with mission.state) applies only to a token that is
itself valid but whose Mission is no longer active.¶
The composite-active rule (Section 10.2) and the mission
member apply equally when a Mission-bound refresh token is introspected.¶
The introspection active member reflects the composite
authorization, not the token in isolation. The AS MUST return
active: true only when the access token is itself valid (valid
signature, unexpired, and not individually revoked) AND the Mission
is active. The AS does not verify the token's sender-constraint
(cnf) at introspection: proof of possession is checked by the
Resource Server when the token is presented, not by the AS over an
introspection call, so active: true is not by itself evidence the
caller holds the bound key.¶
When the token is otherwise valid but the Mission is revoked or
expired, the AS MUST return active: false and include
mission.state giving the reason, so a Resource Server can
distinguish a dead Mission from a bad token. (This deviates from the
[RFC7662] SHOULD NOT against including members when active is
false.) A
Mission transition does not by itself revoke the token as an
individual credential; introspection reports the composite
authorization as inactive.¶
An AS MUST NOT include mission.state in an introspection response
unless it holds the Mission, that is, unless it is the Mission
issuer. Introspection at a non-issuer Resource AS, which returns the
claim-shape members only and never state, is specified by the
companion ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
This is token introspection: it answers "is this token's
authorization still good," keyed by the token presented. The
canonical Mission Status surface (keyed by mission_id) remains out of scope
(Section 9.2).¶
While the Mission is active, the response is the standard
[RFC7662] body plus the mission member. The canonical ERP token
(Section 8.1), introspected at the issuer AS:¶
{
"active": true,
"iss": "https://as.example.com",
"sub": "user_3p2q8mN1a0kV7tR",
"client_id": "s6BhdRkqt3",
"aud": "https://erp.example.com",
"exp": 1797840300,
"authorization_details": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
],
"mission": {
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ",
"state": "active"
}
}
¶
The same token after the Mission is revoked, reported per the composite-active rule (Section 10.2):¶
{
"active": false,
"mission": {
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ",
"state": "revoked"
}
}
¶
This section is OPTIONAL. A deployment whose agents never delegate, and a Resource Server that sees no delegated tokens, are unaffected.¶
An agent may delegate execution to downstream actors (a sub-agent,
service, or tool that is itself an OAuth client) within a Mission.
Delegation is represented with the OAuth Actor Profile
[I-D.draft-mcguinness-oauth-actor-profile], which profiles the
RFC 8693 [RFC8693] act (actor) claim.¶
A delegate obtains a delegated token by Token Exchange ([RFC8693]). The AS issues the delegated token subject to all of the following:¶
The exchange is explicit. The delegating Mission-bound access
token is the subject_token, with subject_token_type of
urn:ietf:params:oauth:token-type:access_token. The delegate is
identified by an actor_token (with its actor_token_type) or by
its own client authentication, and the AS asserts the actor itself
(Section 11.3); a requested_token_type of
urn:ietf:params:oauth:token-type:access_token is used. The
response carries the matching issued_token_type and a token_type
for the issued access token, per [RFC8693] Section 2.2.1.¶
Subject is stable. sub remains the Mission's Subject. The
delegate is an actor, not the subject.¶
The approved agent stays client_id. This profile keeps
client_id equal to the Mission's approved agent on every derived
token (Section 8), so the approved party is
verifiable everywhere. Downstream delegates are carried in the
act chain, not in client_id. For delegated tokens this
deliberately overrides the client_id definition of [RFC8693]
Section 4.3, which [RFC9068] Section 2.2 incorporates (the client
that requested the token); here the immediate delegate is the
outermost act.¶
The act chain identifies the delegates. The delegated token
carries an act claim per the Actor Profile
[I-D.draft-mcguinness-oauth-actor-profile]: the outermost act is
the immediate delegate, with prior delegates nested inward, back
toward the approved agent. Each actor object
carries the members that profile defines (sub, iss, and the
RECOMMENDED sub_profile actor-type classification, e.g.
ai_agent). This document does not re-specify the act structure.¶
Authority only narrows. The delegated token's
authorization_details MUST be a subset (Section 5.1) of the
delegating token's authority, hence of the Mission Authority Set.
Delegation MUST NOT add authority.¶
The Mission binding rides unchanged. The delegated token
carries the same mission claim (Section 8.1), its
id, issuer, and authority_hash, so every actor in
the chain operates under the one consented authority.¶
Each delegate is bound to its own key. The delegated token MUST
be sender-constrained (Section 8) to the delegate's
own key: its cnf is the delegate's DPoP or mTLS key, not the
delegating party's. The delegate proves possession of that key in
the Token Exchange. A compromised delegate key therefore cannot be
replayed as the agent or as another actor in the chain, and each
actor's credential is independently revocable by key.¶
Each delegation is gated. Issuing a delegated token is a
derivation event; the AS MUST refuse it unless the Mission is
active (Section 9).¶
Where a deployment authenticates client instances
([I-D.draft-mcguinness-oauth-client-instance-assertion]; for AI
agents, its agent profile
[I-D.draft-mcguinness-oauth-ai-agent-instance]), the delegate
identified by the outermost act is the concrete instance: act.sub
is the instance identifier and act.cnf is the instance-specific
key. This profile's requirement that a delegated token be
sender-constrained to the delegate's own key then lands on an
instance-possessed key by construction. An allowed_delegates
matcher can select instance-grade actors
(Section 11.3), for example
{ "sub_profile": "client_instance" }. The sub_profile values
used here (ai_agent, client_instance) are drawn from the
entity-profiles vocabulary those instance profiles use; the Actor
Profile [I-D.draft-mcguinness-oauth-actor-profile] remains the
structural reference for the actor object.¶
A rejected alternative rebinds client_id to the immediate delegate
on each hop, the plain [RFC9068] reading in which client_id names
the immediate client. Rebinding loses the stable approved-agent
binding that every consumer of a derived token can verify: each
downstream token presents as a new client rather than an actor
executing within the approved Mission, and joining who was approved to
who executed requires reconstructing the hop history from issuance
records rather than reading both from the token. Rebinding is also
safe only where every Resource Server processes act anyway, since
the delegation history lives nowhere else; that is exactly the
discipline this profile's chosen design requires, so rebinding buys no
relaxation. The operational rule of Section 8.2 therefore holds
regardless of the binding choice: a Resource Server that authorizes or
logs the caller MUST process the act chain, and a deployment SHOULD NOT route delegated tokens to a Resource Server that authorizes or
logs on client_id without processing act.¶
An agent MAY present its own Mission-bound access token as the
subject_token of a Token Exchange ([RFC8693]) with no actor, to
obtain a narrowed token (for example, a single-audience one). The
result MUST be a subset (Section 5.1) of the presented token's
authority, carries the same mission claim (Section 8.1), and
adds no act chain. It is a derivation and is gated on the Mission
being active (Section 9). Because it names no actor, it does not
delegate: it re-scopes the agent's own authority downward.¶
What may be delegated, how far, and to whom is governed per
Authority Set entry by the entry's optional delegation member
(Section 5). Because the policy lives in the
entry, it is committed by authority_hash with the rest of the
Authority Set and travels with the entries wherever they are carried,
including across a cross-domain projection
([I-D.draft-mcguinness-oauth-mission-cross-domain]), needing no
separate mechanism.¶
Delegation depth. The delegation depth of a token is the number
of actors in its act chain (the nesting depth of the act claim),
counted from the approved agent: the agent's own non-delegated token
is depth 0, the first delegate is depth 1, and each further delegate
adds 1. The depth checked against max_depth is that of the token
being issued, computed after appending the new outermost actor, not
the depth of the delegating token. A credential projected across a
trust domain carries no act chain and enters the target domain at
depth 0 ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
Per-entry enforcement. When the AS issues a token to a delegate
(the actor that becomes the outermost act) at delegation depth
d, it includes a Mission Authority Set entry in the delegated
token's authorization_details only if all of the following hold:¶
the entry carries a delegation member (otherwise it is
non-delegable, which is the default);¶
d is less than or equal to the entry's delegation.max_depth;
and¶
the delegate is permitted by delegation.allowed_delegates, or
that member is absent.¶
An entry failing any of these narrows out of the delegated token,
consistent with the subset rule (Section 5.1). The delegation
member is policy, not authority, and is not part of the subset
comparison; surviving entries are carried with their delegation
member intact so the next hop is evaluated the same way.¶
Matching allowed_delegates. Each entry is a matcher object
modeled on the RFC 8693 may_act actor object ([RFC8693] Section
4.4): where may_act names a single party eligible to act on a token,
allowed_delegates is a per-Authority-Set-entry list of such
matchers, generalized to actor-type classes. A { "sub": ... }
matcher permits a specific delegate by client identifier; a
{ "sub_profile": ... } matcher permits any actor of that type (for
example, ai_agent). An actor's sub_profile MAY carry multiple
space-separated values; a { "sub_profile": ... } matcher is
satisfied when its value is among the actor's values. A deployment
can thus permit a specific client,
a class of actors, or both, and a delegate is permitted if it matches
any entry. The AS MUST authenticate the delegate at the Token Exchange
and assert the actor's sub and sub_profile itself. A self-asserted
sub_profile MUST NOT satisfy a matcher; otherwise a client could
claim any actor type to bypass the constraint.¶
A { "sub": ... } matcher is a client identifier in the issuing AS's
namespace and is not portable across a trust domain; how a Resource AS
evaluates conveyed matchers, failing closed and narrowing out any
sub matcher it cannot resolve, is specified by the companion
([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
Empty result. If narrowing leaves no entries for the delegate,
the AS MUST refuse with invalid_target ([RFC8693] Section 2.2.2)
rather than issue a token with empty authority: the requested
delegation has no authority to carry, while the subject grant itself
remains valid for other exchanges.¶
The Resource Server enforces none of this. Delegation
constraints are applied by the AS at issuance; a Resource Server sees
only the already-narrowed authorization_details and enforces those
as usual (Section 8).¶
Suppose the Mission's Authority Set has two entries on the ERP:
invoices.read, delegable to ai_agent actors through depth 2; and
journal-entries.write, which carries no delegation member and is
therefore non-delegable. The approved agent s6BhdRkqt3 delegates to
sub-agent tool-runner-7, an ai_agent, at depth 1. The read entry
is permitted (depth 1 <= 2, ai_agent allowed) and the write entry
narrows out. The decoded delegated access token:¶
{
"iss": "https://as.example.com",
"sub": "user_3p2q8mN1a0kV7tR",
"aud": "https://erp.example.com",
"client_id": "s6BhdRkqt3",
"iat": 1797840600,
"exp": 1797840900,
"jti": "at_3qX5bN7sR1tY8mZ9Kp2v",
"authorization_details": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} }
],
"act": {
"sub": "tool-runner-7",
"iss": "https://as.example.com",
"sub_profile": "ai_agent"
},
"cnf": { "jkt": "qVx7y2N0p4Lq9Md3sZJ8b8mZ3rN2xT5pV4lE6sQqYY" },
"mission": {
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ"
}
}
¶
sub is still the user and client_id is still the approved agent;
tool-runner-7 appears only as the actor. The cnf is
tool-runner-7's own key, not the agent's, so this token cannot be
replayed as the agent. The non-delegable write entry was dropped; the
read entry survives, carrying its delegation member so a further hop
can be evaluated: a depth-3 delegate, or a non-ai_agent one, would
narrow it out too. The mission claim is unchanged.¶
This profile is a base layer that other agent-authorization work is expected to extend. Extensions build alongside the stable interface below; they MUST NOT redefine it. An extension MAY rely on these remaining stable across revisions of this profile:¶
the mission claim members id, issuer, and authority_hash
(Section 8.1);¶
the mission_resource_access authorization details shape
(Section 5); and¶
the act delegation chain (Section 11).¶
The profile offers four extension points, each a declared seam rather than new machinery:¶
Authority types. The Authority Set is open to other AS-supported
authorization_details types (Section 5.3); the Mission
apparatus (commitment, gating, delegation) is type-agnostic toward
them, subject to the delegation and projection limits in
Section 5.3.¶
Integrity anchors. Additional committed objects use the same
domain-separated, issuer-bound envelope with a new typ
(Section 6.3). A consent-disclosure commitment, an
instruction-text attestation, or a delegation receipt can be
committed this way without changing this profile. A profile that
commits an evidence or disclosure object MUST commit it with this
envelope and a collision-resistant typ, not by hashing the bare
object, so the domain separation and issuer binding hold uniformly. A
mission descriptor embedded in such an object uses the mission
claim shape (Section 8.1), optionally extended with
collision-resistantly named members (for example, an intent_hash
for audit), and is never authority-bearing on its own.¶
The mission claim. It is an open object (Section 8.1):
additional, collision-resistantly named members ride the mission
binding (for example, a runtime decision reference, a delegation
receipt, or an attestation reference), and consumers ignore unknown
members and never derive authority from them.¶
Lifecycle state. The lifecycle state space (Section 9) is open
to additional states defined by companion profiles for lifecycles they
introduce. The forward-compatibility rule in Section 9 keeps this
safe without a registry: only active permits issuance, and a consumer
treats every other state, recognized or not, as non-active.¶
This document defines no extension registry, capability-negotiation
mechanism, or profile-version field; an extension declares its own
identifiers and, where it needs discovery, its own metadata. The
extensibility of the typ value space, the mission claim, and the
lifecycle state space rests on collision-resistant naming and the
fail-safe rules above rather than on central registration.¶
An AS MAY advertise support for this specification in its authorization server metadata [RFC8414]:¶
mission_bound_authorization_supported:OPTIONAL boolean. When true, the AS supports the core Mission
Issuer surfaces of this profile (Section 2): the
mission_intent authorization request parameter through PAR
(Section 4), derivation of mission_resource_access
authorization details (Section 5), Mission-bound
access tokens (Section 8), and the mission JWT claim
(Section 8.1). It asserts Mission Issuer support only; it makes
no claim about any Resource Server, nor about the OPTIONAL
capabilities (delegation, introspection, cross-domain projection),
which are discovered out of band or by attempt (Section 2).¶
An AS that advertises this profile SHOULD also include
mission_resource_access in its authorization_details_types_supported
metadata ([RFC9396]), so that RFC 9396-aware clients
discover the authorization details type through the standard mechanism.
A client MAY use the RFC 9396 client metadata authorization_details_types
at registration to declare the types it understands.¶
Discovery is OPTIONAL: a deployment MAY arrange Mission-bound
authorization out of band, and this member only lets an AS advertise
it. When the member is absent or false, a client MUST NOT infer
that the AS supports this specification.¶
An AS that advertises mission_bound_authorization_supported: true
MUST also publish pushed_authorization_request_endpoint
([RFC9126]), since a Mission Intent is accepted only through PAR
(Section 4.1).¶
This member and the mission_bound_authorization_required member of
Section 14 are unauthenticated discovery data:
their integrity rests on the metadata retrieval protections of
[RFC8414] and [RFC9728], whose security considerations apply.¶
A protected resource MAY advertise, in its protected resource metadata [RFC9728]:¶
mission_bound_authorization_required:OPTIONAL boolean. When true, the protected resource accepts only
Mission-bound tokens: a token that lacks the mission claim
(Section 8.1) is rejected (Section 8.2). When absent or
false, the resource makes no such requirement.¶
The security goal of this document is that a user's approval of a
task bounds every token derived for it. The authority_hash is the
mechanism: it commits the exact Authority Set the Approver
consented to, and every derived token carries it in the mission
claim. An AS MUST compute authority_hash over the same Authority
Set it rendered for consent, and MUST re-render and re-consent if that
set changes (Section 6). authority_hash commits the full
Authority Set, while a derived token may carry a narrowed subset, so a
Resource Server cannot in general recompute it from the token alone.
Recomputation is OPTIONAL. A Resource Server that performs it
recomputes the anchor over the full Authority Set it independently
holds, compares the result to mission.authority_hash, and MUST reject
on mismatch; it additionally verifies that each carried
authorization_details entry is a subset (Section 5.1) of that held
set. A narrowed token matches by that subset test, never by hashing
its carried entries: the anchor is defined only over the full set. A
Resource Server that does not hold the full Authority Set treats
authority_hash as a whole-Mission audit and correlation anchor
([I-D.draft-mcguinness-oauth-mission-cross-domain]) and enforces the
token's authorization_details directly (Section 8).¶
intent_hash extends the same protection to the task itself: it
commits the approved Mission Intent, so an auditor can detect any
later alteration of the recorded task, independently of the authority
derived from it. The two anchors are domain-separated
(Section 6.3); neither is a substitute for the other.¶
The task and the authority are committed separately, rather than folded
into one hash over the whole Mission, because they are distinct objects
with distinct uses. authority_hash commits what a Resource Server
enforces and what a cross-domain projection carries, so it MUST be
verifiable from a token that conveys only the authority, without the
Intent. intent_hash commits the task as audit material, tamper-evident
even where the authority is projected without the Intent traveling with
it. One combined hash could not serve both a token that carries
authority alone and an auditor that holds the task alone.¶
Neither anchor proves the Approver understood the rendered task, nor that the AS rendered it faithfully; they commit what the AS recorded, and make post-hoc tampering of those records detectable.¶
This profile commits the task (intent_hash) and the authority
(authority_hash) the Approver consented to, but deliberately does
not commit the rendered consent disclosure itself: the locale,
disclosure-template version, and material notices the Approver was
shown are not bound by any anchor here. Because of this gap, a buggy or
malicious rendering layer could mislead the Approver, showing a
narrower or different task than the Authority Set actually committed,
without leaving any committed trace. A deployment whose Missions carry
high-risk authority SHOULD therefore record presentation-level audit
evidence: for example, a hash over the exact consent disclosure
rendered to the Approver, retained so the disclosure shown can be
reconstructed and audited after the fact. Binding this on the wire (a
consent_rendering_hash over a structured consent-disclosure object)
is specified as an OPTIONAL companion profile by Mission Consent
Evidence [I-D.draft-mcguinness-oauth-mission-consent-evidence]; an AS
that does not implement it MAY record equivalent evidence out of band.
As that profile makes explicit, such a commitment binds the structured
disclosure the AS records, not the pixels actually presented; it
narrows this gap for audit but does not close it.¶
Because issuance is gated on Mission state and bounded by the
Authority Set, an agent cannot escalate beyond the approved task by
acquiring additional tokens: every derived token is a subset of the
approved authority (Section 5.1), and no token can be derived once the
Mission is revoked or expired. Deployments SHOULD keep derived
token lifetimes short so state transitions take effect promptly.¶
A token bearing equivalent authorization_details but no mission
claim is governed by no Mission state, revocation, or consent
commitment. A deployment that designates a resource Mission-governed
MUST NOT issue tokens for that resource outside a Mission, except under
documented policy exceptions. On the enforcement side, a Resource
Server for such a resource rejects a token lacking the mission claim
(Section 8.2), and MAY advertise the requirement through
mission_bound_authorization_required
(Section 14).¶
An agent that reads attacker-influenceable content can be prompt-injected; this profile assumes that and does not try to make the agent immune. Injection is dangerous when one agent combines access to private data, exposure to untrusted content, and the ability to communicate externally; the robust defense is architectural, constraining one of those, not making the model resistant.¶
This profile constrains the data-access leg: a Mission narrows authority
from everything the agent's standing credentials allow to the resources
the approved task needs, and per-task Missions (Section 1.5) shrink
the blast radius further. It contributes one thing against the
untrusted-content leg: purpose and success_criteria are inert,
granting, widening, and gating no authority, and goal shapes
authority only through the pre-approval derivation whose result the
Approver reads and consents to (Section 4,
Section 5); authority is fixed at the approval
event, so injected text cannot talk an approved Mission into
expanding itself.¶
This profile does not constrain the external-communication leg and provides no information-flow control. It models authority over resources and actions, not how an agent uses authority it holds: within an approved Authority Set, an injected agent can read what the Mission permits and write to a sink the Mission permits, and the flat subset and constraint model cannot express "may read secrets, may write documents, but not write secrets into documents." Constraining exfiltration by a compromised agent is the runtime enforcement layer's role (Section 15.5), and even there it is bounded, not closed (see that profile's security considerations). Closing within-scope data laundering needs a separate taint or information-flow layer this profile does not define.¶
This profile governs the issuance and derivation of authority: it bounds what authority a Mission yields, binds it to the Approver's consent, and gates derivation on Mission state. It does not evaluate individual runtime actions. In particular, it does not:¶
evaluate a request's parameters against the Mission at the point of use;¶
produce runtime enforcement evidence for each consequential action;¶
bind tool or function identities to the Mission; or¶
re-evaluate at execution time to close the approval-to-execution (time-of-check to time-of-use) gap.¶
Mission governance is necessary but not sufficient. An active Mission still bounds a set of authority an agent may exercise freely within a token's lifetime, so an active Mission can become ambient authority for individual consequential actions. Preventing that requires a runtime enforcement layer that evaluates each consequential action against the Mission and records evidence; such a layer composes with this profile and is out of scope here. Which party enforces each Mission-carried bound is summarized in the enforcement table (Section 4). Short token lifetimes and narrow authority bound, but do not eliminate, this exposure.¶
Derived tokens are sender-constrained (DPoP [RFC9449] or mTLS [RFC8705]) at the levels set in Section 8 and Section 11: SHOULD for the primary access token, MUST for delegated tokens; the companion sets the same MUST for its cross-domain credentials ([I-D.draft-mcguinness-oauth-mission-cross-domain]). A stolen token is bounded by the Authority Set and the Mission lifetime regardless, but sender-constraint prevents replay by a different party.¶
Delegation (Section 11) widens the set of parties holding
Mission-derived authority. Because authority only narrows down the
chain, a compromised actor can act only within the authority it was
delegated, for the lifetime of the token it holds: the exposure of
any actor is bounded by its narrowed authorization_details times
its token lifetime. The per-entry delegation constraints
(Section 11.3) bound this exposure at approval time:
non-delegable entries never reach a delegate at all, max_depth
caps how far an entry can propagate, and allowed_delegates
restricts who may receive it. Note that max_depth bounds the
length of a delegation chain, not its breadth: fan-out to many
distinct depth-1 delegates is bounded only by allowed_delegates, so
a deployment that needs to limit breadth MUST constrain
allowed_delegates (and MAY use max_derivations to cap total
derivations). Because each delegated token is bound
to the delegate's own key (Section 11), a compromised delegate is
confined to its own narrowed credential: it cannot replay as the
agent or another actor, and its credential can be revoked by key
without revoking the rest of the chain. Deployments SHOULD keep
delegated token lifetimes short and SHOULD make only the entries that
need delegation delegable.¶
The mission claim and authorization_details are carried inside
the [RFC9068] JWT and are covered by the AS's token signature; their
integrity reduces to the AS's signing key. An AS MUST publish its
verification keys (for example, via [RFC8414] jwks_uri) and
SHOULD retain the verification key for each key identifier it has
signed under long enough to verify tokens issued before a rotation.¶
The AS is trusted to derive authority no broader than the Mission
Intent. Deployments SHOULD constrain derivation with explicit
resource and action mappings rather than free-form inference, and
SHOULD record policy_version so a derivation can be audited and
reproduced. General OAuth security guidance [RFC9700] applies.¶
A Mission Identifier is a correlation handle: a deployment limits exposure by giving stable Mission Identifiers only to parties that enforce, audit, or observe that Mission, preferring audience-scoped projections of authority where possible, and minimizing status and introspection disclosures to authorized callers. The subsections that follow and the introspection minimization rules (Section 10.1) give the specific rules.¶
This document carries a single canonical Mission Identifier on every
derived token; the companion's cross-domain projection carries it
across trust domains unchanged
([I-D.draft-mcguinness-oauth-mission-cross-domain]). Any party that
observes credentials for the
same Mission, whether a Resource Server, a Resource AS, or an auditor
spanning audiences, can correlate that activity by the Mission
Identifier, and mission.issuer further identifies the issuing AS.
This is intentional:
a stable, correlatable Mission anchor is what lets a Resource Server, a
cross-domain Resource AS, and an auditor bind credentials and evidence
to one approved Mission, which the governance and audit properties of
this document and its companion profiles depend on. The cost is that
this profile does not provide
cross-audience unlinkability, and that is a deliberate non-goal for this
version (Section 1.7), not an unfinished feature. Audience-pairwise
(or request-pairwise) Mission references, in which the issuer projects a
distinct opaque identifier per audience and resolves them server-side,
are the fuller mechanism for unlinkability; because they work against
the stable anchor, they are future work rather than a v1 property. A
deployment that carries the canonical Mission Identifier on the wire
SHOULD document this correlation property.¶
The carried constraints and a multi-resource Authority Set disclose
the shape of the task and its business bounds (for example, an amount
ceiling) to every holder and every audience of a derived token.
Per-RS single-audience tokens are the minimization measure: they carry
only the entries the consuming Resource Server needs, and this
document recommends them (Section 8). The privacy
considerations of [RFC9396] apply to the carried
authorization_details.¶
This document registers the following in the "OAuth Parameters" registry:¶
Name: mission_intent¶
Parameter Usage Location: authorization request¶
Change Controller: IETF¶
Name: mission_id¶
Parameter Usage Location: token response¶
Change Controller: IETF¶
Specification Document(s): this document, Section 6.1¶
PAR [RFC9126] carries authorization-request parameters without a
distinct usage location, so the pushed submission of mission_intent
needs no separate registration.¶
mission_resource_access is an authorization_details type per
[RFC9396] Section 2, defined by this document in
Section 5. RFC 9396 does not establish an IANA
registry of authorization details types (type identifiers are
interpreted by the Authorization Server), so this document creates no
registry entry for it and requires no IANA action here. If a registry
of authorization details types is established in the future, this type
SHOULD be registered in it.¶
This document registers the following in the "JSON Web Token Claims" registry:¶
Claim Name: mission¶
Claim Description: Reference to the Mission a token was derived
under, with the consent-commitment authority_hash. An open object;
additional members may be present and are ignored if unknown.¶
Change Controller: IETF¶
Specification Document(s): this document, Section 8.1¶
This document registers the following in the "OAuth Token Introspection Response" registry ([RFC7662]):¶
Name: mission¶
Description: The Mission a token was derived under. Same object shape
as the mission JWT claim (Section 8.1); a response from the
Mission's issuer additionally carries a state member giving the
current lifecycle state (Section 10).¶
Change Controller: IETF¶
Specification Document(s): this document, Section 10¶
This document registers the following in the "OAuth Protected Resource Metadata" registry ([RFC9728]):¶
Metadata Name: mission_bound_authorization_required¶
Metadata Description: Boolean indicating that the protected resource accepts only Mission-bound tokens.¶
Change Controller: IETF¶
Specification Document(s): this document, Section 14¶
This document creates no Common Constraints registry. The Common
Constraints it defines (max_amount, resource_issued_after,
resource_issued_before, tenant, recipient_domain) are specified in
Section 5.2, and a further
Common Constraint is defined by specification: it fixes a name matching
^[A-Za-z0-9_.:-]+$, its JSON [RFC8259] value syntax, its subset
rule, and its intersection rule, in value-space terms
(Section 5.2). Names are kept collision-free by the same
convention the rest of this document uses: a specification-defined name
is coordinated within this document family, and any other name is
collision-resistant or remains deployment-defined
(Section 5.2).¶
Should the set of interoperable Common Constraints grow beyond what specification coordination bears, a future revision can create a "Mission Common Constraints" registry with a Specification Required [RFC8126] policy, seeded with the entries then defined; this document does not create it.¶
This appendix walks one Mission from an agent through Mission creation, token issuance, and Resource Server enforcement in a single trust domain. It is illustrative and adds no normative requirements. The OAuth pieces use the rules in this document; the identity setup is by reference to [I-D.draft-klrc-aiagent-auth]. Identifiers and hash values are illustrative and are not computed from the displayed JSON.¶
This walkthrough is the baseline issuance path: stateless enforcement bounded only by token lifetime. No stage calls back to the AS for Mission state; each party enforces from the credential it holds. Stage 3 notes where the OPTIONAL runtime layer adds a point-of-use check.¶
Scenario: agent s6BhdRkqt3, acting for alice
(user_3p2q8mN1a0kV7tR), reconciles Q3 invoices in the home ERP
under Mission msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-.¶
The agent is an OAuth client with a workload identity (for example a
WIMSE or SPIFFE identity), and alice has delegated to it through an
ordinary authorization-code flow, per
[I-D.draft-klrc-aiagent-auth]: client_id is the agent and the
token sub is alice. This document adds the Mission layer on top of
that identity; Stage 0 is otherwise unchanged from that specification.¶
The agent submits this Mission Intent through PAR (Section 4):¶
{
"goal": "Reconcile Q3 invoices and post adjustments under $500.",
"resources": ["https://erp.example.com"],
"constraints": [
"Read only invoices issued in 2026-Q3.",
"Post journal entries under $500."
],
"success_criteria": [
"All Q3 invoices reconciled.",
"Each posted adjustment references a source invoice."
],
"purpose": "urn:example:purpose:reconcile",
"expires_at": "2026-12-31T23:59:59Z",
"controls": {
"acr": "urn:example:acr:mfa",
"max_derivations": 200
}
}
¶
The AS (as.example.com) validates it, derives this Authority Set,
and renders it for alice's consent:¶
[
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
]
¶
After approval, the AS records Mission
msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9- in the active state with
authority_hash
sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ and
intent_hash
sha-256:wQ7p4LHnX9Md0LqJ6sZJ8b8mZ3rN2xT5pV4lE6sQqYY.¶
The agent redeems the authorization code at the token endpoint. The
AS resolves the Mission from the grant (Section 6.1), gates on
it being active (Section 9), and issues a Mission-bound access
token for the ERP, echoing the granted authorization_details in the
token response (Section 8). The decoded token:¶
{
"iss": "https://as.example.com",
"sub": "user_3p2q8mN1a0kV7tR",
"aud": "https://erp.example.com",
"client_id": "s6BhdRkqt3",
"iat": 1797840000,
"exp": 1797840300,
"jti": "at_9Kp2vN7sR1tY8mZ3qX5b",
"authorization_details": [
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"],
"constraints": {
"resource_issued_after": "2026-07-01T00:00:00Z",
"resource_issued_before": "2026-09-30T23:59:59Z"
},
"delegation": {
"max_depth": 2,
"allowed_delegates": [{ "sub_profile": "ai_agent" }]
} },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
],
"cnf": { "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" },
"mission": {
"id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"issuer": "https://as.example.com",
"authority_hash":
"sha-256:l3KvZ4mP5x0wQrR6tY2nD9bM7sX1cF8gH2vJ4kE5pNQ"
}
}
¶
Everything enforcement needs is in the token: the audience, the
sender-constraint (cnf), the authority with its constraints, and the
mission claim carrying the authority_hash consent anchor. The
token is short-lived (300 s) and its exp is far below
expires_at; revoking the Mission stops further derivation, and
this token dies at its own expiry (Section 9.2).¶
The agent calls the ERP Resource Server (erp.example.com) with that
token. The Resource Server validates the JWT and the cnf binding and
enforces the authorization_details whose resource it serves,
permitting invoices.read within the Q3 issuance window and
journal-entries.write up to the max_amount ceiling of 500.00 USD
(Section 8.2). It treats the mission claim as audit and
correlation context and makes no call to the AS.¶
This is stateless enforcement from the token alone.
journal-entries.write is a consequential write, so where the
deployment runs the runtime profile
([I-D.draft-mcguinness-mission-runtime]) it also obtains a
point-of-use PDP permit against current Mission state before
executing. The baseline bounds the write only by token lifetime and
the carried constraints.¶
The cross-domain continuation of this same Mission, projected to a partner ERP in another trust domain and enforced there, is walked through in the companion's end-to-end example ([I-D.draft-mcguinness-oauth-mission-cross-domain]).¶
These non-normative vectors let an implementation verify its anchor
computation (Section 6.3, Section 6.4) byte for byte.
Both use the issuer https://as.example.com. Each canonical-bytes block
is the exact JCS [RFC8785] output: a single line, UTF-8, with no
whitespace outside string values.
It is shown here wrapped only for layout; remove the layout line breaks,
adding no characters, to recover the canonical form. Note that JCS sorts
object member names (so iss precedes typ precedes value, within
an entry actions precedes constraints precedes resource precedes
type, and within max_amount amount precedes currency) and
preserves array order.¶
intent_hash, over this Mission Intent as the envelope value with
typ mission-intent:¶
{
"goal": "Reconcile Q3 invoices",
"resources": ["https://erp.example.com"],
"expires_at": "2026-12-31T23:59:59Z"
}
¶
Canonical bytes of the envelope:¶
{"iss":"https://as.example.com","typ":"mission-intent","value":{"e
xpires_at":"2026-12-31T23:59:59Z","goal":"Reconcile Q3 invoices","
resources":["https://erp.example.com"]}}
¶
intent_hash = sha-256:6mIFoCz79uCHNzKLfBpBwqFjoFXdpmpuc65486IqimQ¶
authority_hash, over this Authority Set as the envelope value with
typ mission-authority-set:¶
[
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["invoices.read"] },
{ "type": "mission_resource_access",
"resource": "https://erp.example.com",
"actions": ["journal-entries.write"],
"constraints": {
"max_amount": { "amount": "500.00", "currency": "USD" }
} }
]
¶
Canonical bytes of the envelope:¶
{"iss":"https://as.example.com","typ":"mission-authority-set","val
ue":[{"actions":["invoices.read"],"resource":"https://erp.example.
com","type":"mission_resource_access"},{"actions":["journal-entrie
s.write"],"constraints":{"max_amount":{"amount":"500.00","currency
":"USD"}},"resource":"https://erp.example.com","type":"mission_res
ource_access"}]}
¶
authority_hash = sha-256:vUCCfjGulit9u0qJ0Z6pQSNerZtXMqRlfJNCr4PzLro¶
An implementation that canonicalizes the same value under the same
typ and iss, computes SHA-256, and encodes as sha-256: followed by
base64url with no padding (Section 6.3) reproduces these
anchors exactly. A divergence indicates a JCS or encoding difference to
resolve before interoperating.¶
This work builds on the OAuth 2.0 Rich Authorization Requests, Pushed Authorization Requests, and JWT access token specifications, and is intended to complement agent-identity work including [I-D.draft-klrc-aiagent-auth].¶