Web Authorization Protocol S. Canning Internet-Draft Canva Intended status: Standards Track 16 June 2026 Expires: 18 December 2026 Registration Lifecycle and Continuous Signalling for OAuth Clients draft-canning-oauth-registration-lifecycle-latest Abstract This document defines a lifecycle state machine for OAuth 2.0 clients identified by an OAuth Client ID Metadata Document (CIMD) URL or registered via Dynamic Client Registration (RFC 7591), together with an Authorization Server-hosted admin-approval ceremony that transitions a just-in-time-registered "unmanaged" client into an admin-pinned "managed" state, and a Security Event Token-shaped event format that signals state transitions to interested consumers. The mechanism extends RFC 7591 from binary (registered or not) to a four-state machine (UNREGISTERED → UNMANAGED → MANAGED, with SUSPENDED reachable from UNMANAGED and MANAGED) while preserving client identifier stability across all transitions. The Authorization Server metadata registry is extended with a client_promotion_endpoint member naming the ceremony endpoint, and a small profile of [SSF]/[CAEP] event types is defined. 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 18 December 2026. Copyright Notice 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. Table of Contents 1. Introduction 1.1. Editor's note: running-code basis 1.2. Terminology 2. Registration State Machine 2.1. States 2.2. Identifier stability 2.3. Transitions 3. Unmanaged-Tier Policy 4. Admin Approval Ceremony 4.1. Endpoint 4.2. Ceremony obligations 4.3. Pinning 4.4. Action: unsuspend 5. Managed-Tier Policy 6. Suspended State 6.1. Behaviour 6.2. Reverse transitions 7. Per-Request Guards 7.1. JWKS fetch size cap and SSRF discipline 7.2. private_key_jwt audience value 8. Lifecycle Event Signalling 8.1. Envelope 8.2. Event types 8.3. Event payload 8.4. Signing and delivery 9. Security Considerations 9.1. Refresh tokens deferred until MANAGED 9.2. Same-origin redirect_uris for unmanaged clients 9.3. Exfiltration via the ceremony return_uri 9.4. Pinning vs. silent change 9.5. SUSPENDED → MANAGED reverse-transition 9.6. Lookalike clients 9.7. Event signal authenticity 9.8. Admin role compromise 10. IANA Considerations 10.1. OAuth Authorization Server Metadata 10.2. Token Claims 10.3. SET Event Type URIs 11. References 11.1. Normative References 11.2. Informative References Appendix A. Open Issues A.1. A.1 PENDING state (admin approval before first login) A.2. A.2 JWKS size cap numerics A.3. A.3 private_key_jwt audience canonicalisation A.4. A.4 Hard-reset action ("purge") A.5. A.5 Admin role vocabulary A.6. A.6 Pinning granularity (URL only vs. URL + key hash) A.7. A.7 Event signing A.8. A.8 Permanent prefix for event type URIs Appendix B. Acknowledgments Author's Address 1. Introduction OAuth 2.0 client registration today is binary. A client either holds a client_id issued by the Authorization Server (whether out-of-band, by Dynamic Client Registration [RFC7591], or by identifying itself with a CIMD URL [CIMD]) or it does not. Real enterprise deployments operate a wider range of registration states: a just-in-time- registered first-seen client may need extra controls (restricted scope, extra consent, no refresh tokens) until an administrator has had an opportunity to review it; a previously trusted client may be suspended pending investigation; an admin who has approved a client may wish to "pin" the specific keys and redirect URIs in force at the time of approval, so that subsequent silent changes by the client are not honoured until the admin re-reviews them. This document defines a four-state lifecycle, an Authorization Server-hosted admin ceremony for promotion and suspension actions, and a Security Event Token-shaped event format for signalling state transitions. The lifecycle is independent of the registration mechanism (CIMD URL, DCR client_id, or pre-configured client_id); it preserves identifier stability across all transitions. The mechanism is sized for the *same-domain SSO bootstrap* target of the broader zeroconf-sso profile [ZEROCONF-SSO]: in particular, the UNMANAGED state is restrictive enough that an Authorization Server can safely accept a first-seen CIMD URL without administrator intervention, while the MANAGED state's pinning rules preserve the admin's review choices against silent client-side change. 1.1. Editor's note: running-code basis This draft is motivated by, and tracks, the following entries in spec/GAPS.md of the zeroconf-sso prototype [ZEROCONF-SSO] [GAPS]: - *GAP-3* — "Registration lifecycle states and signaling". The state machine and admin ceremony are direct lifts of spec/ PROTOCOL.md §9 in that prototype, which the prototype's IdP component implements end-to-end (admin promotion, suspension, unsuspension; event emission at /admin/events). - *GAP-6* — "JWKS fetch size cap and SSRF discipline" — addressed in Section 7.1. - *GAP-7* — "private_key_jwt audience value" — addressed in Section 7.2, where this draft pins the canonical value pending RFC 7523bis stabilisation. - *GAP-8* — "SUSPENDED state's required reverse-transition path" — addressed in Section 6. - *GAP-9* — "Admin ceremony role vocabulary" — deliberately left in Open Issues, with a minimal in-text MUST that an admin role exists. The prototype IdP implements UNMANAGED, MANAGED, and SUSPENDED end to end; the prototype's integration tests assert that promotion changes policy without re-registration and that suspension blocks login. 1.2. 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. The following terms are used throughout, in addition to the terms defined in [RFC6749], [RFC8414], [RFC7591], and [CIMD]. Client identifier: The OAuth 2.0 client_id value, whether issued by the Authorization Server out-of-band, issued by DCR [RFC7591], or formed by the client as a CIMD URL [CIMD]. Registration state: The state of a client identifier on the Authorization Server, as defined in Section 2. Pinned set: The snapshot of jwks_uri and redirect_uris taken by the Authorization Server at the moment a client transitions into the MANAGED state, applied subsequently in place of the live values from the client's metadata source. Defined in Section 4.3. Domain admin: An End-User of the Authorization Server who holds an implementation-defined role that authorises driving the admin ceremony defined in Section 4. Role naming is discussed in Open Issues (Appendix A). Lifecycle event: A Security Event Token-shaped event ([RFC8417]) emitted by the Authorization Server when a client transitions between registration states. Defined in Section 8. 2. Registration State Machine 2.1. States A client identifier known to an Authorization Server implementing this specification is in exactly one of the following states at any time: +-------------+ | UNREGISTERED| +------+------+ | first valid authz request | v +-------------+ admin promote +---------+ | UNMANAGED |------------------>| MANAGED | +------+------+ +----+----+ | | +------- admin suspend ---------+ | v +-----------+ | SUSPENDED | +-----------+ | admin unsuspend (returns to MANAGED only) The states are: UNREGISTERED: The Authorization Server has no record of the client identifier. UNMANAGED: The Authorization Server has accepted a first valid authorization request bearing this client identifier, but no domain admin has approved the client. Restrictive policy applies (Section 3). MANAGED: A domain admin has approved the client through the ceremony in Section 4. The Authorization Server holds a pinned set of jwks_uri and redirect_uris for the client and applies them in place of the live values. Relaxed policy MAY apply (Section 5). SUSPENDED: A domain admin has suspended the client, or an implementation- defined automated trigger has suspended it. All authorization requests are refused with unauthorized_client (Section 6). This document does not define additional states; in particular it does not define a PENDING state (admin approval _before_ first login). PENDING is discussed under Open Issues (Appendix A). 2.2. Identifier stability The client identifier MUST NOT change across any transition defined in this document. Promotion from UNMANAGED to MANAGED, suspension from any active state to SUSPENDED, and unsuspension SUSPENDED → MANAGED are policy-state changes on the existing identifier; they are NOT re-registrations. This rule applies regardless of how the identifier was minted: a CIMD URL [CIMD] client_id is still its CIMD URL after promotion; a DCR [RFC7591]-issued identifier is still the same string. 2.3. Transitions The transitions defined by this document are: +==============+===========+=============================+ | From | To | Trigger | +==============+===========+=============================+ | UNREGISTERED | UNMANAGED | First valid authorization | | | | request from the client. | +--------------+-----------+-----------------------------+ | UNMANAGED | MANAGED | Domain admin completes | | | | promote action (Section 4). | +--------------+-----------+-----------------------------+ | UNMANAGED | SUSPENDED | Domain admin or automated | | | | trigger suspends. | +--------------+-----------+-----------------------------+ | MANAGED | SUSPENDED | Domain admin or automated | | | | trigger suspends. | +--------------+-----------+-----------------------------+ | SUSPENDED | MANAGED | Domain admin completes | | | | unsuspend action. | +--------------+-----------+-----------------------------+ Table 1 No other transitions are permitted. In particular: * There is no SUSPENDED → UNMANAGED transition. See Section 6 and Open Issues (Appendix A). * There is no MANAGED → UNMANAGED transition (a "demote" action is not defined by this document). * Deletion (transitioning back to UNREGISTERED by removing the client record) MAY be performed by the Authorization Server operator out-of-band; this document does not define a deletion ceremony. 3. Unmanaged-Tier Policy When the Authorization Server processes an authorization request ([OAUTH-2.1] §4.1) from a client in UNMANAGED state, it MUST: * For CIMD clients ([CIMD]), enforce *same-origin* ([RFC6454]) between every redirect_uri in the client's CIMD document and the CIMD URL (i.e. the client_id). The authorization request's redirect_uri MUST also share that origin and MUST be one of those listed in the CIMD document. * For DCR clients ([RFC7591]), enforce that every registered redirect_uri shares an origin with at least one of the Authorization Server-validated identifiers presented at registration time. In the absence of such an identifier the Authorization Server MUST require the operator to pre-approve the client (i.e. the client SHOULD NOT be permitted to operate in UNMANAGED state via DCR alone). This avoids reintroducing the unbounded-DCR problem that motivated CIMD. * Restrict the granted scope set to an implementation- or profile- defined minimum. For the zeroconf-sso profile [ZEROCONF-SSO] the RECOMMENDED minimum is openid email profile. The Authorization Server MUST reject requested scopes outside this set with the OAuth 2.1 error invalid_scope ([OAUTH-2.1] §4.1.2.1). * Display an explicit consent screen on every authorization, prominently showing the client_id (CIMD URL or DCR-issued identifier) hostname (cf. [CIMD] §6.4). * NOT issue refresh tokens to the client. Refresh tokens are a delegable grant surface; this document defers them to the MANAGED state. * Persist an audit record per authorization containing at minimum: timestamp, end-user sub, client_id, redirect_uri, granted scope, and request IP. The record MUST be visible to a domain admin reviewing first-seen clients. * Include the claim app_tier with the value "unmanaged" in any ID Token issued ([RFC7519]); this claim is REQUIRED for UNMANAGED- state issuances and is REGISTERED by this document (Section 10). 4. Admin Approval Ceremony 4.1. Endpoint This document registers a new Authorization Server metadata member (Section 10): client_promotion_endpoint: An https URL identifying the endpoint at which the admin ceremony is hosted. RECOMMENDED for any Authorization Server that supports the UNMANAGED state. A Relying Party admin tool initiates the ceremony by causing the admin's browser to navigate to the endpoint with the following parameters: client_id (REQUIRED): The client_id of the candidate client (a CIMD URL or DCR-issued identifier). action (REQUIRED): One of "promote", "suspend", "unsuspend". return_uri (REQUIRED): An https URL to which the Authorization Server redirects the admin after the ceremony completes, carrying the outcome. state (RECOMMENDED): An opaque value the RP admin tool will validate when the admin returns. Echoed by the Authorization Server in the return_uri redirect. 4.2. Ceremony obligations The Authorization Server MUST satisfy the following on receipt of a ceremony request: 1. Authenticate the End-User driving the ceremony. The End-User MUST hold a domain admin role (see Open Issues, Appendix A, for role-vocabulary discussion). If authentication fails, or the authenticated user does not hold the role, the ceremony MUST be denied and a result=denied outcome MUST be reported per (6) below. 2. Re-fetch the candidate client's CIMD document (for CIMD clients) under the same fetch discipline as during authorization processing: HTTP GET, no redirects, SSRF-special-use-IP rejection, 5 KB cap for the CIMD doc itself, validation per [CIMD]. A failure here MUST cause the ceremony to surface the error to the admin and MUST NOT transition state. 3. Display, on the approval screen, the resolved redirect_uris, jwks_uri, and client_name (if present) so the admin can see exactly what is being pinned. 4. Verify that return_uri shares an origin with the candidate client_id. For CIMD clients the origin of the client_id is the origin of the CIMD URL; for DCR clients the Authorization Server MAY use the origin of any registered redirect_uri. A mismatch MUST cause result=invalid_request. 5. Apply the action only if the admin issues an explicit approval gesture (e.g. clicks a confirmation button). Closing the browser tab MUST be treated as denial, leaving the registration state unchanged. 6. Regardless of outcome, redirect the admin to the return_uri carrying: * result — one of "approved", "denied", "invalid_request". * client_id — the candidate identifier. * state — echoed if supplied per §5.1. The return_uri MUST receive only these parameters. The Authorization Server MUST NOT include any user-identifying information about the admin in the return_uri redirect. 4.3. Pinning On approval of a promote action, the Authorization Server MUST snapshot: * the client's CIMD URL (for CIMD clients), or DCR identifier (for DCR clients), as the canonical client identifier; * the current jwks_uri value, and the SHA-256 hash of the document's current key set (the Authorization Server MAY pin both the URL and the hash, or only the URL — see Open Issues (Appendix A)); * the current redirect_uris set. After promotion, the Authorization Server SHOULD continue to refresh the CIMD document on its normal cache schedule, but MUST treat any change to jwks_uri or redirect_uris as a security-relevant change per [CIMD] §6.3 and SHOULD require re-approval before honouring the new values. 4.4. Action: unsuspend The unsuspend action requires that the candidate client be in SUSPENDED state. On approval, the Authorization Server MUST re- establish the pinned set previously held (i.e. the values pinned at the most recent promote) and transition the client to MANAGED. The Authorization Server MUST NOT discard the pinned set on unsuspension. See Section 6 for the rationale. 5. Managed-Tier Policy When the Authorization Server processes an authorization request from a client in MANAGED state, the Authorization Server: * MUST enforce redirect_uri against the *pinned* set, not the current CIMD document or DCR record. * MAY relax the UNMANAGED scope restriction subject to the Authorization Server's local policy. * MAY skip the per-request consent screen if the End-User has previously consented (standard OpenID Connect behaviour). * MAY issue refresh tokens. * MUST still emit the iss authorization response parameter [RFC9207], and MUST still validate private_key_jwt ([RFC7523]) against the pinned JWKS. * MUST NOT include app_tier: unmanaged in any ID Token. The claim MAY be set to "managed" for downstream Relying Party signalling. 6. Suspended State 6.1. Behaviour A SUSPENDED client MUST be refused with the OAuth 2.1 error unauthorized_client ([OAUTH-2.1] §4.1.2.1). The error response MUST be delivered to the request's redirect_uri only if that URI remains valid for the suspended client (i.e. it remains in the pinned set for previously-MANAGED clients, or the same-origin rule of Section 3 for never-promoted clients). Otherwise the Authorization Server MUST surface the error to the End-User directly per [OAUTH-2.1] §2.3.5 and §4.1.2.1. The Authorization Server MUST emit the iss parameter on the error redirect ([RFC9207] §2.2) when it does deliver an error to the request's redirect_uri. 6.2. Reverse transitions A SUSPENDED client returns to MANAGED state via the unsuspend action (Section 4.4). No other reverse transition out of SUSPENDED is defined by this document. In particular, SUSPENDED → UNMANAGED is NOT permitted. This preserves the pinned set the admin previously reviewed; discarding it would lose information without operator review and re-introduce the silent-change risk the pinning step was designed to close. A deployment that wants a hard reset (re-establish via the JIT path with no pinned values) MUST delete the client record out-of-band (see Open Issues, Appendix A, for a possible "purge" action). 7. Per-Request Guards This section pins two behaviours that the CIMD draft [CIMD] and RFC 7523bis [RFC7523BIS] leave open, and that the prototype [ZEROCONF-SSO] surfaced (GAP-6 and GAP-7). 7.1. JWKS fetch size cap and SSRF discipline The Authorization Server MUST fetch the client's JWKS from the jwks_uri in the (live or pinned) client metadata to validate private_key_jwt ([RFC7523]) client assertions. This fetch MUST apply: * the same hostname-resolution and SSRF protections as the CIMD fetch ([CIMD] §6.5), in particular: rejection of host components resolving to RFC 6890 special-use addresses (except where the Authorization Server itself is on a loopback interface); * no HTTP redirects; * a body size cap of *32 KB*. This is larger than the [CIMD] §6.6 5 KB cap for the metadata document because realistic JWKS documents carrying current and rotation keys, plus optional key- encipherment material, exceed 5 KB. The 32 KB number was determined empirically against a sample of real-world JWKS documents; it accommodates roughly 16 RSA-2048 keys with metadata. The cache invalidation rules from [CIMD] §4.4 apply unchanged to the JWKS cache. 7.2. private_key_jwt audience value The Authorization Server MUST accept a client assertion JWT (per [RFC7523]) whose aud claim equals either: * the Authorization Server's issuer value as published in its metadata ([RFC8414]); OR * the URL of the token endpoint at which the assertion is being presented. This document REQUIRES Authorization Servers to accept both values in this revision. RFC 7523bis [RFC7523BIS] is the authoritative specification once published; the choice of which value to RECOMMEND to clients is deferred to it. Clients MAY mint assertions with the issuer value, but the token endpoint value remains the canonical OIDC Core §9 convention and many existing Authorization Servers require it; clients SHOULD be prepared to use either based on deployment policy. This permissive posture is bounded in time: once [RFC7523BIS] stabilises, a future revision of this document SHOULD remove the permissive acceptance rule. 8. Lifecycle Event Signalling 8.1. Envelope The Authorization Server MUST emit a lifecycle event for every state transition defined in Section 2. Events are structurally compatible with the OpenID Shared Signals Framework [SSF] and Continuous Access Evaluation Profile [CAEP], and are carried inside a Security Event Token (SET) [RFC8417]. A lifecycle event SET MUST carry the following claims: iss: The Authorization Server's issuer URL as published in its metadata ([RFC8414]). iat: Event issuance time. jti: Unique event identifier. aud: The audience(s) entitled to receive the event. In this profile, the audience SHOULD include the client_id of the subject client. Stream-configured fan-out to additional audiences is an SSF stream property and out of scope. events: A single-entry object keyed by an event type URI defined in Section 8.2, whose value is the per-event payload defined in Section 8.3. 8.2. Event types This document defines three event types within a profile URI prefix: +=======================+==================================+ | Event type URI suffix | Trigger | +=======================+==================================+ | client-promoted | UNMANAGED → MANAGED | +-----------------------+----------------------------------+ | client-suspended | UNMANAGED or MANAGED → SUSPENDED | +-----------------------+----------------------------------+ | client-unsuspended | SUSPENDED → MANAGED | +-----------------------+----------------------------------+ Table 2 The URI prefix is https://schemas.zeroconf-sso.example/secevent/ in this revision (matching the prototype [ZEROCONF-SSO]). A permanent IANA-registered prefix is requested in Section 10; until that registration is approved, implementations MUST use the prefix above for interoperability with the prototype. 8.3. Event payload A lifecycle event payload MUST contain at minimum: subject: A SET §2.3-compatible subject object { "format": "uri", "uri": "..." } whose uri value is the client_id of the subject client. event_timestamp: Milliseconds since the Unix epoch. prior_state: One of "UNREGISTERED", "UNMANAGED", "MANAGED", "SUSPENDED". new_state: One of "UNMANAGED", "MANAGED", "SUSPENDED". The following additional members are REQUIRED on specific event types: * client-promoted and client-unsuspended MUST carry a pinned object with members jwks_uri (the URL) and redirect_uris (the array). The pinned key set hash MAY be included as jwks_sha256 (lower-case hex). * client-suspended MUST carry reason (free-form string) and triggered_by (one of "admin", "automated"). 8.4. Signing and delivery The lifecycle event format defined here is structurally compatible with a SET-wrapped JWT, but this document does NOT mandate signing in this revision. The prototype [ZEROCONF-SSO] emits plain JSON event objects so that the event log is inspectable to the integration test; this MUST be revisited before any real-world deployment (see Open Issues, Appendix A). Delivery is via an SSF stream configured out-of-band per [SSF] §7. The Authorization Server MUST persist emitted events in a log addressable for inspection (admin debug endpoint or operator-side durable log); the prototype implements /admin/events for this purpose. 9. Security Considerations 9.1. Refresh tokens deferred until MANAGED Refresh tokens are a delegable grant surface: possession of a refresh token, plus the ability to authenticate as the client, lets the holder mint access tokens indefinitely until the refresh token is revoked. This document defers refresh-token issuance to the MANAGED state (Section 3) so that the first interactive grant to a first-seen client cannot be silently extended past the End-User's attention. A deployment that disagrees with this trade-off MAY relax it as local policy, but at the cost of admin visibility: unmanaged-tier policy is the only thing the Authorization Server gives an enterprise to limit a not-yet-reviewed client's reach. 9.2. Same-origin redirect_uris for unmanaged clients The UNMANAGED state's same-origin rule on redirect_uris (Section 3) closes an exfiltration channel: a CIMD URL at https://app.example.com/cimd whose document lists redirect URIs at arbitrary unrelated hosts could otherwise be used to surface authorization codes at any of them. Forcing every redirect URI to share an origin with the client_id constrains the attack surface to the host that holds the CIMD URL itself. 9.3. Exfiltration via the ceremony return_uri The return_uri parameter of the admin ceremony (Section 4) carries the outcome of a promotion or suspension back to the RP admin tool. If the Authorization Server accepted an arbitrary return_uri, a hostile admin tool at an unrelated origin could receive the result=approved signal and use it to drive out-of-band exploitation against an enterprise that mistakenly clicked through the ceremony. The Authorization Server MUST constrain return_uri to share an origin with the candidate client_id (Section 4, step 4) to close this channel. 9.4. Pinning vs. silent change The pinning rule (Section 4.3) is the only mechanism this document provides against silent client-side change after admin approval. An attacker who briefly controls a managed client's hosting endpoint (but not its CIMD signing keys, if applicable) cannot mint new redirect URIs that the Authorization Server will honour; the Authorization Server applies the pinned set. The administrator MUST be re-engaged to honour a change. Authorization Servers that omit the pinning step (i.e. continue to follow live redirect_uris and jwks_uri after admin approval) re- introduce the silent-change risk in full. 9.5. SUSPENDED → MANAGED reverse-transition The decision to permit only SUSPENDED → MANAGED (Section 6) trades off "fast recovery to the most recent admin-reviewed state" against "operator-driven hard reset". A deployment that experiences a genuine compromise of a previously-managed client SHOULD prefer deletion of the client record over unsuspension, so that the subsequent JIT re-establishment puts the admin back in the loop. See Open Issues (Appendix A) for a possible "purge" action. 9.6. Lookalike clients This document does not address lookalike clients (a malicious vendor publishing a CIMD document with a deceptively similar client_name or logo). The UNMANAGED-tier policy of Section 3 is the only mitigation here, and is structural rather than detective: the restricted scope and explicit consent screen reduce blast radius even if the End-User is deceived. A heavier verification mechanism remains out of scope; see Open Issues. 9.7. Event signal authenticity This revision does not require lifecycle events to be signed JWTs (Section 8). A deployment that consumes events from an outside party MUST sign them per [RFC8417] §4; the prototype's omission is for inspectability only. 9.8. Admin role compromise Possession of the admin role at the Authorization Server is equivalent to control over the MANAGED-tier policy applied to every client the role can promote. The Authorization Server MUST hold domain admins to authentication standards at least as strong as those it requires of end users, and SHOULD require step-up authentication ([RFC9470]) at the moment of ceremony approval. 10. IANA Considerations 10.1. OAuth Authorization Server Metadata This document registers the following member in the "OAuth Authorization Server Metadata" registry established by [RFC8414]: Metadata Name: client_promotion_endpoint Metadata Description: An HTTPS URL identifying the Authorization Server-hosted admin ceremony endpoint for transitioning clients between lifecycle states. Change Controller: IETF Reference: This document, Section 4 10.2. Token Claims This document registers the following claim in the "JSON Web Token Claims" registry established by [RFC7519]: Claim Name: app_tier Claim Description: Lifecycle state of the client to which a token was issued, expressed as one of "unmanaged" or "managed". Used by Relying Parties to distinguish administrator-reviewed from JIT- only-registered clients. Change Controller: IETF Reference: This document, Section 3 and Section 5 10.3. SET Event Type URIs This document REQUESTS the registration of three new SET event type URIs in the OAuth/OIDF event-type registry. Pending establishment of a permanent prefix, the URIs in Section 8.2 use a profile- private prefix. Once a permanent prefix is assigned, this document will be updated to refer to it. 11. References 11.1. Normative References [CIMD] Parecki, A. and E. Smith, "OAuth Client ID Metadata Document", March 2026, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC6454] Barth, A., "The Web Origin Concept", RFC 6454, DOI 10.17487/RFC6454, December 2011, . [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012, . [RFC7591] Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", RFC 7591, DOI 10.17487/RFC7591, July 2015, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8414] Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, June 2018, . [RFC8417] Hunt, P., Ed., Jones, M., Denniss, W., and M. Ansari, "Security Event Token (SET)", RFC 8417, DOI 10.17487/RFC8417, July 2018, . 11.2. Informative References [CAEP] OpenID Foundation, "OpenID Continuous Access Evaluation Profile 1.0", 2024, . [GAPS] "zeroconf-sso: standards gaps log (spec/GAPS.md)", 2026, . [I-D.canning-oauth-dns-issuer-discovery] Canning, S., "DNS-Based Discovery of OAuth Authorization Servers for Email Domains", 2026, . [I-D.canning-oauth-issuer-domain-binding] Canning, S., "Issuer-to-Domain Authority Binding for OAuth", 2026, . [OAUTH-2.1] Hardt, D., Parecki, A., and T. Lodderstedt, "The OAuth 2.1 Authorization Framework", 2025, . [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, . [RFC7523] Jones, M., Campbell, B., and C. Mortimore, "JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants", RFC 7523, DOI 10.17487/RFC7523, May 2015, . [RFC7523BIS] IETF OAuth WG, "OAuth 2.0 JWT-Secured Authorization Request Profile for Client Authentication and Authorization Grants", 2026, . [RFC9207] Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0 Authorization Server Issuer Identification", RFC 9207, DOI 10.17487/RFC9207, March 2022, . [RFC9470] Bertocci, V. and B. Campbell, "OAuth 2.0 Step Up Authentication Challenge Protocol", RFC 9470, DOI 10.17487/RFC9470, September 2023, . [SSF] OpenID Foundation, "OpenID Shared Signals Framework Specification 1.0", 2024, . [ZEROCONF-SSO] "zeroconf-sso prototype and profile (running code)", 2026, . Appendix A. Open Issues This appendix lists open questions that this revision does not foreclose. Each entry corresponds to an item in spec/GAPS.md of the zeroconf-sso prototype [ZEROCONF-SSO][GAPS]. A.1. A.1 PENDING state (admin approval before first login) This document defines the path "first authorization request → UNMANAGED → admin promotes → MANAGED". An enterprise that wants its admins to approve a client BEFORE the first user login (the PENDING case) cannot express that policy under this revision; the first login is always permitted under UNMANAGED-tier policy. A future revision MAY add a PENDING state, gated by a per-Authorization-Server policy that the operator sets out-of-band. A.2. A.2 JWKS size cap numerics Section 7.1 pins 32 KB based on empirical inspection of real- world JWKS documents. The right number depends on observed key- rotation patterns and on the upper bound an Authorization Server is willing to accept before considering a document hostile. A future revision SHOULD revisit the number with broader deployment evidence. A.3. A.3 private_key_jwt audience canonicalisation Section 7.2 accepts both the issuer URL and the token endpoint URL pending [RFC7523BIS]. The right canonical value is deferred to that draft. This document SHOULD be aligned with RFC 7523bis once that document stabilises; the permissive acceptance rule SHOULD be removed in favour of a single canonical value. A.4. A.4 Hard-reset action ("purge") Section 6 permits only SUSPENDED → MANAGED, not SUSPENDED → UNMANAGED. An operator that wants to wipe the pinned set on the way back from suspension has no protocol-level lever in this revision beyond deletion of the client record. A future revision MAY define a fourth ceremony action purge that combines deletion with an event signal so that downstream consumers see the reset. A second design question is whether the client_unsuspended event should carry the prior pinned values so that consumers can detect tampering across the suspended interval. This document does not require it. A.5. A.5 Admin role vocabulary Section 4 requires a "domain admin role" but defines exactly one. Real deployments routinely carry multiple roles (security_admin, app_admin, audit) and different action verbs (promote vs. suspend vs. unsuspend) may warrant different roles. The prototype [ZEROCONF-SSO] maps a single literal role string to all three actions. A future revision MAY define: * A small standardised role vocabulary with a profile-defined mapping from role to permitted action. * An OAuth-scopes-based gate on the admin's IdP session, in lieu of a separate role vocabulary. This document takes no position. A.6. A.6 Pinning granularity (URL only vs. URL + key hash) Section 4.3 permits the Authorization Server to pin only the jwks_uri URL, or the URL plus a SHA-256 hash of the current key set. The trade-off is admin friction during scheduled key rotation versus blast radius if jwks_uri content is silently swapped. A future revision MAY mandate the hash form for high-assurance deployments. A.7. A.7 Event signing Section 8 does not mandate JWT-wrapping of lifecycle events. The running-code argument for plain-JSON envelopes is inspectability during integration testing. The argument for mandating JWT (i.e. RFC 8417 SET signing) is that any cross-organisation event delivery demands cryptographic authenticity. A future revision SHOULD mandate the SET-wrapped form for any deployment that publishes events to a consumer outside the issuing organisation. A.8. A.8 Permanent prefix for event type URIs Section 8.2 uses a profile-private prefix. Allocation of a permanent IANA-registered prefix is requested in Section 10; until that allocation is approved, deployments will need to interoperate on the profile-private URIs. Appendix B. Acknowledgments This work was motivated by the zeroconf-sso prototype [ZEROCONF-SSO], whose spec/GAPS.md log [GAPS] catalogued the specific scenarios cited in Appendix A. The state machine and admin ceremony shape are direct lifts of spec/PROTOCOL.md §9 in that prototype, where they are implemented end-to-end and exercised by the prototype's integration tests. Author's Address Simon Canning Canva Email: scanning@canva.com