Internet-Draft OAuth Mission Derivation Limits October 2026
McGuinness Expires 11 April 2027 [Page]
Workgroup:
Web Authorization Protocol
Internet-Draft:
draft-mcguinness-oauth-mission-derivation-limits-latest
Published:
Intended Status:
Standards Track
Expires:
Author:
K. McGuinness
Independent

Mission Derivation Limits for OAuth 2.0

Abstract

Mission-Bound Authorization for OAuth 2.0 gates each token issuance under a Mission on the Mission's lifecycle state, its approved authority, and its expiry. This document defines Mission Derivation Limits, a companion that bounds the number of derivations the Mission Issuer performs under a Mission. A client can request a ceiling in the Mission Intent. The authorization server establishes the effective limit as the minimum of that request and its own policy, records it on the Mission, renders it at approval, refuses any derivation that would exceed it, and can report the remaining count through token introspection. The limit is an issuer-side operational control, not a bound on the authority a token carries or on how that token is used.

About This Document

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-derivation-limits.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-mcguinness-oauth-mission-derivation-limits/.

Source for this draft and an issue tracker can be found at https://github.com/mcguinness/mission-bound-authorization.

Status of This Memo

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 11 April 2027.

▲

Table of Contents

1. Introduction

Mission-Bound Authorization for OAuth 2.0 [I-D.draft-mcguinness-oauth-mission] (the OAuth binding) gates every derivation under a Mission on its lifecycle state, its Authority Set, and its expiry. It does not bound how many derivations the issuer performs. This document adds that bound: a derivation limit on the number of derivations the issuer authorization server (AS) performs under a Mission. The limit is an issuer-side operational control. It bounds counted issuance operations at the token endpoint, or at the Mission Authority Server's grant endpoint under the Mission Issuance Grant profile (Section 4.5), not the authority any derived token carries or how often a token already issued is used. The refreshes of an async delegation family are not counted (Section 4.3), nor are redemption and refresh at a consuming Authorization Server under the Mission Issuance Grant profile (Section 4.5).

The limit uses these extension seams of the OAuth binding and changes none of its rules:

An AS that does not implement this document establishes no derivation limit, and its closed-top-level validation refuses a submitted requested_derivation_limit as an unknown member ([I-D.draft-mcguinness-oauth-mission], Section "Submission via PAR"). Bounding aggregate consumption (calls, spend, or activity over the life of a Mission) is out of scope; the metering profile defines it ([I-D.draft-mcguinness-mission-metering]).

2. Conventions and Terminology

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 Mission, Mission Intent, Mission Record, Mission Issuer (the "issuer AS" or the "AS"), Resource AS, Approver, approval event, Authority Set, Mission-bound token, and derivation from [I-D.draft-mcguinness-oauth-mission].

Derivation limit:

The AS-established effective ceiling on the number of derivations under one Mission, recorded as the Mission Record's derivation_limit (Section 3.3).

Derivation count:

The number of derivations the issuer AS has committed under a Mission (Section 4).

3. The Derivation Limit

A Mission's derivation limit bounds the number of derivations (Section 4) the issuer AS performs under it. The limit is AS-established operational policy; a client can request a narrower ceiling through the Mission Intent's requested_derivation_limit member (Section 3.1).

3.1. Requested Limit

This document defines one top-level Mission Intent member, under the OAuth binding's Mission Intent members extension point ([I-D.draft-mcguinness-oauth-mission], Section "Extensibility"):

requested_derivation_limit:

OPTIONAL. A positive integer (1 or greater). A client-requested ceiling on the number of derivations the issuer AS performs under the Mission. An AS MUST reject a value below 1 with invalid_request. This member is a request only: the AS-established effective ceiling and its omission semantics are defined in Section 3.2, its rendering in Section 7, and its enforcement in Section 5.

intent_hash commits the member like every Intent member ([I-D.draft-mcguinness-oauth-mission], Section "Integrity Anchors"); Appendix A gives a vector.

The following is an example of a Mission Intent carrying a requested derivation limit:

{
  "goal": "Reconcile Q3 invoices and post adjustments under $500.",
  "target_resources": ["https://erp.example.com"],
  "expires_at": "2026-12-31T23:59:59Z",
  "requested_derivation_limit": 200
}

