Skip to main content

Authorization Posture Mechanism (APM): Per-Transaction Consistency for OAuth 2.0
draft-vicente-oauth-apm-02

Document Type Active Internet-Draft (individual)
Author Brian Vicente
Last updated 2026-06-28
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-vicente-oauth-apm-02
OAUTH                                                         B. Vicente
Internet-Draft                                        Sanctum SecOps LLC
Intended status: Standards Track                            28 June 2026
Expires: 30 December 2026

 Authorization Posture Mechanism (APM): Per-Transaction Consistency for
                               OAuth 2.0
                       draft-vicente-oauth-apm-02

Abstract

   This document describes the Authorization Posture Mechanism (APM), a
   method by which an OAuth 2.0 [RFC6749] authorization server, or a
   resource server acting on its behalf, re-evaluates the mutual
   consistency of three bound factors -- the client certificate, the
   access token, and the device posture -- on a per-request basis for
   privileged operations, rather than only at session establishment.
   When re-evaluated posture degrades relative to the posture under
   which the token was issued, APM defines deterministic, least-
   privilege Graduated Outcomes including scope reduction and method
   restriction, rather than a binary allow or deny.

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 30 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.

Vicente                 Expires 30 December 2026                [Page 1]
Internet-Draft                  OAuth APM                      June 2026

   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  . . . . . . . . . . . . . . . . . . . . . . . .   2
   2.  Requirements  . . . . . . . . . . . . . . . . . . . . . . . .   3
   3.  Conventions and Definitions . . . . . . . . . . . . . . . . .   4
   4.  Mechanism Overview  . . . . . . . . . . . . . . . . . . . . .   5
   5.  Wire Format . . . . . . . . . . . . . . . . . . . . . . . . .   8
     5.1.  authorization_details Object  . . . . . . . . . . . . . .   8
     5.2.  WWW-Authenticate Challenge  . . . . . . . . . . . . . . .   9
     5.3.  HTTP Status Mapping . . . . . . . . . . . . . . . . . . .  10
   6.  Posture-Signal Abstraction  . . . . . . . . . . . . . . . . .  10
   7.  Interaction Matrix  . . . . . . . . . . . . . . . . . . . . .  11
   8.  Relationship to Prior Art . . . . . . . . . . . . . . . . . .  13
   9.  Security Considerations . . . . . . . . . . . . . . . . . . .  14
     9.1.  Replay of Stale Posture Signals . . . . . . . . . . . . .  14
     9.2.  Downgrade-Forcing Attacks . . . . . . . . . . . . . . . .  14
     9.3.  Confused-Deputy Under Graduated Downgrade . . . . . . . .  14
     9.4.  Side-Channel Leakage of Device State  . . . . . . . . . .  15
   10. Implementation Status . . . . . . . . . . . . . . . . . . . .  15
   11. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  16
     11.1.  authorization_details Type Registration  . . . . . . . .  16
   12. References  . . . . . . . . . . . . . . . . . . . . . . . . .  16
   13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  16
     13.1.  Normative References . . . . . . . . . . . . . . . . . .  16
     13.2.  Informative References . . . . . . . . . . . . . . . . .  17
   Appendix A.  Worked Example: Compliance Downgrade --
           scope_reduction Outcome . . . . . . . . . . . . . . . . .  18
   Appendix B.  Appendix B.  Mapping to NIST SP 800-207 Zero Trust
           Architecture  . . . . . . . . . . . . . . . . . . . . . .  19
   Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  20
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  20

1.  Introduction

   OAuth 2.0 [RFC6749] and related mechanisms bind tokens to a client at
   issuance time.  Certificate-bound access tokens [RFC8705] and
   Demonstrating Proof of Possession (DPoP) [RFC9449] strengthen the
   binding between a token and a key.  Step-up authentication [RFC9470]
   allows a resource server to demand stronger authentication for
   specific requests.  These mechanisms are predominantly evaluated per
   session or per challenge.  Continuous Access Evaluation [CAEP]
   propagates security-event signals between providers but does not, by

Vicente                 Expires 30 December 2026                [Page 2]
Internet-Draft                  OAuth APM                      June 2026

   itself, define a per-request consistency computation across
   certificate, token, and posture at the point of enforcement.

   APM addresses a complementary problem: at the granularity of an
   individual privileged request, re-computing whether the presented
   certificate, the presented token, and the current device posture
   remain mutually consistent with the posture under which the token was
   issued, and defining what happens when they do not.

   [I-D.ietf-oauth-attestation-based-client-auth] defines attestation-
   based client authentication but explicitly leaves device-attestation
   details out of scope and operates at authentication time.  APM
   occupies the intersection: an issuance-time-anchored, per-request
   consistency check with deterministic graduated outcomes.  APM
   graduates the authorization policy rather than applying a binary
   permit or deny: when posture degrades, the mechanism reduces to the
   most permissive authorization the current posture supports.  The
   specific decision function that maps a degradation to an outcome
   class is implementation-defined and out of scope of this document;
   see the Applicability section of the corresponding Sanctum SecOps
   publication.

