| Internet-Draft | OAuth Mission Management | August 2026 |
| McGuinness | Expires 22 February 2027 | [Page] |
The Mission Status and Lifecycle profile observes and changes one Mission at a time and defers fleet-scale management. This document defines that deferred surface: a Mission Management endpoint through which an authorized Management Client enumerates the Missions a Mission Issuer holds, filtered by Subject, client, state, creation time, expiry, or parent, and applies bulk lifecycle operations to the enumerated set through a dry-run-then-execute exchange whose bulk token pins the evaluated membership. The surface is management-plane and operator-facing: authorized for the existence knowledge the status profile's anti-oracle rules deny to ordinary consumers, audited on every call, and never exposed to the agents whose Missions it manages. Fleet enumeration and bulk lifecycle are the OAuth lane's fleet-management surface of the family's delegated-authority layer: how an estate administers delegated authority at scale. It is optional; a deployment that does not adopt it is unaffected.¶
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-management.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-mcguinness-oauth-mission-management/.¶
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 22 February 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.¶
This document is a satellite of the Mission Status and Lifecycle profile [I-D.draft-mcguinness-oauth-mission-status] (the "status profile"), the lifecycle suite's root document, adding the suite's operator plane. The status profile answers "what is the state of this Mission" and changes that state, one Mission per request. Its Deferred Lifecycle Capabilities section defers two fleet-scale capabilities: Mission enumeration ("which Missions exist for this Subject, client, or state") and bulk lifecycle operations over the enumerated set. This document specifies both.¶
The two surfaces are deliberate counterparts. The status profile is consumption-plane: its callers are authorized for individual Missions, so it makes an unknown reference indistinguishable from an unauthorized one. This document is management-plane: its callers are operator consoles and incident-response tooling in the Mission Issuer's own trust domain, explicitly authorized for existence knowledge over a declared filter scope, compensated not by indistinguishability but by explicit authorization and mandatory audit of every call (Section 3.3). The surface is never agent-facing: the Agent executing a Mission has no role here (Section 3.2). Fleet enumeration and bulk lifecycle are the operator surface of the family's delegated-authority layer ([I-D.draft-mcguinness-mission-architecture]).¶
Both capabilities share one endpoint, one request shape, one
authentication and authorization model, one signing discipline, and
one audit rule; a request's operation member selects between them.
Bulk operations apply the status profile's per-Mission lifecycle
semantics unchanged, so this document adds no state, no transition,
and no event type to the lifecycle state space. It is optional and
does not restate the issuance profile
[I-D.draft-mcguinness-oauth-mission] or the status profile; a
deployment that does not adopt it is unaffected.¶
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.¶
This document uses the terms defined in the issuance profile
[I-D.draft-mcguinness-oauth-mission] and the status profile
[I-D.draft-mcguinness-oauth-mission-status], in particular Mission,
Mission Issuer (the Mission issuer: in this document's OAuth binding
the Authorization Server; a standalone Mission Issuer, the Mission
Authority Server [I-D.draft-mcguinness-mission-authority-server],
serves this surface with the same semantics), mission_id, the
Mission record, and the Mission lifecycle states and operations. It
additionally uses:¶
An authenticated client authorized for the Mission Management endpoint: an operator console, incident-response tooling, or administrative automation acting in the Mission Issuer's trust domain. An Agent executing a Mission is never a Management Client.¶
All JSON shown in this document is non-normative and illustrative; the member definitions in the surrounding text are authoritative. HTTP message examples follow the conventions of [RFC9110]; long values are wrapped for display. JWT examples are shown as decoded JSON; on the wire the JWS Compact Serialization [RFC7515] applies.¶
The Mission Issuer publishes its Mission Management endpoint URL in
Authorization Server metadata (Section 11) as
mission_management_endpoint. The endpoint MUST be served over TLS
1.2 or later (TLS 1.3 RECOMMENDED), following the recommendations of
[RFC9325].¶
A request is an HTTPS POST whose body is a JSON object [RFC8259]
sent as application/json; the structured filter does not fit the
form encoding of the status profile's single-Mission operations. Every
request carries:¶
operation:REQUIRED. A string. enumerate (Section 6) or one of the
status profile's lifecycle operations revoke, suspend,
resume, complete, applied in bulk (Section 7).¶
filter:REQUIRED. An object (Section 5) selecting the Missions the operation addresses.¶
nonce:REQUIRED. A string. A client-generated nonce, unique per request within the response lifetime, echoed in the signed response. It is also the idempotency key (Section 3.1).¶
A success response is a JWS Compact Serialization [RFC7515] signed
with a key published in the Mission Issuer's jwks_uri, following the
status profile's signing discipline: the JWS header carries a kid
and a typ of mission-management-response+jwt, the algorithm is one
advertised in mission_status_signing_alg_values_supported
(Section 11), and the status profile's signing-key retention
rules apply.¶
Per [RFC7515] Section 4.1.9 the typ header omits the
application/ prefix. The full media type
application/mission-management-response+jwt (registered in Section 15)
is used as the HTTP Content-Type, with Cache-Control: no-store.
Exact validation of the protected typ value, together with
mutually exclusive validation rules for the artifact profiles,
implements the substitution defense of [RFC8725], Sections 3.11
and 3.12.¶
The signed payload carries the members of Section 6.1, Section 7.1, or Section 7.3, plus the envelope members:¶
Before honoring a response a Management Client MUST apply the status
profile's response verification checks: signature, iss, aud,
sub, nonce, and iat/exp with up to 30 seconds skew. The
Management Client MUST also verify the typ.¶
Rate limits, the enumeration page maximum, and the bulk size bound are deployment-declared operational configuration; this document defines the error symbols that surface them (Section 8) but no metadata for them.¶
The nonce is the idempotency key. The AS MUST deduplicate
management requests by (client, nonce) for a bounded window, at
least the validity span of the signed response it would replay, as
the status profile's lifecycle endpoint requires
([I-D.draft-mcguinness-oauth-mission-status]). On a retransmit, the
AS MUST replay the original response rather than re-execute the
request.¶
The request MUST be authenticated using the status profile's mechanism set ([I-D.draft-mcguinness-oauth-mission-status], Section "Authentication"), discovered through the AS's existing client-authentication metadata [RFC8414]:¶
Plain Basic or POST client authentication MUST NOT be used. A deployment MUST NOT accept at the Management endpoint an authentication mechanism weaker than those it accepts at its Mission Lifecycle endpoint.¶
When a sender-constrained access token authenticates the call, it
MUST carry a management authorization: a mission_management scope
or an equivalent deployment-defined grant, distinct from the status
profile's lifecycle grant.¶
The surface is management-plane only. A Mission Issuer MUST NOT authorize an Agent (the OAuth client that submitted or executes a Mission) as a Management Client. A Mission Issuer MUST NOT accept a Mission-bound access token as authentication here.¶
A deployment authorizes each Management Client for a filter scope:
the Missions it may enumerate and operate on, expressed over the
filter members of Section 5. A subject-scoped operator, a
client-scoped operator, and a tenant-wide incident responder are
distinct grants; the grant syntax is deployment-defined. The AS MUST
evaluate a request's filter against the caller's filter scope before
evaluating it against the Mission store, and MUST refuse with
forbidden (Section 8) a request whose filter could match
a Mission outside that scope.¶
This surface intentionally inverts the status profile's anti-oracle
property: that property exists because status callers are not
authorized for existence knowledge, while a Management Client is,
over exactly its filter scope, so unknown and unauthorized references
need not be indistinguishable here and forbidden is returned
openly. The compensating control is audit: the AS MUST record every
management request, including refused ones, in its audit log with¶
the caller,¶
the operation,¶
the full filter,¶
the purpose or reason,¶
the result count or outcome manifest, and¶
the disposition.¶
A refusal is computed from the caller's grant and the request alone, never from Mission data, so it discloses nothing about which Missions exist.¶
The Mission record identifies the parties and the authority; operating an estate needs administrative context the record deliberately does not carry: who owns the Mission organizationally and which tenant it belongs to. A Mission Issuer MAY maintain an administrative metadata object per Mission, management-plane state associated with the record:¶
owner:The accountable operator of the Mission's agent: an (iss, sub)
principal or a group URI. Distinct from subject, whom the task is
for, and approver, who approved it.¶
tenant:A string naming the owning tenant. Distinct from any tenant constraint inside the Authority Set, which bounds resource authority rather than naming ownership.¶
A deployment MAY keep any further administrative taxonomy (domains, sensitivity classes, grouping labels, retention pointers) as private state; this document names only the two members it gives semantics.¶
Administrative metadata is control-plane state: it MUST NOT be carried on access tokens or in audience-scoped authority projections, and it grants no authority. It drives the management plane: approval routing, filter scope (Section 3.3), enumeration, and incident response.¶
How the object is populated, at issuance from deployment policy or by
an authorized management operation, is deployment-defined; a
dedicated metadata update operation is deferred until deployment
experience shows the shape. owner and tenant are fixed when the
administrative metadata is created: they define filter scope, so
changing either redraws who may see and operate on the Mission. So
does changing whether the object exists: a metadata-matching filter
member matches no Mission that has none (Section 5), so creating the
object after issuance, deleting it, or deleting and recreating it
redraws scope as surely as changing a value. Every post-issuance
transition of the administrative metadata (a value change, absent to
present, or present to absent) is therefore a re-home. A
deployment that supports re-homing MUST gate it on an explicit
authority distinct from its enumeration and lifecycle grants, MUST
require the caller's filter scope to cover the Mission both before
and after the change (a Mission without administrative metadata is
covered through the filter members that do not match against it),
MUST NOT accept an authorization derived from the values the change
itself would establish, MUST apply the change as an atomic
compare-and-set against the current values, absent being a value the
comparison and the record both name, and MUST record the audited
management event with both the prior and the new values
(Section 3.3). A re-home does not travel alone: an outstanding
bulk token that pins the Mission fails its scope-currency check at
its next presentation (Section 13.3).¶
The filter object selects Missions by conjunction: a Mission matches
when it satisfies every member present. An empty filter matches every
Mission in the caller's filter scope. The members, each OPTIONAL,
match against the Mission record
([I-D.draft-mcguinness-oauth-mission], Section "Mission Record"):¶
subject:An object with iss and sub. Matches the record's subject
exactly.¶
client_id:A string. Matches the record's client_id.¶
state:An array of strings. Matches a Mission whose current lifecycle state equals any listed value, drawn from the issuance profile's open state space as extended by the profiles the deployment runs. The AS MUST NOT refuse a filter for carrying a state value it does not produce; such a value matches no Mission.¶
created_after, created_before:RFC 3339 [RFC3339] date-times. Match a Mission whose created_at
is strictly after, respectively strictly before, the value.¶
expiring_before:An RFC 3339 [RFC3339] date-time. Matches a Mission whose
expires_at is strictly before the value.¶
parent:A string, a Mission Identifier. Matches the Child Missions whose parent
lineage member names it
([I-D.draft-mcguinness-oauth-mission-child-delegation]): direct
children only. A caller walks a delegation tree level by level.¶
owner:An object with iss and sub, or a string group URI. Matches the
administrative metadata's owner (Section 4).¶
tenant:A string. Matches the administrative metadata's tenant
(Section 4).¶
A filter member that matches against administrative metadata matches no Mission where the deployment maintains none.¶
The AS MUST refuse a filter carrying an unrecognized member with
invalid_request, so a filter is never silently broader than the
caller intended.¶
On a standalone Mission Authority Server, the filter members that
match subject and client_id are evaluated under the MAS mapping
contract for those identities
([I-D.draft-mcguinness-mission-authority-server]).¶
The enumerate operation answers "which Missions exist" for the
caller's filter, returning signed pages of Mission summaries. In
addition to the common members (Section 3), the request
carries:¶
purpose:REQUIRED. A string, maximum 1024 characters. The operator's reason for the query (for example a ticket or case identifier), recorded in audit (Section 3.3).¶
cursor:OPTIONAL. A string. An opaque pagination cursor from a prior response.¶
limit:OPTIONAL. A positive integer. The AS returns at most the smaller of
limit and its deployment-declared page maximum, and applies the
maximum when limit is absent.¶
bulk_token:OPTIONAL. A string. A bulk token from a prior dry run (Section 7.1).
When present, enumerate returns exactly the membership that token
pins (the pinned set) as summaries, so the reviewed set equals the
executed set (Section 7.1). filter MUST equal the filter the
token binds; the AS MUST refuse a mismatch with invalid_bulk_token
(Section 8). Before disclosing any summary, the AS MUST
verify that every pinned member is still within the caller's
current filter scope (Section 3.3), refusing the whole token
with stale_bulk_token and naming no member otherwise
(Section 13.3). Presenting a bulk token to enumerate is
read-only and does not consume it.¶
The signed payload (Section 3) carries:¶
missions:REQUIRED. An array of Mission summary objects, each carrying
id, state, version (the Mission's state version,
[I-D.draft-mcguinness-oauth-mission-status]), subject (an
object with iss and sub),
client_id, created_at, and expires_at from the Mission
record, plus the lineage members successor, predecessor
([I-D.draft-mcguinness-oauth-mission-expansion]), and parent
([I-D.draft-mcguinness-oauth-mission-child-delegation]) where
present on the record. A summary MUST NOT carry the Mission Intent,
the Authority Set, or any member beyond these: enumeration answers
which Missions exist and stand in what state; a caller needing full
detail resolves each Mission through Mission Status, which is
separately authorized.¶
cursor:CONDITIONAL. A string. Present exactly when more results remain; the caller re-sends the same request with this cursor to continue.¶
A cursor is opaque and bound to the (caller, filter) that produced
it; the AS MUST refuse with invalid_request a cursor presented by a
different caller or with a different filter. Result order MUST be
stable within a cursor walk. The AS SHOULD present a consistent
membership across a walk but MAY reflect transitions committed while
it is in progress; a caller that needs a pinned membership uses the
bulk dry run (Section 7.1), whose bulk token provides exactly that and
is reviewable by presenting the token to enumerate.¶
An incident responder (client_secops-console) triages a credential
compromise for Subject user_3p2q8mN1a0kV7tR and enumerates that
Subject's active Missions:¶
Decoded signed response payload:¶
{
"iss": "https://as.example.com",
"aud": "client_secops-console",
"sub": "client_secops-console",
"nonce": "nonce_M4kR8vT2nQ7xB5sW",
"iat": 1793611740,
"exp": 1793611800,
"missions": [
{ "id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"state": "active",
"subject": { "iss": "https://idp.example.com",
"sub": "user_3p2q8mN1a0kV7tR" },
"client_id": "s6BhdRkqt3",
"created_at": "2026-10-15T14:32:11Z",
"expires_at": "2026-12-31T23:59:59Z" }
]
}
¶
No cursor is present: the result is complete. The AS records the
caller, filter, purpose, and result count in its audit log.¶
A bulk request applies one lifecycle operation of the status profile
(revoke, suspend, resume, complete) to every Mission a filter
matches, in two steps: a REQUIRED dry run returning the match count
and a bulk token pinning the evaluated membership, then an execute
presenting that token. In addition to the common members
(Section 3), the request carries:¶
mode:REQUIRED. A string, dry_run or execute.¶
bulk_token:CONDITIONAL. A string. REQUIRED when mode is execute; MUST NOT
be sent otherwise.¶
reason:REQUIRED. A string, maximum 1024 characters. Recorded in audit
(Section 3.3) and applied as each per-Mission transition's
reason under the status profile, so it surfaces in per-Mission
audit and, where signals run, in each emitted event
([I-D.draft-mcguinness-oauth-mission-signals]).¶
suspend_until, on_expiry:OPTIONAL and CONDITIONAL respectively, valid only when operation
is suspend, with the status profile's semantics, applied
uniformly to every Mission in the set.¶
The AS MAY declare a bound on the evaluated set size and refuse a dry
run whose match count exceeds it with filter_too_broad
(Section 8); the caller narrows the filter (for example
with created_after) and retries.¶
On mode dry_run the AS evaluates the filter within the caller's
filter scope (Section 3.3), records the matched membership, and
returns a signed response carrying:¶
operation:REQUIRED. The requested operation, echoed.¶
match_count:REQUIRED. An integer. The size of the evaluated membership.¶
bulk_token:REQUIRED. A string. An opaque, single-use token binding the caller,
the operation, the filter (with suspend_until and on_expiry
when present), and the evaluated membership itself: the exact set
of mission_id values matched at dry-run time
(Section 13.3).¶
bulk_token_expires_at:REQUIRED. An RFC 3339 [RFC3339] date-time. The bulk token's expiry. Its lifetime is deployment-defined and SHOULD NOT exceed 15 minutes: long enough to review, short enough that the reviewed set cannot silently age.¶
A dry run commits no transition. To review the membership behind the
count, the caller runs enumerate presenting the bulk_token
(Section 6), which returns exactly the pinned set, so the
reviewed membership equals the set the matching execute will operate
on. Running enumerate with only the same filter re-evaluates it and
MAY return a drifted set; the bulk_token pins the review to the
evaluated membership.¶
On mode execute the AS MUST verify that the presented
bulk_token:¶
is unexpired,¶
is unused,¶
was issued to this caller,¶
binds an operation, filter, and (for a suspend)
suspend_until and on_expiry all equal to the request's, and¶
pins a membership every member of which is still within the caller's current filter scope (Section 3.3).¶
An execute whose operation, filter, or on_expiry differs from
what the token pins MUST be refused with invalid_bulk_token,
executing nothing. An execute any of whose pinned members has left
the caller's filter scope (administrative metadata changed under the
reviewed set, Section 4) MUST be refused with
stale_bulk_token, executing nothing and naming no member; the
caller re-runs the dry run under current scope
(Section 13.3). Either check completes before any
transition commits. The token is then consumed: it is single-use
whatever the outcome.¶
The AS applies the operation to each member of the bound membership
individually, under the status profile's lifecycle semantics
unchanged: legality per its Legal Transitions, idempotency,
per-transition evidence and audit, and, where signals run, one
mission.lifecycle-change SET per committed transition
([I-D.draft-mcguinness-oauth-mission-signals]). There is no bulk
event type and no transactionality: transitions commit independently,
and a failure on one member MUST NOT roll back another.¶
The membership is the one the dry run evaluated. A Mission created, or
newly matching the filter, after the dry run is not in the membership
and MUST NOT be operated on; a member that transitioned in the interim
yields an already_terminal or illegal_transition outcome rather
than a surprise transition (Section 13.3).¶
The dry-run-then-execute exchange with its pinned membership is the
bulk-path analog of the status profile's expected_version guard
([I-D.draft-mcguinness-oauth-mission-status]), and a deployment
that requires expected_version for an operation it classifies
high-risk satisfies that requirement on the bulk path through the
pinned membership plus the per-member outcomes (Section 7.3).¶
The execute response is a signed manifest carrying operation (the
executed operation, echoed) and:¶
results:REQUIRED. An array of objects, one per member of the executed
membership, each carrying mission_id, outcome, and, on error
only, an OPTIONAL detail string.¶
The outcomes:¶
| Outcome | Meaning |
|---|---|
applied
|
The operation succeeded: the transition was committed, or the Mission already stood in the operation's resulting non-terminal state (the status profile's idempotent case). |
already_terminal
|
The Mission already stood in a terminal state; when that state is the operation's own resulting state, this is the status profile's idempotent case, reported distinctly for operator clarity. |
illegal_transition
|
The operation is not legal from the Mission's current non-terminal state; the Mission is unchanged. |
error
|
The AS failed to process this Mission; its state is unverified. |
A Mission in any terminal state reports already_terminal, taking
precedence over the idempotent reading of applied; it is reported
distinctly from error because, for a terminating operation, an
already-terminal member is a satisfied objective, not a failure. After
a partial failure the spent bulk token is not reusable; the caller
remediates with a fresh dry run over the same filter and a new
execute: members already transitioned then report already_terminal,
and only error members are retried.¶
Continuing Section 6.2, the responder revokes every
Mission for the compromised Subject in any state, so the filter omits
state. Dry-run request body (transport and authentication as in
Section 6.2):¶
{
"operation": "revoke",
"filter": {
"subject": { "iss": "https://idp.example.com",
"sub": "user_3p2q8mN1a0kV7tR" }
},
"mode": "dry_run",
"reason": "IR-4192: subject credential compromise",
"nonce": "nonce_P9sB3xV7mK1tR6qZ"
}
¶
Decoded dry-run response payload:¶
{
"iss": "https://as.example.com",
"aud": "client_secops-console",
"sub": "client_secops-console",
"nonce": "nonce_P9sB3xV7mK1tR6qZ",
"iat": 1793611800,
"exp": 1793611860,
"operation": "revoke",
"match_count": 3,
"bulk_token": "blk_7Nq4xW2rT9mK5vB8sD1zA6pY3cE0hJfL",
"bulk_token_expires_at": "2026-11-02T09:45:00Z"
}
¶
The count is 3, more than the enumeration above: without state the
filter also matches a suspended and a completed Mission (revoke is
legal from suspended, so suspended Missions belong in the sweep).
The responder executes,
re-sending the same operation and filter with mode of execute,
the bulk_token, the same reason, and a fresh nonce
(nonce_W2tN6bQ9kX4mV8rS). Decoded manifest payload, with a partial
failure:¶
{
"iss": "https://as.example.com",
"aud": "client_secops-console",
"sub": "client_secops-console",
"nonce": "nonce_W2tN6bQ9kX4mV8rS",
"iat": 1793611980,
"exp": 1793612040,
"operation": "revoke",
"results": [
{ "mission_id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
"outcome": "applied" },
{ "mission_id": "msn_6VbT1yHn4RwQk9x3zE8sC5j2MpDfL0G-",
"outcome": "already_terminal" },
{ "mission_id": "msn_0JpW3xEr8KtNb5v2qC7mD4h1YsAgF9L-",
"outcome": "error",
"detail": "state store timeout" }
]
}
¶
One Mission was revoked, emitting its own lifecycle signal where
signals run; the completed Mission needed nothing; one failed. The
responder re-runs the dry run over the same filter, reviews the new
count, and executes again: the revoked and completed members report
already_terminal and only the failed one is retried.¶
A wire error returns the matching HTTP status with a JSON object
[RFC8259] body carrying error, error_description, and nonce,
as in the status profile. Per-Mission conditions during a bulk execute
are manifest outcomes (Section 7.3), never wire errors. The codes:¶
| error | HTTP | Description |
|---|---|---|
invalid_request
|
400 | Malformed request: unknown operation, unrecognized filter member, invalid member combination, or a cursor that does not match its caller and filter. |
invalid_bulk_token
|
400 | The bulk token is missing, expired, already used, issued to another caller, or bound to a different operation, filter, suspend_until, or on_expiry. |
stale_bulk_token
|
409 | Administrative metadata changed under the pinned membership: at least one pinned Mission is no longer within the caller's filter scope. Re-run the dry run (Section 13.3). |
filter_too_broad
|
400 | The filter matches more Missions than the deployment's declared bound for the requested operation. |
unauthorized
|
401 | Request not authenticated. |
forbidden
|
403 | Caller authenticated but not authorized for the requested operation or filter scope (Section 3.3). |
rate_limited
|
429 | Caller is rate-limited. |
unavailable
|
503 | The AS temporarily cannot serve management requests. |
For rate_limited, the response SHOULD include a Retry-After header
[RFC9110] and a retry_after body member in seconds.¶
This section is non-normative. Common incident shapes compose the two operations directly:¶
Compromised Subject. Filter subject, enumerate to triage, then
bulk revoke (the worked examples above).¶
Decommissioned client. Filter client_id, bulk revoke; every
Mission the retired Agent submitted stops deriving.¶
Key or approval-surface compromise. Filter created_after and
created_before around the compromise window, bulk revoke; every
Mission approved while the surface was suspect is terminated,
regardless of Subject or client.¶
Suspend-first triage. Bulk suspend with suspend_until and
on_expiry of revoke, investigate, then selectively resume
individual Missions through the status profile's lifecycle endpoint;
anything not affirmatively cleared revokes itself at the deadline.¶
What bulk revocation does and does not stop is the security model's revocation-to-action latency table ([I-D.draft-mcguinness-mission-security-model]): each revocation stops new derivation at commit, while tokens already derived persist until the tightest propagation layer the deployment runs cuts them off. Bulk management changes how many Missions one request can stop, not how fast any one revocation propagates.¶
Approver transfer, re-anchoring a Mission's consent to a different
accountable party, is not defined here. Administrative monotonic
narrowing, such as shortening a Mission's expires_at or retiring
a single Authority Set entry, is not defined here. Cross-issuer
enumeration, one query spanning Missions held by multiple Mission
Issuers, is not defined here; a Management Client queries each
issuer it is authorized for separately.¶
An AS that serves the Mission Management endpoint advertises it in its Authorization Server metadata [RFC8414]:¶
mission_management_endpoint:OPTIONAL. A string containing a URL. The URL of the Mission Management endpoint (Section 3). Present when the AS serves it.¶
Because management responses reuse the status profile's signing
discipline, an AS that publishes mission_management_endpoint MUST
also publish mission_status_signing_alg_values_supported
([I-D.draft-mcguinness-oauth-mission-status]).¶
A standalone Mission Issuer (a Mission Authority Server [I-D.draft-mcguinness-mission-authority-server]) MAY serve this surface and, when it does, carries the same member with the same semantics in its discovery document; Section 15 registers the member in the Mission Authority Server Metadata registry.¶
This document is OPTIONAL. An implementation that claims it conforms in one of two roles.¶
A Management-capable Mission Issuer:¶
serves the Mission Management endpoint over the authentication and authorization of Section 3.2 and Section 3.3 with signed responses per Section 3;¶
serves enumerate (Section 6) and the bulk lifecycle
operations (Section 7) with dry-run-then-execute and the
bulk token bindings of Section 7.1;¶
applies bulk transitions per Mission under the status profile's lifecycle semantics, emitting per-Mission evidence and signals (Section 7.2);¶
audit-logs every management request per Section 3.3; and¶
advertises mission_management_endpoint (Section 11).¶
A Management Client:¶
authenticates per Section 3.2;¶
sends the REQUIRED purpose or reason on every request,
identifying the operator task rather than a fixed placeholder;¶
obtains a fresh dry run for every execute, surfacing the
match_count to the deciding operator or decision point before
executing; and¶
executes only bulk tokens from dry runs it itself requested.¶
An implementation that supports neither role is unaffected and remains a conforming issuance or status profile implementation.¶
The security considerations of the issuance profile [I-D.draft-mcguinness-oauth-mission] and the status profile [I-D.draft-mcguinness-oauth-mission-status] apply. This section covers what is specific to fleet-scale management.¶
This endpoint is the highest-blast-radius surface in this suite: one authorized request can terminate or suspend every Mission in a filter scope, and one enumeration can disclose a tenant's entire Mission population. Accordingly, the authentication floor of Section 3.2 is at least the lifecycle endpoint's with a distinct management grant, every call including every refusal is audited (Section 3.3), and destructive operations are structurally two-step, since an execute cannot exist without the dry run that pinned its membership.¶
A compromised Management Client is equivalent to an operator compromise of the Mission Issuer's management plane: within its filter scope it can enumerate at will and stop or suspend all governed work. It is a trusted-base component in the sense of the security model ([I-D.draft-mcguinness-mission-security-model]); its compromise is not prevented here, only bounded by the filter scope and recorded by the mandatory audit trail. Its abuse ceiling is disclosure and work stoppage, not authority escalation: the surface cannot create or widen a Mission, and the model's availability trade applies, since a management credential converts into stopped governed work rather than loosened enforcement.¶
One qualification: bulk resume re-activates Missions suspended for
cause, undoing an in-flight containment. A deployment MUST require a
distinct or elevated grant for resume at this endpoint. A
deployment SHOULD alert on bulk resume.¶
Deployments SHOULD:¶
scope Management Clients narrowly,¶
protect their credentials as operator credentials, and¶
alert on anomalous management activity.¶
Where audit transparency runs, management audit records are candidates for it ([I-D.draft-mcguinness-mission-audit]).¶
The purpose and reason strings that flow into those records, and
into per-Mission evidence and signals, are caller-written free text;
audit systems MUST treat them as untrusted input.¶
The status profile makes Mission existence unobservable to the unauthorized; this document makes it queryable by the authorized. The two compose safely only if the boundary between them holds. A deployment MUST NOT satisfy a management request with a credential authorized only for status or lifecycle calls. The filter-scope check of Section 3.3 MUST run before any Mission data is touched, so a refusal is data-independent. The audit rule of Section 3.3 is the compensating control for the disclosure this surface exists to provide.¶
The bulk token closes the review-to-execution gap, and each of its bindings (Section 7.1) is load-bearing. The membership binding prevents time-of-review to time-of-execution growth: without it, a filter re-evaluated at execute time could match Missions created after the operator reviewed the dry-run count, so a reviewed "revoke these 3" could silently become "revoke these 30". Single use prevents a captured or logged token from re-running the sweep; the short lifetime bounds how stale the reviewed set can be; and the caller binding keeps the reviewed set and the executing principal the same.¶
The scope-currency check (Section 7.2) is the fifth binding, and it guards the reverse drift: the membership binding freezes the set, but a re-home (Section 4) can move a pinned Mission out of the caller's filter scope after review, and a token checked only against its own bindings would let its holder keep enumerating the moved Mission and revoke, suspend, resume, or complete it from outside the scope that now governs it. The re-homing actor's own pre- and post-scope gate cannot see other callers' outstanding tokens; the check at presentation is what closes them. The refusal is computed before any disclosure or transition and names no member. How the AS detects staleness is its choice: binding each member's administrative-metadata generation into the token and refusing on any change, or eagerly invalidating every outstanding token that pins a re-homed Mission, both conform.¶
An AS MUST enforce all five; a bulk token that survives reuse, transfer, filter substitution, or a re-home reduces the two-step exchange to a one-step sweep.¶
This document inherits OAuth 2.0 Best Current Practice [RFC9700] for the OAuth surfaces it composes with.¶
The privacy considerations of the issuance and status profiles apply. This section covers what is specific to enumeration.¶
An enumeration response is PII-bearing by construction: each summary row ties a Subject identifier to an Agent, a lifecycle state, and activity timing, and a page of rows profiles a person's delegated activity. Minimization is structural: the summary shape of Section 6.1 excludes the Mission Intent and the Authority Set, and the filter-scope authorization of Section 3.3 bounds each Management Client to the population it demonstrably needs. A deployment SHOULD grant tenant-wide filter scopes only to incident-response roles.¶
The audit records of Section 3.3 are doubly sensitive: they carry the Subject identifiers of the Missions touched, and they record which operator investigated which person, when, and why. Deployments MUST:¶
treat them as PII sinks under the issuance profile's privacy rules,¶
retain them for at least the audit horizon of the Missions they concern ([I-D.draft-mcguinness-oauth-mission]), and¶
restrict read access to them at least as tightly as the management surface itself.¶
IANA is requested to register mission_management_endpoint in the
"OAuth Authorization Server Metadata" registry [RFC8414], and in the
"Mission Authority Server Metadata" registry established by
[I-D.draft-mcguinness-mission-authority-server], whose registration
policy is Specification Required; this document is the specification.
For both: Change Controller IETF; Reference this document,
Section 11.¶
IANA is requested to register one media type per [RFC6838], mirroring the status profile's registration.¶
Type name: application¶
Subtype name: mission-management-response+jwt¶
Required parameters: none¶
Optional parameters: none¶
Encoding considerations: binary; JWS Compact Serialization¶
Security considerations: see Section 13¶
Interoperability considerations: see this document¶
Published specification: this document¶
Applications that use this media type: OAuth Mission-Bound Management Clients¶
Fragment identifier considerations: not applicable¶
Restrictions on usage: none¶
Provisional registration: no¶
Magic number(s): none¶
File extension(s): none¶
Macintosh file type code(s): none¶
Person & email address to contact: Karl McGuinness public@karlmcguinness.com¶
Intended usage: COMMON¶
Author/Change controller: IETF¶
The author thanks the implementers and reviewers of the Mission-Bound Authorization work for the incident-response experience that shaped this surface.¶