| Internet-Draft | OASNT-ENFORCE | August 2026 |
| Thallapelly | Expires 2 February 2027 | [Page] |
This document profiles the enforcement of OASNT tokens at the point of execution. It defines the OASNT-Token HTTP field, the rules by which an enforcement point derives the observed request from the octets it will itself forward, a verification procedure for relying parties that hold no request-to-action mapping, uniform refusal behavior, and the set of refusals a conforming enforcement point is required to produce. An enforcement point conforming to this profile makes a human approval a precondition of execution for the requests it fronts, without any change to the protected service.¶
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 2 February 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
[I-D.thallapelly-oasnt] (hereafter "the core document") defines a token
in which a hardware-bound device key attests that a specific human
authorized one specific action, optionally bound to one concrete HTTP
request through the rqf claim. The core document also states where such
a token counts: at the party that verifies it against the request it is
about to perform.¶
This document specifies that party. Without it, the token gates only a cooperating caller: an agent may obtain a token for one request and issue another, or issue a request with no token at all, and nothing positioned at the transport observes the difference. An enforcement point conforming to this profile closes that gap for every request it fronts, and does so without modifying the protected service, which continues to receive ordinary HTTP.¶
The profile deliberately specifies behavior, not placement. A conforming enforcement point is typically a reverse proxy in front of an unmodified origin, but the same rules apply to an in-process interceptor inside the service itself.¶
This profile is written from a running implementation, whose adversarial corpus exercises every refusal Section 8 lists.¶
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 core document" refers to [I-D.thallapelly-oasnt]. The claim names
adg, dsp, rqf, and jti, and the terms "canonical action" and
"request fingerprint", have the meanings the core document gives them.¶
Enforcement point: the party that verifies a token against the request it is itself about to perform or forward.¶
Presenter: the party transmitting the request and token to the enforcement point. The presenter is untrusted.¶
Observed request: the request as the enforcement point will actually execute it, derived under Section 4. Never anything the presenter asserts about the request.¶
Upstream: the protected service the enforcement point fronts.¶
The token travels in a dedicated HTTP field:¶
OASNT-Token = b64part "." b64part "." b64part b64part = 1*base64url-char base64url-char = ALPHA / DIGIT / "-" / "_"¶
The value is the compact JWS serialization the core document defines, unmodified; the segment alphabet is the URL-safe alphabet of [RFC4648] without padding.¶
A dedicated field is used rather than the Authorization field of [RFC9110] because the upstream commonly consumes Authorization for its own credential, and this profile's promise is that the upstream changes nothing. The enforcement point removes the OASNT-Token field before forwarding (Section 7), so the two never collide.¶
A request MUST carry at most one OASNT-Token field with a single value. A
request carrying more than one, or a value that does not match the syntax
above, MUST be refused. A request carrying none MUST be refused
(no-token); there is no anonymous path through an enforcement point.¶
The observed request is derived exclusively from what the enforcement point will itself execute:¶
Method and target: the method and request target the enforcement point will use upstream, as octets. These are the same octets it received, but their authority comes from the enforcement point's intent to forward them, not from the presenter having sent them.¶
Tenant and privilege: the orgId and scope inputs to the request
fingerprint are not inferable from HTTP. Configuration MUST bind them to
request targets. A target no configuration entry names MUST be refused
(no-route): a target nobody declared is not an open path.
Misconfiguration is fail-closed by construction, because a wrong tenant
or privilege recomputes to a different fingerprint and refuses as a
mismatch.¶
Body: the enforcement point MUST buffer the body it will forward, up to a configured cap, and compute the body digest over exactly those raw octets. A body exceeding the cap MUST be refused and MUST NOT be forwarded unverified. There is no compliant configuration in which oversized requests bypass verification.¶
The request fingerprint is then recomputed from these observed values as the core document specifies. Nothing the presenter declares participates in the derivation at any point.¶
An enforcement point MUST apply the core document's verification
procedure to the presented token, with the observed request of
Section 4 as the expected request. Because an enforcement point
always authorizes a concrete request, the core document's request-binding
rule applies in full: a token without rqf MUST be refused, and absence
is never a downgrade.¶
The core verification procedure recomputes the action and display digests from the relying party's own representation of the action. An enforcement point positioned at the transport typically holds no request-to-action mapping and cannot form that representation. This profile therefore defines the following modification, and only this modification:¶
In place of the action-binding and intent-binding recomputation steps, an
enforcement point that holds no request-to-action mapping MUST require
adg and dsp to be present as non-empty strings covered by the
verified signature. Every other step of the core procedure applies
unchanged.¶
The result is transport-bound verification: the token is proven to originate from the enrolled key, to be fresh, unconsumed, and bound to exactly the observed request, while the action and display digests are carried at signature strength rather than recomputed. A deployment that requires action recomputation places it at a party that holds the mapping, such as an executor-side processing model in the style of [I-D.schrock-action-evidence-boundary] performing identifier matching under [I-D.thallapelly-oasnt-caid]; matching there restores recomputation strength to the carried digests. An enforcement point MUST NOT represent transport-bound verification as full verification.¶
The consumed-jti set is scoped to the enforcement deployment that
maintains it, consistent with the core document's scoping of nonce
consumption. Coordinating consumption across deployments or trust domains
is out of scope here, as it is there.¶
On the wire, every refusal MUST be indistinguishable from every other: the same status code and an identical body, carrying no indication of which check failed. The distinct refusal cause MUST be available to the operator, and MUST NOT be available to the presenter. Refusal causes reveal enrollment state and nonce state, which is reconnaissance an untrusted presenter is not owed.¶
A failure of the upstream after an allow decision is an availability outcome, not an authorization outcome. It MUST be distinguishable from a refusal (for example, 502 rather than 403) and MUST NOT be folded into the uniform refusal, because masking availability as refusal corrupts the operator's signal in both directions.¶
Only a request whose token passed verification in full is forwarded, and what is forwarded is exactly the observed octets the fingerprint was computed over: same method, same target, same body. The OASNT-Token field MUST be removed before forwarding; every other field is passed through unmodified.¶
Because the fingerprinted octets and the forwarded octets are the same buffer, there is no window at this hop between what was verified and what executes. What the upstream does beyond those octets, such as dereferencing an identifier the body names, is outside the binding and belongs to the action layer.¶
A conforming enforcement point MUST refuse, without forwarding, in each of the following situations. The labels are descriptive, for operator logs; nothing on the wire distinguishes them (Section 6).¶
| Situation | Label |
|---|---|
| body altered relative to the fingerprinted request |
rqf-mismatch
|
| target altered relative to the fingerprinted request |
rqf-mismatch
|
| token already consumed by a previously executed request |
replay
|
| no token presented |
no-token
|
| tenant or privilege configuration disagrees with the binding |
rqf-mismatch
|
| body exceeding the configured cap |
body-too-large
|
| target named by no configuration entry |
no-route
|
| more than one OASNT-Token field, or a syntactically invalid one |
no-token
|
The reference implementation exercises each of these against a live enforcement point over HTTP, together with a check that all refusal responses are octet-identical on the wire; see Appendix A.¶
An enforcement point protects exactly the requests that pass through it. A service reachable around it is not protected, and no property of this profile survives such a path. Deployments MUST ensure the upstream accepts requests only from its enforcement point, by network isolation, mutual authentication, or equivalent means. With that condition in place, skipping the authorization ceremony is not a bypass; it is the refused path.¶
Section 5.1 trades action recomputation for deployability at the
transport. The carried adg and dsp are exactly as strong as the
signature over them: they prove what the device signed, not what the
upstream will do. The composition intended by this profile is that
recomputation happens where the mapping lives, at the approval broker
that derives the display from the request, and at the executor that
matches identifiers per [I-D.thallapelly-oasnt-caid]. An enforcement point is one layer
of that composition, not the whole of it.¶
The core document's limits pass through unchanged. A compromised device may still assert a clean integrity verdict. A valid display digest proves which octets were shown, not that they were understood. Nothing in this profile strengthens either claim.¶
Refusing oversized bodies is the fail-closed arm of a real trade: it makes the enforcement point a hard dependency for large uploads. The alternative, forwarding unverified above a threshold, silently exempts the largest requests from the strongest control, which is the wrong shape for a security boundary. Deployments with large-body endpoints SHOULD raise the cap for those targets explicitly rather than exempt them.¶
Refusal causes are operator-only (Section 6) precisely because they reveal enrollment and nonce state. The log that carries them SHOULD be protected as security telemetry, and log entries need carry no token material beyond the cause label.¶
IANA is requested to register the following entry in the "Hypertext Transfer Protocol (HTTP) Field Name Registry" defined by [RFC9110]:¶
This section records the implementation this profile was written from; it is not a conformance statement.¶
A reverse-proxy enforcement point and its verification core exist and run in front of an unmodified HTTP origin. The verification core delegates every cryptographic decision to the same verifier the core document's test vectors were generated from. An adversarial corpus drives a live enforcement point over real HTTP through every situation Section 8 lists, asserting each is refused, that nothing refused reaches the upstream, and that all refusal responses are octet-identical on the wire. The corpus and the list are cross-checked mechanically, so a refusal cannot be documented without being exercised or exercised without being documented.¶
The executor-side framing that this profile composes with, in particular the discussion of admissibility conditions on the WIMSE mailing list, sharpened the boundary between transport-bound and action-recomputed verification.¶