2.  Requirements

   This section specifies functional requirements for an APM solution.
   Requirements describe what a conforming mechanism SHOULD satisfy;
   they do not constitute a protocol specification.

   REQ-1:  For each Privileged Request, the enforcing entity SHOULD
      assemble a Consistency View comprising (a) the client certificate
      or DPoP key thumbprint, (b) the bound access token's claims
      including cnf, and (c) an integrity-protected device-posture
      signal associated with the request.

   REQ-2:  At token issuance, the authorization server SHOULD record the
      security posture of the requesting client as the Issuance Posture,
      associated with the token either as a signed claim or as server-
      side metadata accessible via token introspection [RFC7662].

   REQ-3:  The enforcing entity SHOULD evaluate the Consistency View
      against the Issuance Posture synchronously with processing of the
      Privileged Request.  The evaluation function SHOULD be
      deterministic: identical inputs MUST produce the same outcome
      classification.

   REQ-4:  The enforcing entity SHOULD produce Graduated Outcomes

Vicente                 Expires 30 December 2026                [Page 3]
Internet-Draft                  OAuth APM                      June 2026

      ordered by the least-privilege principle: Permit, Scope Reduction,
      Method Restriction, and Full Denial, applied proportionally to the
      degree of degradation.

   REQ-5:  Method Restriction SHOULD be a distinct outcome class,
      expressible in terms of HTTP methods or RAR actions per [RFC9396]
      §2.2.  The response MUST convey the permitted method or operation
      set.

   REQ-6:  Scope Reduction MUST NOT be implemented by modifying the
      access token.  It MUST be applied by the resource server or APM
      Enforcement Point as an additional constraint during request
      processing.

   REQ-7:  A deployment SHOULD define a policy that maps posture
      degradation dimensions to outcome classes in a deterministic,
      auditable manner independent of transient state beyond the
      Consistency View and Issuance Posture.

   REQ-8:  The device-posture signal MUST be integrity-protected.
      Integrity protection SHOULD be cryptographic.  The signing
      authority SHOULD be distinct from the client itself.

   REQ-9:  An APM mechanism MUST operate as an additive layer over
      existing sender-constraining mechanisms.  It MUST NOT weaken the
      cnf/x5t#S256 binding of [RFC8705] or the cnf/jkt binding of
      [RFC9449].  Implementations that do not recognize APM parameters
      MUST ignore them.

   REQ-10:  A Scope Reduction or Method Restriction outcome MUST NOT be
      interpreted as a token revocation event.  The token remains valid
      for subsequent requests, which may yield different outcome
      classifications if posture is restored.

3.  Conventions and Definitions

   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 this document:

   Consistency View:  the tuple of (client certificate, access token and
      its bound claims, current device-posture signal) assembled for a
      single privileged request.

Vicente                 Expires 30 December 2026                [Page 4]
Internet-Draft                  OAuth APM                      June 2026

   Issuance Posture:  the device-posture state recorded at the time the
      access token was issued.

   Posture Degradation:  a determination that the current device-posture
      signal is materially weaker than the Issuance Posture.

   Graduated Outcome:  one of a defined set of deterministic, least-
      privilege responses to a detected Posture Degradation:
      scope_reduction, method_restriction, or full_denial.

   APM Enforcement Point:  an authorization server or resource server
      that implements the consistency-view evaluation described in this
      document.

4.  Mechanism Overview

   For each privileged request, an APM Enforcement Point executes the
   following five-step state machine:

Vicente                 Expires 30 December 2026                [Page 5]
Internet-Draft                  OAuth APM                      June 2026

            +----------------------+
            |   Request Received   |
            +----------+-----------+
                       |
                       v
            +----------+-----------+
            |  Step 1: Assemble    |
            |  Consistency View    |
            +----------+-----------+
                       |
            +----------v-----------+
            | Step 2: Cert         |
            | Thumbprint Check     |
            +----------+-----------+
                  |           |
               PASS         FAIL -----> FULL_DENIAL
                  v
            +----------+-----------+
            | Step 3: DPoP Key     |
            | Binding Check        |
            +----------+-----------+
                  |           |
               PASS         FAIL -----> FULL_DENIAL
                  v
            +----------+-----------+
            | Step 4: Posture vs.  |
            | Issuance Posture     |
            +----------+-----------+
                  |           |
            CONSISTENT    DEGRADED
                  |           |
                  v           v
               200 OK    Step 5: Dispatch
                         Graduated Outcome
                         (scope_red | method_rest | full_deny)

   An endpoint determines which requests are "privileged" by local
   policy.  APM is a defense-in-depth control expected to be applied to
   a subset of high-value operations.  Applying APM to every request
   increases the side-channel surface described in Section 9.4.

   When Posture Degradation is detected, an APM Enforcement Point
   applies one of the following Graduated Outcome classes, ordered from
   least restrictive to most restrictive:

   *  scope_reduction: narrowing the effective authorization per
      [RFC9396];

