Authorization Posture Mechanism (APM): Per-Transaction Consistency for OAuth 2.0
draft-vicente-oauth-apm-02
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| 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]