3.2. Effective Limit

Omitting requested_derivation_limit means no client-requested ceiling; the effective limit is then set by AS policy alone, which can impose none.

The Mission Record's derivation_limit (Section 3.3) is the immutable, AS-established effective ceiling. At the approval event the AS establishes it as the minimum of the deployment's own policy ceiling for this Mission and the requested requested_derivation_limit, where one was submitted, so a client's request narrows, and never widens, the AS's own policy ceiling. Section 7 states how the approval surface renders it.

This establishment happens afresh at every approval event that creates a Mission Record: a Child Mission's ([I-D.draft-mcguinness-oauth-mission-child-delegation]), a dispatched Template instance's ([I-D.draft-mcguinness-oauth-mission-template]), and an Expansion successor's ([I-D.draft-mcguinness-oauth-mission-expansion]), exactly as at direct approval. An established derivation_limit is never inherited from a parent, a template, or a predecessor Mission, with two exceptions, each defined by the profile that creates the Mission, so that neither can replenish a derivation budget:

  • a Child Delegation carryover replacement preserves the old child's derivation_limit and derivation count ([I-D.draft-mcguinness-oauth-mission-child-delegation], Section "No State, Authority, Expiry, or Budget Reset"); and

  • a policy-adjudicated ceiling-drawdown successor carries forward its predecessor's committed derivation count, and its derivation_limit never exceeds the predecessor's: a stricter policy or requested ceiling narrows it further, and a predecessor with no derivation_limit passes on no finite limit ([I-D.draft-mcguinness-oauth-mission-progressive], Section "In-ceiling expansion").

Otherwise each Mission Record's ceiling comes only from its own Intent's requested_derivation_limit, clamped by the deployment's policy for that Mission. A successor created by a fresh human approval and each distinct Template dispatch establish theirs afresh.

3.3. Mission Record Member

This document defines one Mission Record member, under a short name coordinated with the OAuth binding's open record ([I-D.draft-mcguinness-oauth-mission], Section "Mission Record"):

derivation_limit:

REQUIRED when an effective derivation ceiling is established for this Mission, whether by requested narrowing or by policy alone (Section 3.2), absent otherwise. A positive integer: the AS-established effective ceiling on derivations under this Mission, fixed at the approval event. Section 5 defines its enforcement and Section 4 the running derivation count it is gated against.

Neither integrity anchor commits derivation_limit ([I-D.draft-mcguinness-oauth-mission], Section "Integrity Anchors"). Section 9.5 describes how an auditor checks it.

4. Counting Derivations

The running derivation count is AS-side state about the Mission, not a member of the immutable record. It counts derivations as the OAuth binding defines them ([I-D.draft-mcguinness-oauth-mission], Section "Issuance Gating"): one issuance operation the issuer AS performs for a single request, namely the initial authorization-code exchange, a refresh, a Token Exchange ([RFC8693]), or a cross-domain grant issuance ([I-D.draft-mcguinness-oauth-mission-cross-domain]). Under the Mission Issuance Grant profile the list gains one entry, the Mission Authority Server's minting of a grant (Section 4.5).

4.1. What Counts

Each derivation 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. A derivation that fails, including one refused for exceeding the bound, MUST NOT be counted.

A child-creation token exchange ([I-D.draft-mcguinness-oauth-mission-child-delegation]) is not counted against the Parent Mission's limit. The Child Mission's first issuance, its redemption of the child's initial grant, is counted against the child's own derivation_limit. The successor access token a ceiling-drawdown response returns is one derivation, counted against the successor, never the predecessor ([I-D.draft-mcguinness-oauth-mission-progressive]).

4.2. Atomicity and Concurrency

The AS MUST NOT let concurrent derivations collectively exceed the bound. A derivation is counted when it commits, so the count, and the derivations_remaining it yields (Section 6), reflect committed issuances only.

4.3. Refresh and Token Exchange

A refresh is one derivation, and a refresh that rotates both the access token and the refresh token is one. A Token Exchange under the Mission is one derivation, whether it down-scopes a token for the approved agent or issues a delegated token ([I-D.draft-mcguinness-oauth-mission], Section "Delegation Within a Mission").