Vicente                 Expires 30 December 2026                [Page 6]
Internet-Draft                  OAuth APM                      June 2026

   *  method_restriction: limiting the permitted HTTP method;

   *  full_denial: refusing the request.

   Policy authors MUST design graduated outcomes so that every downgrade
   path leads to a safe, self-consistent authorization state.  Each
   Graduated Outcome MUST correspond to a complete access control
   policy, not a partial policy derived by removing permissions from the
   full policy.

   The pseudocode below specifies the normative evaluation procedure:

   function EvaluateConsistencyView(request, token, postureSignal):

     # Step 1: Assemble Consistency View.
     view = ConsistencyView {
         cert:    request.mtlsClientCertificate,
         token:   token,
         posture: postureSignal
     }

     # Step 2: RFC 8705 cert thumbprint check.
     tokenCertHash     = token.cnf["x5t#S256"]
     presentedCertHash = BASE64URL(SHA256(DER_ENCODE(view.cert)))
     if tokenCertHash != presentedCertHash:
         return FULL_DENIAL("cert_thumbprint_mismatch")

     # Step 3: RFC 9449 DPoP key binding check (if applicable).
     if token.isDPoP:
         dpopProof          = request.header["DPoP"]
         dpopKey            = dpopProof.header["jwk"]
         tokenKeyThumbprint = token.cnf["jkt"]
         proofKeyThumbprint = JWK_SHA256_THUMBPRINT(dpopKey)
         if tokenKeyThumbprint != proofKeyThumbprint:
             return FULL_DENIAL("dpop_key_mismatch")
         if not ValidateDPoP(dpopProof, request.method, request.uri, token):
             return FULL_DENIAL("dpop_proof_invalid")

     # Step 4: Posture consistency evaluation.
     issuancePosture   = token.claims["apm_issuance_posture"]
     currentPosture    = view.posture
     degradationResult = ComputePostureDegradation(
                             issuancePosture, currentPosture)
     # ComputePostureDegradation is implementation-defined.
     # Its parameters, scoring, and thresholds are out of scope.

     if degradationResult == CONSISTENT:
         return GRANT(token.scope)

Vicente                 Expires 30 December 2026                [Page 7]
Internet-Draft                  OAuth APM                      June 2026

     # Step 5: Decision-function dispatch (implementation-defined).
     outcome = DispatchGraduatedOutcome(degradationResult)

     if outcome.class == "scope_reduction":
         effectiveScope = outcome.effective_scope
         if request.requiresScope NOT IN effectiveScope:
             return HTTP_403(authorizationDetails(outcome))
         else:
             return HTTP_200_WITH_REDUCED_SCOPE(effectiveScope,
                                                authorizationDetails(outcome))

     if outcome.class == "method_restriction":
         permittedMethods = outcome.permitted_methods
         if request.method NOT IN permittedMethods:
             return HTTP_405(allow=permittedMethods,
                             authorizationDetails(outcome))
         else:
             return HTTP_200_WITH_METHOD_RESTRICTION(
                             authorizationDetails(outcome))

     if outcome.class == "full_denial":
         return HTTP_403(authorizationDetails(outcome))

   Implementations MUST NOT cache introspection responses for tokens
   where APM is active, or MUST use a freshness window for cached
   responses shorter than the expected posture-change window.

5.  Wire Format

5.1.  authorization_details Object

   APM outcomes MUST be conveyed as typed authorization_details objects
   per [RFC9396].  The type value for APM Graduated Outcomes is:

   urn:apm:graduated-outcome:v1

   The following JSON Schema defines the APM outcome object:

   {
     "type": "urn:apm:graduated-outcome:v1",
     "class": "<scope_reduction | method_restriction | full_denial>",
     "original_scope": "<space-separated OAuth scope string>",
     "effective_scope": "<space-separated reduced scope string>",
     "permitted_methods": ["<HTTP method>"],
     "reason_code": "<implementation-defined string>",
     "apm_decision_id": "<opaque identifier>"
   }

Vicente                 Expires 30 December 2026                [Page 8]
Internet-Draft                  OAuth APM                      June 2026

   Field semantics:

