Internet-Draft OAuth APM June 2026
Vicente Expires 7 December 2026 [Page]
Workgroup:
OAUTH
Internet-Draft:
draft-vicente-oauth-apm-01
Published:
Intended Status:
Standards Track
Expires:
Author:
B. Vicente
Sanctum SecOps LLC

Authorization Posture Mechanism (APM): Per-Transaction Consistency for OAuth 2.0

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 7 December 2026.

Table of Contents

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

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:

         +----------------------+
         |   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:

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)

  # 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>"
}

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:

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.

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:

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

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/)                   |                              |                           |
+---------------------------+------------------------------+---------------------------+

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.

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.

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, , <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>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, , <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, , <https://www.rfc-editor.org/rfc/rfc8174>.
[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, , <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, , <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, , <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, , <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, , <https://cseweb.ucsd.edu/~mihir/papers/eakd.pdf>.
[CAEP]
"OpenID Continuous Access Evaluation Profile (CAEP) 1.0", , <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, , <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, , <https://www.iacr.org/archive/crypto2003/27290399/27290399.pdf>.
[NIST.SP.800-207]
National Institute of Standards and Technology, "Zero Trust Architecture", NIST Special Publication 800-207, , <https://csrc.nist.gov/pubs/sp/800/207/final>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <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):

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:

+---------------------+------------------------------------------------+
| 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