The one exception is a delegation family under the Continuation profile's async delegation transport ([I-D.draft-mcguinness-oauth-mission-continuation], Section "Async Delegation Transport"): the exchange that creates the family is one derivation, and the family's successive refreshes are not counted again. That profile makes the Mission's expiry, not this limit, the family's continuity ceiling (Section 9.2).

4.4. Cross-Domain Issuance

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 Resource AS's local issuance under a projected grant is bounded by that grant's own lifetime and local policy, not counted against the origin issuer's per-Mission derivation cap.

4.5. Mission Issuance Grant Minting

Under the Mission Issuance Grant profile ([I-D.draft-mcguinness-oauth-mission-issuance-grant]), the Mission Authority Server is the Mission Issuer, and minting a grant is the derivation it performs: each committed minting counts once, and the MAS refuses minting past the limit with derivations_exhausted ([I-D.draft-mcguinness-oauth-mission-issuance-grant], Section "Grant Errors"). Neither redeeming the grant at a consuming Authorization Server nor any refresh there is a derivation the issuer performs, and neither increments the count. As at the cross-domain boundary (Section 4.4), the limit therefore bounds the grants the issuer mints, not the number of tokens consuming Authorization Servers issue from them.

5. Enforcement at Issuance

The derivation limit is an issuance gate beside those of the OAuth binding ([I-D.draft-mcguinness-oauth-mission], Section "Issuance Gating"). When the Mission's derivation_limit (Section 3.3) is established, the AS MUST refuse, with the invalid_grant error code, any derivation that would make the number of derivations under the Mission exceed it. Where the derivation is a Mission Authority Server's minting of a grant, the refusal is that profile's derivations_exhausted grant error instead (Section 4.5).

The issuer AS enforces the limit at each derivation. The bound is never absent at the issuer when established, and it does not bound another domain's local minting (Section 4.4). The rendered limit (Section 7) is therefore a bound a named party enforces, so rendering it meets the OAuth binding's rule against presenting a rendered bound as enforced when no party enforces it ([I-D.draft-mcguinness-oauth-mission], Section "Mission Approval").

invalid_grant alone does not tell a client which gate refused. On a refusal under this section the AS SHOULD include, alongside error, the mission_error token-error-response member ([I-D.draft-mcguinness-oauth-mission], Section "Issuance Gating") with the value derivations_exhausted. The OAuth binding's rules for that member apply: it is diagnostic only, it grants nothing, an unrecognized value is ignored, and it is returned only to the authenticated client presenting the Mission's grant. The refusal maps as the OAuth binding's other token-endpoint lifecycle refusals do ([I-D.draft-mcguinness-oauth-mission], Section "Error and Challenge Mapping"): invalid_grant (Section 5.2 of [RFC6749]), with mission_error as the optional detail.

The following is an example of a token error response refusing a derivation under an exhausted limit:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store

{
  "error": "invalid_grant",
  "mission_error": "derivations_exhausted"
}

6. Remaining Derivations in Token Introspection

Where the AS supports token introspection [RFC7662] for Mission-bound tokens ([I-D.draft-mcguinness-oauth-mission], Section "Mission State via Token Introspection"), the mission member of the introspection response can carry one member this document defines:

derivations_remaining lets an issuance-budget consumer plan refreshes against the cap. It is not an enforcement input ([I-D.draft-mcguinness-oauth-mission], Section "Resource Server Enforcement").

The OAuth binding's caller authorization and minimization rules apply to it ([I-D.draft-mcguinness-oauth-mission], Section "Caller Authorization and Minimization"), and its disclosure is member-scoped. derivations_remaining serves issuance-budget consumers, not resource server enforcement, and the AS MUST disclose it only to a caller the deployment has granted that member's disclosure privilege. By default, an audience-authorized resource server receives the audience-filtered enforcement projection without it.

An AS MUST NOT include derivations_remaining in an introspection response unless it holds the Mission, that is, unless it is the Mission issuer ([I-D.draft-mcguinness-oauth-mission], Section "Only the Issuer Reports Mission State").

The following is an example of an introspection response to a caller granted the derivations_remaining disclosure privilege:

{
  "active": true,
  "client_id": "s6BhdRkqt3",
  "exp": 1790000000,
  "mission": {
    "id": "msn_8RfX2Lqv9TqMv4z7sA2bN1k0YpEdHc9-",
    "issuer": "https://as.example.com",
    "state": "active",
    "derivations_remaining": 187
  }
}