+-----------------------+--------+----------+---------------------------+
| Field                 | Type   | Presence | Semantics                 |
+-----------------------+--------+----------+---------------------------+
| type                  | string | REQUIRED | Always                    |
|                       |        |          | urn:apm:graduated-outcome |
|                       |        |          | :v1                       |
+-----------------------+--------+----------+---------------------------+
| class                 | string | REQUIRED | One of scope_reduction,   |
|                       |        |          | method_restriction,       |
|                       |        |          | full_denial               |
+-----------------------+--------+----------+---------------------------+
| original_scope        | string | REQUIRED | Scope at token issuance   |
+-----------------------+--------+----------+---------------------------+
| effective_scope       | string | REQUIRED | Reduced scope; present    |
|                       |        | if class | only if class is          |
|                       |        | = scope_ | scope_reduction           |
|                       |        | reduction|                           |
+-----------------------+--------+----------+---------------------------+
| permitted_methods     | array  | REQUIRED | Permitted HTTP methods;   |
|                       |        | if class | present only if class is  |
|                       |        | = method | method_restriction        |
|                       |        | _restrict|                           |
+-----------------------+--------+----------+---------------------------+
| reason_code           | string | RECOM-   | Opaque code identifying   |
|                       |        | MENDED   | degradation category.     |
|                       |        |          | MUST NOT encode scoring   |
|                       |        |          | weights or thresholds.    |
+-----------------------+--------+----------+---------------------------+
| apm_decision_id       | string | RECOM-   | Opaque identifier for     |
|                       |        | MENDED   | audit-log correlation;    |
|                       |        |          | not interpretable by      |
|                       |        |          | the client.               |
+-----------------------+--------+----------+---------------------------+

   The reason_code field MUST NOT include decision-function parameters,
   scoring weights, thresholds, or posture metric values.  Acceptable
   enumerated codes include POSTURE_DEGRADED, ATTESTATION_CLASS_CHANGED,
   and CERT_THUMBPRINT_MISMATCH.

5.2.  WWW-Authenticate Challenge

   When a Graduated Outcome is accompanied by an invitation to re-
   authenticate (step-up per [RFC9470]), the resource server SHOULD
   return a WWW-Authenticate challenge:

   For Bearer-bound tokens:

Vicente                 Expires 30 December 2026                [Page 9]
Internet-Draft                  OAuth APM                      June 2026

WWW-Authenticate: Bearer
    error="insufficient_user_authentication",
    error_description="Device posture degraded; re-authentication required",
    acr_values="<acceptable ACR values>",
    scope="<scope hint for step-up>"

   For DPoP-bound tokens:

   WWW-Authenticate: DPoP
       error="insufficient_user_authentication",
       acr_values="<acceptable ACR values>"

5.3.  HTTP Status Mapping

+--------------------+-------------------+-----------------------------+
| APM Outcome Class  | HTTP Status       | Rationale                   |
+--------------------+-------------------+-----------------------------+
| scope_reduction    | 200 OK or         | If effective_scope permits  |
|                    | 403 Forbidden     | the resource, 200 with      |
|                    |                   | reduced scope. If not, 403. |
+--------------------+-------------------+-----------------------------+
| method_restriction | 405 Method Not    | Allow header SHOULD list    |
|                    | Allowed           | permitted_methods.          |
+--------------------+-------------------+-----------------------------+
| full_denial        | 403 Forbidden     | Explicit denial regardless  |
|                    |                   | of token validity.          |
+--------------------+-------------------+-----------------------------+
| Step-up invitation | 401 Unauthorized  | When re-authentication at   |
|                    | with WWW-         | higher assurance would      |
|                    | Authenticate      | restore access.             |
+--------------------+-------------------+-----------------------------+

