Repository navigation
ARAP: signed approval state has no interoperable payload #659
Description
Problem
The Interoperability Baseline requires every PDP to support verifying an approval.state presented as a JWS, but no claim set is defined. Two implementations can both conform to that requirement and share no payload, so the portable bound-reference flow the profile describes is not reachable without a bilateral agreement.
The two binding boundaries are not symmetric. The denial side specifies issuer, audience, expiry, replay, the authorization-relevant Context member set, and an inline-or-hash representation of the bound tuple. The approval side specifies iss, aud, key discovery, and an unnamed equivalent of binding_context_members, while Approval Verification requires the PDP to determine the approval identifier, the task identifier, the original evaluation identifier, the approved Subject, Resource and Action or scope, requester and client binding, status, approval times, and revocation state.
Three further questions depend on the same claim set.
Approval scope has no portable representation. Exact-match scope is the stated interoperability baseline, yet the signed form carries no standardized representation of the approved tuple, so exact match works naturally only where the PDP can look the approval up in trusted state.
approved_until conflates two lifetimes. It is REQUIRED, and it is read as both the validity of the approval evidence and the lifetime of the authority the approval established. An approval that provisions a durable entitlement has no natural value for it.
Current-status checking is unsatisfiable for a self-contained artifact. The PDP MUST check whether an approval was revoked, cancelled, or superseded before approved_until. A signed artifact proves what was true when it was signed. It cannot prove that nothing has changed since. As written, the rule cannot be met in the topology that signed approval state exists to serve.
Recommendation
Define an Approval State JWT, structurally parallel to the denial binding claims: iss, aud, iat, exp, jti, approval_id, task_id, evaluation_id when available, the approved subject, resource and action or approval_scope, binding_context_members, and requester and client binding.
Carry the approved tuple inline or as a hash, using the same canonical construction as denial binding. Denial binding then proves the tuple that may be requested and approval binding proves the tuple that was approved, and exact-match scope becomes portable without a lookup.
State that approved_until bounds use of the Approval Result, not the lifetime of the authority the approval established. Renaming it is a wire change and should travel with the claim set if the group wants one.
Replace the single current-status rule with three validity models:
- Lookup approval,
approval.idresolved in trusted state: current status can be checked, so revocation, cancellation, and supersession MUST be enforced. - Signed approval with an online status source: current status can be checked and MUST be.
- Self-contained signed approval: the artifact is valid through its protected expiry unless current PDP policy independently denies. Early revocation requires a profile-defined status or revocation mechanism.
Considered and rejected
A refreshed-proof design, in which a status resource keyed by the approval identifier reissues approval.state to an authorized PEP while the approval remains active. It fails on availability: refreshing at enforcement time makes the service a dependency of already-granted access, and the profile's fail-closed guidance then turns a service outage into fleet-wide revocation. It also requires the PEP to read an expiry it is forbidden to parse, and a distinct denial reason code.
Related
Five independent reviews of the restructured draft named this the largest remaining interoperability hole.
Whatever is decided here must be checked against the AuthZEN Access Request OAuth Profile, which places the PEP and PDP roles in three ways: an authorization server evaluating and deferring its own token request, a protected resource asserting the denial as a signed challenge, or both acting as PEP.
Once the claim set settles, the illustrative tokens need correcting. The approval.state in the base draft decodes to an approval identifier alone, with none of the iss, aud, or exp that the text requires or that verification depends on, and the one in the callback profile expires thirty minutes before its own approved_until, which is the lifetime question above shown by example. That is an editor task, not a decision for this issue.
Activity
ARAP register version 22: the seven core issues are filed
ARAP: retire the gaps registers
aeoess commentedon Sep 22, 2026
The three validity models look right to me. One thing the online-status model needs, which is also where the rejected refresh design went wrong: status results should be three-valued, not two. When the status source is unreachable, the answer is unknown, not revoked. A PDP can still deny on unknown, but with its own reason code, so an outage stays an outage in audit and retry handling and is never recorded as a revocation of granted access.
I've been testing this exact split in an open delegation-revocation implementation:
activeonly with positive current-state evidence,revokedonly with a verified revocation record, andunknownotherwise. The verifier treatsunknownas indeterminate rather than valid. I also have deterministic negative vectors around this if a concrete status-model case would be useful.Require issuance support for a claimed binding capability