7. Approval Rendering

Where an effective derivation_limit is established at a human approval event, the AS MUST render it for consent at that event, as context beside the derived Authority Set, in the rendering step of the OAuth binding's approval sequence ([I-D.draft-mcguinness-oauth-mission], Section "Mission Approval"). The rendering shows the established value, not only the requested one. Where the AS supports the Continuation profile's async delegation transport, the rendering MUST also state that the refreshes of an async delegation family are not counted against the limit (Section 4.3). Where the Mission Issuer is a Mission Authority Server issuing grants under the Mission Issuance Grant profile, the rendering MUST also state that the limit bounds the grants it issues, not the tokens consuming Authorization Servers issue from them (Section 4.5).

The rendered limit is one Mission's local bound (Section 9.4). Where a deployment runs child delegation, that profile states what an approval interface discloses beside it ([I-D.draft-mcguinness-oauth-mission-child-delegation]).

8. Conformance

An AS conforming to this document MUST implement:

A resource server does not need to understand this document to enforce Mission-bound tokens; derivations_remaining is not an enforcement input (Section 6).

9. Security Considerations

The security considerations of [I-D.draft-mcguinness-oauth-mission] apply. This section covers what the derivation limit adds.

9.1. Issuance, Not Authority

The derivation limit bounds how many counted issuance operations the issuer performs; the refreshes of an async delegation family, and redemption and refresh at a Mission Issuance Grant consuming Authorization Server, are not counted (Section 9.2, Section 4.5). It does not narrow the Authority Set, shorten a token's lifetime, or bound the requests a resource server honors under a token already issued: a derived token remains usable until its exp. A deployment that needs to bound use, rather than issuance, adopts a runtime control such as metering ([I-D.draft-mcguinness-mission-metering]).

9.2. Async Delegation Families

Because the refreshes of an async delegation family are not counted (Section 4.3), the limit does not bound how many tokens the issuer mints under such a family. The Continuation profile bounds the family instead: its delegated authorization state is a subset of the Mission's Authority Set, its absolute lifetime equals the Mission's expires_at, and it is invalidated when the Mission reaches a terminal state ([I-D.draft-mcguinness-oauth-mission-continuation], Section "Async Delegation Transport").

9.3. Delegation Fan-Out

In-Mission delegation bounds the length of a delegation chain with max_depth and its breadth with allowed_delegates ([I-D.draft-mcguinness-oauth-mission], Section "Delegation Constraints"). The derivation limit caps total derivations, including each Token Exchange that issues a delegated token (Section 4.3), however the resulting credentials are distributed.

9.4. Composition Across Missions

derivation_limit is a per-Mission bound the issuer AS enforces for that Mission alone; a Child Mission's own derivation_limit is independent of its parent's, and the parent's cap does not bound the child subtree by default. The derivations summed across an entire child subtree can therefore exceed what a single approval appears to bound at consent time.

For example, a child-delegation deployment ([I-D.draft-mcguinness-oauth-mission-child-delegation]) allowing max_children 3 per Mission with max_child_depth 2 admits up to 12 concurrently non-terminal descendant Missions (3 in the first generation, up to 9 in the second), each with its own independent derivation_limit; at 10 each, those 12 live Missions can draw up to 120 derivations while no single bound the Approver saw exceeds 10. Neither figure is a lifetime ceiling. max_children counts only non-terminal children, so a completed child frees its slot and its replacement brings its own derivation_limit. Absent a lineage-wide bound ([I-D.draft-mcguinness-mission-metering]), no count limits what the subtree derives over its lifetime; Mission expiry bounds only its duration.

Cross-domain projection composes separately: local issuance at a Resource AS is not counted against the origin issuer's cap (Section 4.4), and neither are the tokens a consuming Authorization Server issues under the Mission Issuance Grant profile (Section 4.5). The OAuth binding's composition guidance applies to the derivation limit as to its other bounds ([I-D.draft-mcguinness-oauth-mission], Section "Composition and the Effective Ceiling").

9.5. Audit Recomputation