6.  Posture-Signal Abstraction

   APM treats the posture signal as an opaque, integrity-protected
   input.  The specific attestation format, measurement protocol, and
   trust chain for the posture signal are outside the scope of this
   document.

   An APM Enforcement Point MUST require that: (1) the posture signal is
   integrity-protected (signed or MAC'd by a trusted posture authority);
   (2) the posture signal includes an iat (issued-at) claim for
   freshness evaluation; (3) the posture signal includes a subject
   identifier binding it to the device or client instance; (4) the
   posture signal SHOULD include a unique identifier (jti) for replay
   detection.

Vicente                 Expires 30 December 2026               [Page 10]
Internet-Draft                  OAuth APM                      June 2026

   While not mandating a specific format, this document recommends the
   following JWT shape for implementations requiring an interoperable
   baseline:

   {
     "iss": "https://posture.example.com",
     "sub": "device-12345",
     "iat": 1735689600,
     "jti": "4f9a2b1c-e8d7-4a3b-9c2e-1d0f8a7b6c5d",
     "posture": {
       "attestation_class": "hardware_tpm",
       "device_compliance": "compliant",
       "last_attestation_iat": 1735689590,
       "binding_cert_thumbprint_s256": "OKy4RNzHvwY..."
     }
   }

   This schema MUST NOT include scoring weights, risk-band thresholds,
   or decision budgets.  The fields above expose only the observable
   posture properties.  The attestation_class field is an
   implementation-defined string (e.g., hardware_tpm, software_tee,
   none); ordering and thresholds are implementation-defined and out of
   scope.

7.  Interaction Matrix

   The following table describes how APM relates to each relevant
   protocol:

Vicente                 Expires 30 December 2026               [Page 11]
Internet-Draft                  OAuth APM                      June 2026

+----------------------------------+--------------------------------------+
| Mechanism                        | Relationship and What APM Adds       |
+----------------------------------+--------------------------------------+
| RFC 8705 mTLS Certificate-Bound  | APM consistency view includes the    |
| Tokens                           | mTLS cert thumbprint check (Step 2). |
|                                  | APM re-verifies per privileged       |
|                                  | request; RFC 8705 binds at issuance. |
+----------------------------------+--------------------------------------+
| RFC 9449 DPoP                    | APM consistency view includes DPoP   |
|                                  | proof validation (Step 3). APM       |
|                                  | re-verifies per request.             |
+----------------------------------+--------------------------------------+
| RFC 9470 Step-Up Authentication  | APM MAY trigger step-up by returning |
|                                  | 401 + WWW-Authenticate with          |
|                                  | acr_values. RFC 9470 defines the     |
|                                  | challenge; APM decides when to use   |
|                                  | it based on posture evaluation.      |
+----------------------------------+--------------------------------------+
| RFC 9396 Rich Authorization      | APM graduated outcomes are conveyed  |
| Requests                         | as urn:apm:graduated-outcome:v1      |
|                                  | authorization_details objects.       |
+----------------------------------+--------------------------------------+
| RFC 7662 Token Introspection     | Orthogonal. Introspection determines |
|                                  | token validity; APM determines       |
|                                  | posture consistency within the       |
|                                  | valid-token window. APM is layered   |
|                                  | on top of introspection.             |
+----------------------------------+--------------------------------------+
| draft-ietf-oauth-attestation-    | Orthogonal. Attestation-based client |
| based-client-auth                | auth operates at authentication time.|
|                                  | APM extends attestation into per-    |
|                                  | request enforcement throughout the   |
|                                  | token lifetime.                      |
+----------------------------------+--------------------------------------+
| OpenID CAEP 1.0                  | Composable. CAEP provides async      |
|                                  | event-push; APM provides synchronous |
|                                  | per-request enforcement. CAEP events |
|                                  | can feed APM's posture-state cache.  |
|                                  | CAEP SETs MUST be signed and         |
|                                  | verified against a trusted-issuer    |
|                                  | allowlist before use as posture      |
|                                  | inputs.                              |
+----------------------------------+--------------------------------------+

   The RECOMMENDED layering for deployments that combine all mechanisms
   is: Layer A (token validity) per [RFC7662]; Layer B-core (cert
   binding) per [RFC8705]; Layer C (DPoP) per [RFC9449] where
   applicable; Layer D (APM consistency) per this document.

Vicente                 Expires 30 December 2026               [Page 12]
Internet-Draft                  OAuth APM                      June 2026

8.  Relationship to Prior Art

   The following table enumerates gaps in existing mechanisms and how
   APM addresses each.

+---------------------------+------------------------------+---------------------------+
| Prior art                 | Gap                          | How APM addresses it      |
+---------------------------+------------------------------+---------------------------+
| RFC 8705 mTLS cert-bound  | Proves key possession at     | APM adds per-request      |
| tokens                    | issuance; does not re-check  | cert-thumbprint check     |
| (https://www.rfc-editor   | cert validity, revocation,   | (Step 2) and per-request  |
| .org/rfc/rfc8705)         | or device posture per        | posture evaluation        |
|                           | request (RFC 8705 §6.5).     | (Steps 4-5).              |
+---------------------------+------------------------------+---------------------------+
| RFC 9449 DPoP             | Proves key possession and    | APM extends DPoP          |
| (https://www.rfc-editor   | method/URI binding per       | per-request enforcement   |
| .org/rfc/rfc9449)         | request; does not evaluate   | to include device-posture |
|                           | device posture               | consistency evaluation.   |
|                           | (RFC 9449 §11.7, §11.11).    |                           |
+---------------------------+------------------------------+---------------------------+
| RFC 9470 Step-Up          | Reactive, fires on           | APM produces graduated    |
| Authentication            | authentication failures;     | outcomes (scope_reduction,|
| (https://www.rfc-editor   | outcome is binary (re-auth   | method_restriction) for   |
| .org/rfc/rfc9470)         | or deny); no device posture. | minor degradations rather |
|                           |                              | than binary deny.         |
+---------------------------+------------------------------+---------------------------+
| RFC 9396 Rich             | Fine-grained initial grants  | APM applies post-issuance |
| Authorization Requests    | are static for the token     | narrowing of effective    |
| (https://www.rfc-editor   | lifetime; no post-issuance   | scope and methods via     |
| .org/rfc/rfc9396)         | narrowing on posture change  | Graduated Outcomes.       |
|                           | (RFC 9396 §5.3).             |                           |
+---------------------------+------------------------------+---------------------------+
| OpenID CAEP 1.0           | Asynchronous event push;     | APM provides synchronous  |
| (https://openid.net/specs | temporal gap between event   | per-request enforcement;  |
| /openid-caep-1_0-final    | and enforcement; binary      | CAEP events MAY feed      |
| .html)                    | compliance vocabulary; no    | APM's posture-state cache |
|                           | per-request posture check.   | (composable).             |
+---------------------------+------------------------------+---------------------------+
| draft-ietf-oauth-         | Attestation operates at      | APM extends attestation   |
| attestation-based-client- | authentication time; no      | into per-request          |
| auth                      | normative mechanism to force | enforcement throughout    |
| (https://datatracker.ietf | re-attestation on posture    | the token lifetime.       |
| .org/doc/draft-ietf-oauth | degradation within a JWT's   |                           |
| -attestation-based-client | validity window.             |                           |
| -auth/)                   |                              |                           |
+---------------------------+------------------------------+---------------------------+

Vicente                 Expires 30 December 2026               [Page 13]
Internet-Draft                  OAuth APM                      June 2026

9.  Security Considerations

   APM is a defense-in-depth mechanism and MUST NOT weaken any binding
   defined by [RFC8705] or [RFC9449].  The posture signal is an input to
   an authorization decision and MUST be integrity-protected; an APM
   Enforcement Point MUST NOT base a Graduated Outcome on an
   unauthenticated posture signal.  Specific tuning parameters used by
   implementations of this mechanism are out of scope of this document;
   see the Applicability section of the corresponding Sanctum SecOps
   publication.

9.1.  Replay of Stale Posture Signals

   A posture signal valid at token-issuance time may be captured and
   replayed by an adversary to make the resource server believe posture
   has not degraded.  Mitigations: (1) the posture signal MUST include
   an iat claim; the APM Enforcement Point SHOULD reject signals with an
   iat older than an implementation-defined freshness window; (2) the
   resource server MAY include a server-generated nonce in a challenge,
   providing challenge- response-based replay protection; (3) if the
   posture signal is bound to the access token via the same DPoP key
   [RFC9449], replaying it under a different token requires breaking the
   binding.  The formal model for replay resistance in authenticated
   protocols is established in [BellareRogaway].

9.2.  Downgrade-Forcing Attacks

   An adversary who can manipulate the posture-signal channel can inject
   a degraded posture signal to obtain a downgraded token -- for
   example, obtaining a scoped-down token that avoids audit scrutiny, or
   triggering a method_restriction outcome that permits read access
   without the write- access audit trail.  Mitigations: (1) the posture
   signal MUST be integrity- protected; (2) policy authors SHOULD design
   graduated outcomes so that every downgrade path leads to a safe,
   self-consistent authorization state; an operation that is only safe
   at full authorization SHOULD map to full_denial rather than
   scope_reduction when posture degrades.

9.3.  Confused-Deputy Under Graduated Downgrade

   The confused-deputy problem arises in APM when a partially-authorized
   (downgraded) request is processed by a resource server that believes
   it is acting on behalf of a fully-authorized principal.  Each
   Graduated Outcome MUST correspond to a complete access control
   policy, not a partial policy derived by removing permissions from the
   full policy.  Policy authors MUST audit every graduated outcome in
   isolation, not only relative to the full-authorization policy.

Vicente                 Expires 30 December 2026               [Page 14]
Internet-Draft                  OAuth APM                      June 2026

9.4.  Side-Channel Leakage of Device State

   Because APM re-evaluates posture on every privileged request, the
   resource server observes the posture signal at high frequency.
   Implementations MUST NOT return different response codes or timing
   based solely on posture quality in a way that leaks posture details
   not already visible from the authorization outcome.  APM SHOULD be
   applied only to operations designated as privileged.  The principle
   that authenticated key exchange security requires binding identities
   to session keys via signatures and MACs together ([Krawczyk2003]) is
   analogous to APM's multi-factor consistency check; the same binding-
   integrity properties SHOULD be maintained throughout the APM
   enforcement path.

   The remaining threat considerations (compromise of the posture-signal
   channel, DPoP and mTLS binding compromise, CAEP signal injection) are
   addressed by the posture-signal integrity requirements in Section 4,
   the trusted-issuer allowlist requirement for CAEP inputs in
   Section 7, and the independence requirement that the posture signal
   used by APM SHOULD be a direct attestation from the device itself,
   not solely derived from CAEP events.

10.  Implementation Status

   This section records the status of known implementations of the
   protocol defined by this specification at the time of posting, as
   required by [RFC7942].

   Organization: Sanctum SecOps LLC

   Description: An experimental Go implementation of the APM Consistency
   View assembly and graduated-outcome dispatch, covering the
   certificate-thumbprint check (Step 2), DPoP-key-binding check (Step
   3), and graduated-outcome application for all three outcome classes
   defined in Section 4.  The wire format encoding of
   authorization_details per Section 5 and the WWW-Authenticate
   challenge format per [RFC9470] are implemented.  Located at poc/apm/
   in the companion repository at https://github.com/Sanc-Admin/sanctum-
   ietf (private until counsel hand-off).

   Coverage: Consistency View assembly and all five steps of the
   algorithm in Section 4, wire-format encoding of APM outcome objects,
   and HTTP status code mapping per Section 5.

   Maturity: Experimental reference implementation.  This implementation
   is provided for early interoperability testing only and MUST NOT be
   deployed in production or used for security-critical operations
   without review by qualified security and legal counsel.

Vicente                 Expires 30 December 2026               [Page 15]
Internet-Draft                  OAuth APM                      June 2026

11.  IANA Considerations

11.1.  authorization_details Type Registration

   IANA is requested to register the following authorization_details
   type in the OAuth Authorization Details Types registry established by
   [RFC9396]:

Type name:    urn:apm:graduated-outcome:v1
Change controller: IETF
Specification document: This document (TBD2)
Description: APM graduated-outcome object conveying the outcome class,
             effective scope, permitted methods, and audit correlation
             identifier for a per-request posture consistency evaluation.

   The value TBD2 is a placeholder to be assigned upon RFC publication.
   For early interoperability, implementations MAY use the type string
   urn:apm:graduated-outcome:v1 directly; this string is stable and does
   not depend on the IANA OID arc.  The publicly registered Sanctum
   SecOps PEN (1.3.6.1.4.1.65953) is used for any experimental OID-based
   identifiers and MUST NOT be relied upon as a permanent registration.

12.  References

13.  References

13.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC6749]  Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
              RFC 6749, DOI 10.17487/RFC6749, October 2012,
              <https://www.rfc-editor.org/rfc/rfc6749>.

   [RFC7942]  Sheffer, Y. and A. Farrel, "Improving Awareness of Running
              Code: The Implementation Status Section", BCP 205,
              RFC 7942, DOI 10.17487/RFC7942, July 2016,
              <https://www.rfc-editor.org/rfc/rfc7942>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.

Vicente                 Expires 30 December 2026               [Page 16]
Internet-Draft                  OAuth APM                      June 2026

   [RFC8705]  Campbell, B., Bradley, J., Sakimura, N., and T.
              Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication
              and Certificate-Bound Access Tokens", RFC 8705,
              DOI 10.17487/RFC8705, February 2020,
              <https://www.rfc-editor.org/rfc/rfc8705>.

   [RFC9396]  Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0
              Rich Authorization Requests", RFC 9396,
              DOI 10.17487/RFC9396, May 2023,
              <https://www.rfc-editor.org/rfc/rfc9396>.

   [RFC9449]  Fett, D., Campbell, B., Bradley, J., Lodderstedt, T.,
              Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of
              Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449,
              September 2023, <https://www.rfc-editor.org/rfc/rfc9449>.

   [RFC9470]  Bertocci, V. and B. Campbell, "OAuth 2.0 Step Up
              Authentication Challenge Protocol", RFC 9470,
              DOI 10.17487/RFC9470, September 2023,
              <https://www.rfc-editor.org/rfc/rfc9470>.

13.2.  Informative References

   [BellareRogaway]
              Bellare, M. and P. Rogaway, "Entity Authentication and Key
              Distribution", Advances in Cryptology -- CRYPTO 1993 LNCS
              773, 1993,
              <https://cseweb.ucsd.edu/~mihir/papers/eakd.pdf>.

   [CAEP]     "OpenID Continuous Access Evaluation Profile (CAEP) 1.0",
              2025,
              <https://openid.net/specs/openid-caep-1_0-final.html>.

   [I-D.ietf-oauth-attestation-based-client-auth]
              Looker, T., Bastian, P., and C. Bormann, "OAuth 2.0
              Attestation-Based Client Authentication", Work in
              Progress, Internet-Draft, draft-ietf-oauth-attestation-
              based-client-auth-09, 25 May 2026,
              <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-
              attestation-based-client-auth-09>.

   [Krawczyk2003]
              Krawczyk, H., "SIGMA: The SIGn-and-MAc Approach to
              Authenticated Diffie-Hellman and Its Use in the IKE
              Protocols", Advances in Cryptology -- CRYPTO 2003 LNCS
              2729, 2003, <https://www.iacr.org/archive/
              crypto2003/27290399/27290399.pdf>.