An auditor recomputes the expected derivation_limit from the recorded requested_derivation_limit (or its absence) and the Mission's policy_version ([I-D.draft-mcguinness-oauth-mission], Section "Mission Authority") against the deployment's retained, versioned policy; a mismatch is a policy-application defect to investigate, not a Mission-record integrity failure, since neither integrity anchor commits derivation_limit.

9.6. Concurrent Derivation

A count that is read and then incremented in separate steps lets parallel refreshes or exchanges exceed the limit. Section 4.2 forbids that outcome, not a particular locking design.

10. Privacy Considerations

derivations_remaining reveals how actively a Mission's grant is exercised and, across successive responses, its issuance cadence. Member-scoped disclosure (Section 6) limits it to callers the deployment grants that privilege.

11. IANA Considerations

This document requests registration of the following in the "Mission Intent Members" registry established by [I-D.draft-mcguinness-oauth-mission]:

This document's promotion criterion for the member is a complete definition of its request semantics, effective limit, counting, and enforcement. The definitions in Section 3, Section 4, and Section 5 meet it, which a Designated Expert confirms before the stable registration ([I-D.draft-mcguinness-oauth-mission], Section "Mission Intent Members Registry").

derivation_limit is a Mission Record member and derivations_remaining a member of the introspection mission member, each under an extension point of the OAuth binding, and derivations_exhausted is a value of the OAuth binding's mission_error member. None of these has an IANA registry, so this document requests no further registration.

12. References

12.1. Normative References

[I-D.draft-mcguinness-oauth-mission]
McGuinness, K., "Mission-Bound Authorization for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission.html>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC6749]
Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/rfc/rfc6749>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/rfc/rfc7662>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC8693]
Jones, M., Nadalin, A., Campbell, B., Ed., Bradley, J., and C. Mortimore, "OAuth 2.0 Token Exchange", RFC 8693, DOI 10.17487/RFC8693, , <https://www.rfc-editor.org/rfc/rfc8693>.

12.2. Informative References

[I-D.draft-mcguinness-mission-metering]
McGuinness, K., "Mission Consumption Metering", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-mission-metering.html>.
[I-D.draft-mcguinness-oauth-mission-child-delegation]
McGuinness, K., "Mission Child Delegation for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-child-delegation.html>.
[I-D.draft-mcguinness-oauth-mission-continuation]
McGuinness, K., "Mission Continuation for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-continuation.html>.
[I-D.draft-mcguinness-oauth-mission-cross-domain]
McGuinness, K., "Mission Cross-Domain Projection for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-cross-domain.html>.
[I-D.draft-mcguinness-oauth-mission-expansion]
McGuinness, K., "Mission Expansion for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-expansion.html>.
[I-D.draft-mcguinness-oauth-mission-issuance-grant]
McGuinness, K., "Mission Issuance Grant for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-issuance-grant.html>.
[I-D.draft-mcguinness-oauth-mission-progressive]
McGuinness, K., "Mission Progressive Authorization for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-progressive.html>.
[I-D.draft-mcguinness-oauth-mission-template]
McGuinness, K., "Mission Template for OAuth 2.0", , <https://mcguinness.github.io/mission-bound-authorization/draft-mcguinness-oauth-mission-template.html>.
[RFC8785]
Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, , <https://www.rfc-editor.org/rfc/rfc8785>.

Appendix A. Integrity Anchor Test Vector

This non-normative vector shows requested_derivation_limit committed by intent_hash, computed as the OAuth binding specifies ([I-D.draft-mcguinness-oauth-mission], Sections "Integrity Anchors" and "Canonicalization Rules"), with the issuer https://as.example.com. The canonical-bytes block is the exact JCS [RFC8785] output, wrapped here for layout only; removing the line breaks, and adding no characters, recovers the canonical form.

intent_hash, over this Mission Intent as the envelope value with typ mission-intent:

{
  "goal": "Reconcile Q3 invoices",
  "target_resources": ["https://erp.example.com"],
  "expires_at": "2026-12-31T23:59:59Z",
  "requested_derivation_limit": 20
}

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","r
equested_derivation_limit":20,"target_resources":["https://erp.exa
mple.com"]}}
intent_hash = sha-256:r--mF07yZfWRGV6N28A2u_8rUzIG-bNhpvFSS5FhoBk

Appendix B. Document History

[[ To be removed from the final specification ]]

-00

Author's Address

Karl McGuinness
Independent