Vicente                 Expires 30 December 2026               [Page 17]
Internet-Draft                  OAuth APM                      June 2026

   [NIST.SP.800-207]
              National Institute of Standards and Technology, "Zero
              Trust Architecture", NIST Special Publication 800-207,
              August 2020,
              <https://csrc.nist.gov/pubs/sp/800/207/final>.

   [RFC7662]  Richer, J., Ed., "OAuth 2.0 Token Introspection",
              RFC 7662, DOI 10.17487/RFC7662, October 2015,
              <https://www.rfc-editor.org/rfc/rfc7662>.

Appendix A.  Worked Example: Compliance Downgrade -- scope_reduction
             Outcome

   All JWT and certificate thumbprints are synthetic.  No real
   credentials are used.

   Context: Device compliance has dropped (MDM reports a policy
   violation).  Current posture has device_compliance = non_compliant
   while the Issuance Posture had compliant.

   Current posture signal JWT payload (synthetic):

   {
     "iss": "https://posture.example.com",
     "sub": "device-12345",
     "iat": 1735689700,
     "jti": "9e8d7c6b-5a4f-3e2d-1c0b-9a8f7e6d5c4b",
     "posture": {
       "attestation_class": "hardware_tpm",
       "device_compliance": "non_compliant",
       "last_attestation_iat": 1735689690
     }
   }

   APM Consistency View evaluation:

   Step 2: cert.thumbprint matches token cnf -- PASS
   Step 3: DPoP not bound -- SKIP
   Step 4: issuancePosture.device_compliance = compliant
           currentPosture.device_compliance  = non_compliant -- DEGRADED
   Step 5: DispatchGraduatedOutcome -> scope_reduction
           effective_scope = "read" (admin and write removed)

   Response (resource requires write scope, not in effective_scope):

Vicente                 Expires 30 December 2026               [Page 18]
Internet-Draft                  OAuth APM                      June 2026

HTTP/1.1 403 Forbidden
Content-Type: application/json
WWW-Authenticate: Bearer
    error="insufficient_user_authentication",
    acr_values="urn:example:acr:high-assurance",
    scope="read write"

{
  "error": "insufficient_scope",
  "error_description": "Device posture degraded; authorization reduced",
  "authorization_details": [{
    "type": "urn:apm:graduated-outcome:v1",
    "class": "scope_reduction",
    "original_scope": "read write admin",
    "effective_scope": "read",
    "reason_code": "DEVICE_COMPLIANCE_CHANGED",
    "apm_decision_id": "apm-7f3c2b1a-0d9e-4c8b-a2f1-3d4e5f6a7b8c"
  }]
}

   The client MUST obtain a new token after re-establishing device
   posture at the required compliance level before accessing write-
   scoped resources.

Appendix B.  Appendix B.  Mapping to NIST SP 800-207 Zero Trust
             Architecture

   NIST SP 800-207 [NIST.SP.800-207] defines a three-component decision
   plane for Zero Trust Architecture.  APM maps to this architecture as
   follows:

Vicente                 Expires 30 December 2026               [Page 19]
Internet-Draft                  OAuth APM                      June 2026

+---------------------+------------------------------------------------+
| ZTA Component       | APM Role                                       |
+---------------------+------------------------------------------------+
| Policy Enforcement  | The APM Enforcement Point (resource server or  |
| Point (PEP)         | co-located component). Assembles the           |
|                     | Consistency View (REQ-1), executes sender-      |
|                     | constraint verification (Steps 2-3), and        |
|                     | enforces the Graduated Outcome. Corresponds     |
|                     | to NIST SP 800-207 Section 3 PEP.              |
+---------------------+------------------------------------------------+
| Policy Engine (PE)  | Consumes the Consistency View and Issuance     |
|                     | Posture and produces an outcome class. May be  |
|                     | co-located with the PEP or queried per-request.|
|                     | Implements the deterministic outcome mapping   |
|                     | required by REQ-7.                             |
+---------------------+------------------------------------------------+
| Policy              | Communicates scope-reduction and method-        |
| Administrator (PA)  | restriction policy from the authorization      |
|                     | server to the PEP. Also records the Issuance   |
|                     | Posture at token issuance time (REQ-2).        |
+---------------------+------------------------------------------------+

   APM does not introduce new architectural roles beyond those defined
   in [NIST.SP.800-207].  It specifies the information flows --
   specifically, the Consistency View and Issuance Posture -- that
   enable the PE to make the per-request graduated-outcome decisions
   that ZTA requires.

   Informative reference: [NIST.SP.800-207].

Acknowledgments

   The author thanks the OAuth Working Group for the certificate-
   binding, proof-of-possession, and step-up foundations on which this
   mechanism builds.

Author's Address

   Brian Vicente
   Sanctum SecOps LLC
   Email: brian@sanctumsecops.io

Vicente                 Expires 30 December 2026               [Page 20]