| Internet-Draft | Agent Contestability Bindings | August 2026 |
| Pinto | Expires 2 March 2027 | [Page] |
Authorization artifacts can provide signed evidence of a permission under specified authorization rules. Receipts can record a signed claim or protocol event that the authorization was exercised, and outcome evidence can describe what followed. None of those artifacts necessarily tells a person or organization affected by the action where the authorization can be contested, which procedure applies, whether a filing changes execution state, or who selected the contestation forum.¶
This document defines a transport-independent Contestability Binding for authorized agent actions. The binding commits an authorization to a versioned Contestation Parameters Object that identifies the forum, submission mechanism, Standing Policy, procedure, time bounds, declared effect policy, and selection evidence. A forum can acknowledge one exact authorization or publish a reusable acceptance manifest for closed Authorization Binding Profile and Authorization Trust Profile digest pairs. A deterministic verifier validates the binding, separately classifies evidence claiming pre-execution verification by the executor, and reports forum-selection provenance as unilateral, multiparty, externally selected, or indeterminate. Where a filing is declared to affect execution state, the verifier also separates the issuer's declared policy, the executor's signed acceptance, the authenticated trigger, and the executor's claimed application.¶
The mechanism makes the bound contestation parameters identifiable and verifiable, supporting discoverability while resisting post-action substitution. It does not determine standing, prove forum independence, resolve a dispute, select a remedy, establish legal enforceability, or decide whether the original authorization was legitimate.¶
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 March 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.¶
Agent authorization can be action-bound, time-bounded, signed, logged, and receipted. That improves the answer to one question:¶
Was this action authorized under the selected rules?¶
It does not answer a different question:¶
If this authorization produces a contested consequence, before whom can the authorization or its use be challenged, under which procedure, and who chose that forum?¶
A URI labelled challenge_forum is not sufficient. If the authorization issuer can name, replace, or differently present the forum to each audience, the path exists syntactically while remaining captured operationally. A bound field can evidence that a contestation locator was declared in the artifact; it cannot by itself prove delivery or independence.¶
This document therefore separates three properties:¶
Binding: the contestation parameters are cryptographically committed to the exact authorization; pre-execution presentation and ordering are reported separately.¶
Discoverability: a verifier can identify the bound forum, procedure, Standing Policy, deadlines, and submission references.¶
Selection provenance: authenticated evidence and local trust inputs support classification of the forum selection as issuer-only, multiparty, externally selected, or indeterminate.¶
The verifier never returns independent. Independence is a governance and trust conclusion. It returns evidence about how selection occurred.¶
Section 6.2 defines the authoritative structured-result contract. Given the same Authorization Artifact, action, CPO, verification time, selected profiles, and trust inputs, conforming implementations are expected to agree on every field that those inputs make deterministically derivable. The following abstract-protocol example illustrates one complete result:¶
{
"binding": "valid",
"pre_execution_evidence": "executor_attested",
"discoverability": "complete",
"forum_acknowledgement": "valid_class",
"forum_operational_status": "not_checked",
"selection_provenance": "unilateral",
"access_binding": "valid",
"notice_evidence": "delivered",
"retrievability": "not_checked",
"filing_window_status": "open",
"policy_freshness": "indeterminate",
"declared_effect": "none",
"effect_acceptance": "not_required",
"effect_trigger": "not_applicable",
"effect_ordering": "not_applicable",
"effect_application": "not_applicable",
"reasons": []
}
¶
They are not expected to agree that the forum is fair, independent, affordable, competent, or legally authoritative. Those conclusions remain outside the protocol.¶
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 mechanism is designed to satisfy the following requirements.¶
R1 — Pre-execution binding: A cryptographically valid Contestability Binding does not by itself establish pre-execution presentation or ordering. A deployment or profile claiming pre-execution presentation or enforcement of the Contestability Binding MUST bind the contestation parameters to the Authorization Artifact and MUST present them to the enforcing executor before execution. A self-asserted issued_at value is insufficient evidence of ordering. To support that pre-execution claim, the selected profile MUST bind the CPO digest into an executor-signed verification or execution record, or supply equivalent authenticated ordering evidence. A post-execution declaration cannot retroactively satisfy the pre-execution claim.¶
R2 — Exact action and authorization binding: The binding MUST identify one Authorization Artifact or authorization instance and the canonical action it covers. It MUST NOT be reusable across different actions or authorization instances.¶
R3 — Substitution resistance: The forum, submission mechanism, Standing Policy, procedure, filing window, effect policy, and selection policy MUST be integrity-protected. A mutable locator without a bound digest is insufficient.¶
R4 — Forum acknowledgement: A profile claiming a forum-acknowledged contestation path MUST carry authenticated evidence that the named forum accepted the forum identifier, submission mechanism, procedure, and class of actions or authorizations covered. An issuer naming an unconsenting forum is disclosure, not a forum-acknowledged path.¶
R5 — Selection provenance: A verifier MUST derive forum-selection provenance from authenticated evidence and local trust inputs. The object MUST NOT turn an issuer's self-asserted claim of independence into a protocol result.¶
R6 — Affected-party delivery or discovery: A profile claiming affected-party access to the contestation binding MUST define how a person or organization that did not participate in the authorization obtains the CPO and the evidence needed to verify its binding. Availability only to the issuer, agent, or executor is insufficient. The filing clock MUST be based on an authenticated event defined by the profile; an issuer-asserted notice time alone MUST NOT shorten the affected party's window.¶
R7 — Structured, non-collapsed result: Verification MUST return and keep separate the structured-result fields defined in Section 6.2, which is the authoritative result contract. It MUST NOT collapse them into a bare contestable: true result.¶
R8 — Effect acceptance and application separation: An issuer-declared active effect MUST NOT be reported as executor-accepted unless the named executor authenticated the same authorization, CPO, effect-policy, and forum-acceptance digests before execution. Executor acceptance MUST NOT be reported as application. A filing or other trigger MUST be authenticated under the bound trigger profile. Application MUST be reported only from separately verified executor evidence and ordering MUST be verified under the bound serialization profile. None of those records proves physical state or authorizes a remedy.¶
R4 and R6 are profile requirements rather than universal claims about every Authorization Artifact. A deployment can use the base object only for disclosure, but it cannot claim a forum-acknowledged path or a path conforming to the affected-party access profile without satisfying the corresponding requirements.¶
R4 and R6 are deliberately tested against claims that a signature or URI cannot establish.¶
The following cases MUST remain distinguishable:¶
| Case | Acknowledgement result | Selection result | Operational result |
|---|---|---|---|
| Issuer names a forum that never signed |
absent
|
derived separately |
not_checked
|
| Forum signs for the exact authorization |
valid_exact
|
derived separately |
not_checked
|
| Forum signs a standing manifest for a class that includes the authorization |
valid_class
|
derived separately |
not_checked
|
| Forum signature is valid but its accepted scope does not cover the authorization |
invalid_scope
|
derived separately |
not_checked
|
| Forum acknowledged the scope but the endpoint is unreachable | acknowledgement remains valid | derived separately |
unreachable
|
| Forum and issuer are the same controlling party | acknowledgement may be valid | normally unilateral
|
derived separately |
A valid forum signature authenticates a signed commitment under the accepted forum key over a defined scope. It does not prove that the forum was selected independently, remains reachable, will accept a particular filer, or will decide according to the bound procedure.¶
An acknowledgement can be either exact or class-based. A class-based acknowledgement is valid only if the verifier can deterministically establish that the authorization falls within the signed class. A free-text class description is insufficient.¶
The following cases MUST NOT collapse into available:¶
the CPO is retrievable only after logging into the account that the action suspended;¶
a signed notice was issued but no evidence establishes that it was delivered;¶
a discovery URI is public but leaks the existence or subject of a sensitive action;¶
the CPO is available to the principal but not to a distinct Affected Party;¶
the issuer serves audience-specific CPOs under different authorization artifacts;¶
the filing window substantially expires before the first access method becomes usable;¶
the affected party is not identifiable until after execution.¶
The protocol therefore separates notice issuance, delivery evidence, and current retrievability. A valid Contestability Notice signature yields the protocol classification issued and authenticates the notice bytes under the accepted signer key. It does not prove human issuance, receipt, comprehension, or successful access.¶
An affected-party profile for an action that disables or controls a credential MUST provide at least one access method that does not depend solely on that credential. Otherwise the action can remove the means of contesting itself.¶
A naive construction in which the forum signs the final CPO fails three tests:¶
If the final CPO contains the forum signature, signing the final CPO creates a circular signature input.¶
If the forum signs every authorization instance, the construction requires an online forum interaction per action and discloses instance metadata before execution.¶
If the forum signs only a free-text action class, class membership is not interoperably decidable.¶
The base design therefore separates:¶
Contestation Terms: the canonical per-authorization facts to which every signature ultimately refers;¶
Forum Acceptance Evidence: either an exact signature over a closed forum-relevant projection of the Contestation Terms or a reusable Forum Acceptance Manifest for one or more closed authorization-profile digests;¶
Selection Evidence: signatures over the Contestation Terms digest and Forum Acceptance Evidence digest;¶
CPO Envelope: the terms and evidence, signed by the CPO issuer;¶
Authorization Binding: a digest of the completed CPO Envelope covered by the Authorization Artifact or companion binding statement.¶
This ordering is acyclic: the forum first signs either a reusable manifest or an exact forum-terms digest; selectors then sign the complete terms and acceptance-evidence digests; the CPO issuer signs the resulting envelope; finally, the Authorization Artifact or companion statement binds the completed CPO digest.¶
An active effect extends, but does not alter, that graph. The executor signs an Effect Acceptance Statement over the completed Authorization Artifact and CPO. A forum filing receipt later binds the CPO digest. An Effect Application Record binds both the acceptance and receipt digests. For a pre-execution hold, the executor's hold or refusal record then binds the application record; for a post-execution fence, the earlier execution record binds the acceptance and the later application record binds the receipt. No signer is required to sign bytes containing its own signature.¶
For class acceptance, the forum signs accepted ABP and Authorization Trust Profile digest pairs, not an open expression language. A verifier returns valid_class only after it has independently verified and projected the Authorization Artifact under one of those exact pairs. Merely carrying profile identifiers is insufficient.¶
This document specifies:¶
a Contestation Parameters Object (CPO);¶
exact and reusable class-based forum acceptance evidence;¶
an Authorization Binding Profile interface for native authorization systems;¶
two ways to bind a CPO to an authorization;¶
profiles for classifying pre-execution evidence without claiming physical proof;¶
an optional declared effect policy, Executor Effect Acceptance Statement, authenticated filing trigger, and Effect Application Record;¶
a deterministic verification algorithm;¶
a structured result that keeps binding, discoverability, forum acknowledgement, operational status, selection provenance, notice evidence, retrievability, and effect evidence separate;¶
security requirements for substitution, equivocation, dead endpoints, abusive deadlines, issuer-controlled forums, trigger replay, and execution races.¶
This document does not specify:¶
a dispute-resolution protocol or case state machine;¶
arbitrator discovery, evidence exchange, adjudication, appeal, award, or remedy;¶
who legally has standing;¶
whether a forum is impartial, competent, affordable, or legally valid;¶
which effect policy a deployment ought to choose, or whether an external system is legally or operationally compelled to honor it;¶
the legitimacy of the authorization, policy, issuer, or consequence.¶
Authorization Artifact: A signed object expressing, under an authorization system, a permission for an identified agent, workload, or delegate to perform a bounded action.¶
Authorization Instance Identifier (authorization_id): A globally unique or collision-resistant identifier for one authorization instance.¶
Action Digest (action_digest): A digest over the canonical action the executor will evaluate.¶
Contestation Parameters Object (CPO): The closed, signed object defined in Section 4.¶
Contestation Terms: The canonical, unsigned per-authorization facts inside a CPO. Role signatures refer to its digest rather than recursively signing an envelope that contains those signatures.¶
Contestability Binding: A commitment from an Authorization Artifact to a CPO, either directly or through a companion binding statement.¶
Forum: The service or institution designated to receive a contestation. Identification of a forum does not assert independence or legal jurisdiction.¶
Exact Forum Acceptance Statement: A forum-signed acceptance of one closed, forum-relevant projection of the Contestation Terms.¶
Forum Acceptance Manifest (FAM): A reusable forum-signed statement accepting contestations for authorization classes successfully verified and projected under one or more closed ABP and Authorization Trust Profile digest pairs, subject to bound procedure, time, and continuity constraints.¶
Authorization Binding Profile (ABP): A digest-identified adapter specification that verifies one native Authorization Artifact type and deterministically projects the closed authorization tuple consumed by this document.¶
Authorization Trust Profile: A digest-identified set of trust inputs and issuer-authority rules applied by an ABP. It answers which issuer keys are accepted; the ABP answers how the native artifact is verified and projected.¶
Effect Policy: The issuer-signed declaration in the CPO terms that selects none, hold_before_execution, or fence_after_execution and, for an active mode, binds the executor and the trigger, state-machine, idempotency, serialization, and trust profiles.¶
Executor Trust Profile: A digest-identified set of trust anchors, executor-key authority rules, rotation rules, and compromise semantics used to verify effect acceptance and application records.¶
Effect Executor: The party named by an active Effect Policy that signs effect acceptance and application records and controls, or participates under a bound serialization profile in controlling, the target hold or fence transition. It can be the action executor but is not assumed to be the same party.¶
Executor Effect Acceptance Statement: An executor-signed commitment, made over a completed authorization and CPO before execution, to process a bound active effect policy.¶
Filing Receipt: A forum-authenticated record accepting or refusing one contestation submission. Only an accepted receipt verified under the bound trigger profile can be an effect trigger.¶
Effect Application Record: An executor-signed claim describing how it processed one authenticated trigger under the bound effect policy. It is not proof of physical state or a remedy.¶
Standing Policy: A versioned policy describing which roles or parties may file. This document verifies its identity and integrity, not the correctness of its determinations.¶
Selection Authority: A party permitted by the relying party's trust profile to participate in or determine forum selection.¶
Affected Party: A person or organization whose interests may be materially affected by an authorized action. An Affected Party need not be the principal, agent, issuer, executor, or relying party.¶
The object is first shown in JSON diagnostic form for readability. The mandatory executable profile in Section 4.13 encodes the corresponding closed data model using Core Deterministic CBOR and signs each role statement with COSE_Sign1. The JSON form is not a wire encoding and MUST NOT be hashed or signed.¶
{
"type": "agent-contestation-parameters-v1",
"terms": {
"authorization_id": "urn:uuid:...",
"authorization_binding_profile": {
"uri": "https://example/profiles/account-action-authz/3",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"authorization_trust_profile": {
"uri": "https://example/trust/account-action-issuers/5",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"authorization_issuer": "https://issuer.example/keys/3",
"authorization_validity": {
"not_before": "2026-08-11T00:00:00Z",
"not_after": "2026-08-12T00:00:00Z"
},
"action_digest": { "alg": "sha-256", "value": "base64url..." },
"forum": {
"id": "https://forum.example/",
"submission_endpoint": "https://forum.example/cases",
"verification_key_id": "https://forum.example/keys/2026-1"
},
"standing_policy": {
"uri": "https://example/policies/standing/7",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"procedure": {
"uri": "https://example/procedures/agent-actions/4",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"filing_window": {
"basis": "authenticated_delivery_time",
"duration_seconds": 2592000
},
"effect_policy": {
"mode": "none"
},
"selection_policy": {
"uri": "https://example/policies/forum-selection/2",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"affected_party_access": [
{
"method": "effect_notice",
"notice_profile": "agent-contestability-notice-v1",
"available_until": "2026-09-10T00:00:00Z"
},
{
"method": "authenticated_lookup",
"discovery_uri": "https://platform.example/contestability/urn:uuid:...",
"authentication_profile": {
"uri": "https://platform.example/authn/notice-capability/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"available_until": "2026-09-10T00:00:00Z"
}
],
"issued_at": "2026-08-11T00:00:00Z",
"expires_at": "2026-09-10T00:00:00Z",
"nonce": "base64url..."
},
"forum_acceptance": {
"mode": "class_manifest",
"manifest_digest": { "alg": "sha-256", "value": "base64url..." }
},
"selection_evidence": [
{
"selector_id": "https://principal.example/keys/4",
"role": "principal",
"signed_input": "selection-input-v1",
"signature": "base64url..."
},
{
"selector_id": "https://registry.example/keys/9",
"role": "external_selector",
"signed_input": "selection-input-v1",
"signature": "base64url..."
}
],
"issuer": "https://issuer.example/keys/3",
"signature": "base64url..."
}
¶
Every map in the mandatory executable profile is closed. A verifier MUST reject an unknown map member, duplicate map key, unsupported object type or version, non-deterministic encoding, or value outside the profile's CDDL. Payload-level crit processing is therefore unnecessary in CBAP-1. COSE protected-header processing remains governed by Section 4.14.¶
forum.id, submission_endpoint, and verification_key_id MUST be present. A human-readable name alone is insufficient. The endpoint MUST use an authenticated transport profile. Successful network access does not establish forum independence.¶
forum_acceptance identifies either an Exact Forum Acceptance Statement or a Forum Acceptance Manifest by digest. The accepted input covers only the facts to which the forum commits: accepted authorization scope, forum identity and key, submission endpoint, Standing Policy, procedure, filing-window rule, filing-receipt profile, and withdrawal or continuity policy. Selection provenance and the issuer's declared effect policy remain separately signed facts; a forum acknowledgement does not authenticate either one.¶
A valid acknowledgement authenticates a signed commitment under the accepted forum key to receive the declared scope under the bound parameters. It does not prove availability, neutrality, legal jurisdiction, or performance.¶
An exact acknowledgement binds the forum_terms_digest for one authorization instance. A class acknowledgement binds one or more closed ABP and Authorization Trust Profile digest pairs. A verifier MUST refuse a class acknowledgement when the Authorization Artifact has not itself been verified and projected under one of those exact pairs.¶
For exact acceptance, the signed_at value authenticated by the forum signature MUST be no later than the authenticated lower bound of the authorization's executable validity interval, valid_from MUST be no later than that same boundary, and valid_until MUST be no earlier than the end of the declared filing window, unless the bound withdrawal policy provides verifiable continuity through a replacement forum. For class acceptance, the Authorization Artifact MUST bind the manifest during may_bind_from through may_bind_until, and the instantiated filing obligation MUST remain within maximum_filing_horizon_seconds. A withdrawal after execution MUST be evaluated under the bound policy and MUST NOT silently erase the historical acknowledgement. The filing-receipt profile identifies the authenticated response a conforming forum returns after accepting or refusing a filing; this document does not otherwise define the filing exchange.¶
The Standing Policy, procedure, and selection policy MUST be bound by digest. A mutable URI without a digest MUST be refused. A verifier MAY apply a stricter local policy than the referenced procedure or filing window.¶
The filing window MUST identify the authenticated event from which its duration is calculated. Initial event classes are:¶
execution_time: authenticated time in the executor's action or execution record;¶
transparency_publication_time: authenticated registration time of the Contestability Notice or CPO digest under a selected transparency profile;¶
authenticated_delivery_time: time in a transport-specific delivery receipt bound to the Contestability Notice digest.¶
An issuer-signed issued_at value alone is not one of these event classes. If the selected event evidence is absent or invalid, the verifier returns filing_window_status: indeterminate; it MUST NOT silently substitute local receipt time or another clock.¶
A profile can define a deterministic combination or fallback among event classes, but it MUST state the precedence rule. Verification authenticates the selected clock input and computes the deadline; it does not establish that the rule gave the Affected Party a fair opportunity to act.¶
An effect_policy declares whether an authenticated contestation filing is intended to support a protocol-visible transition result for the named executor. The base modes are:¶
none: filing has no automatic execution effect under this binding;¶
hold_before_execution: selects a hold result that is satisfied only when an accepted filing is authenticated and ordered before the bound execution boundary and the bound executor evidence records the required hold state rather than an execution transition for that boundary;¶
fence_after_execution: selects a fence result that is satisfied only when an accepted filing is authenticated and ordered after action execution but before the bound finality boundary and the bound executor evidence records the required fence transition.¶
An active-effect profile using hold_before_execution MUST NOT select execution_time as its filing-window basis. It MUST select an authenticated filing-window event that can occur before the execution boundary, such as conforming delivery or transparency-publication evidence or another profile-defined pre-execution event.¶
The base protocol deliberately has no profile_defined escape value. An unexamined extension cannot be assigned the semantics of a hold or fence. A future mode requires a standards-defined value or a versioned extension understood by every verifier making a claim about it.¶
For none, no effect parameters are present and effect_acceptance is not_required. For either active mode, the policy MUST contain:¶
{
"mode": "fence_after_execution",
"executor": {
"id": "https://executor.example/",
"verification_key_id": "https://executor.example/keys/8"
},
"executor_trust_profile": {
"uri": "https://platform.example/trust/effect-executors/2",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"trigger_profile": {
"event": "accepted_filing_receipt",
"uri": "https://forum.example/profiles/filing-receipt/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"state_machine_profile": {
"uri": "https://platform.example/profiles/account-finality/2",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"target_state_digest": { "alg": "sha-256", "value": "base64url..." },
"application_deadline": {
"basis": "authenticated_trigger_time",
"duration_seconds": 30
},
"idempotency_profile": {
"uri": "https://platform.example/profiles/contest-trigger-idempotency/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"serialization_profile": {
"uri": "https://platform.example/profiles/account-action-serialization/3",
"digest": { "alg": "sha-256", "value": "base64url..." }
}
}
¶
trigger_profile MUST identify an authenticated event and its complete verification rules. For accepted_filing_receipt, its digest MUST equal the submission-receipt profile authenticated by the verified forum acceptance evidence. The receipt time MUST fall within the verified filing window and the effect mode's transition interval, unless the bound procedure and effect policy define the same deterministic grace rule. An authenticated successful receipt records acceptance of a filing under the bound forum key and profile. It does not prove standing, merits, fairness, or entitlement to a remedy.¶
executor_trust_profile binds the trust anchors, key-authority rules, rotation rules, and compromise semantics used to authenticate the named executor; a relying party can apply stricter local policy. state_machine_profile defines the states, transition preconditions, finality boundary, and interpretation of the state commitments carried in effect records. target_state_digest commits to the exact hold or fence transition. application_deadline is computed only from the authenticated time established by the trigger profile; an executor or issuer timestamp cannot silently replace it. idempotency_profile defines how duplicate triggers are detected. serialization_profile defines the authenticated sequence number, compare-and-swap rule, transaction boundary, or equivalent mechanism that orders the trigger against execution and finality transitions.¶
The Effect Executor MAY differ from the executor that performs the authorized action only when the serialization profile authenticates the cross-system boundary and assigns each required transition to a named signer. For hold_before_execution, the Effect Executor MUST control or atomically gate the action's execution boundary. For fence_after_execution, it MUST control or atomically gate the bound finality transition. Merely receiving events from the system of record is insufficient.¶
hold_before_execution is satisfied only when the trigger is ordered before the execution boundary and the bound executor evidence records the hold state rather than an execution disposition for that boundary. It cannot retroactively characterize an already executed action as held. fence_after_execution is satisfied only when the trigger is ordered after execution and before the bound finality boundary and the bound executor evidence records the fence state. These are protocol-state results over authenticated evidence; a fence does not undo the action, restore prior state, or constitute a remedy.¶
The policy is an issuer-signed declaration inside the CPO terms. It does not bind the executor merely because the issuer named an executor key. Active modes require the separate Executor Effect Acceptance Statement in Section 5.4. Acceptance is not application, and an Effect Application Record is still only a signed claim by the executor key about the protocol state it controls. No object defined here compels a court, human, physical process, or external system.¶
The CPO MUST NOT contain a self-asserted boolean such as independent: true. A verifier derives selection provenance from authenticated signatures and its local trust profile.¶
The authorization issuer's signature is necessary to bind the CPO to the authorization but is not evidence of independent selection. An issuer-only object is classified as unilateral.¶
affected_party_access is an ordered set of declared methods for delivery or discovery of the CPO and its verification material by a party that may be absent from the authorization exchange. The initial methods under consideration are:¶
effect_notice: delivered with the notice of the action's effect;¶
authenticated_lookup: retrievable from a bound discovery URI after authenticating an eligible party;¶
public_transparency: retrievable from a named transparency service without disclosing private filing evidence.¶
The access objects MUST be covered by the CPO issuer signature. A profile claiming affected-party access to the contestation binding MUST define at least one mandatory delivery or discovery method, its retention period, and the behavior when the affected party cannot authenticate before the filing window closes.¶
Where the action disables, suspends, revokes, or controls a credential, at least one access method MUST remain usable without relying solely on that credential. The authentication profile is digest-bound so a verifier can apply a local credential-survivability policy; the profile's presence does not by itself prove that access will succeed.¶
An affected-party profile using effect_notice carries or references a signed notice with the following minimum members:¶
{
"type": "agent-contestability-notice-v1",
"authorization_id": "urn:uuid:...",
"action_digest": { "alg": "sha-256", "value": "base64url..." },
"effect_digest": { "alg": "sha-256", "value": "base64url..." },
"cpo_digest": { "alg": "sha-256", "value": "base64url..." },
"issued_at": "2026-08-11T00:00:00Z",
"access": {
"mode": "by_reference",
"uri": "https://platform.example/contestability/urn:uuid:..."
},
"issuer": "https://issuer.example/keys/3",
"signature": "base64url..."
}
¶
The notice signature MUST cover the authorization, action, effect, CPO digest, issue time, and access method. A valid signature yields notice_evidence: issued. It MUST NOT yield delivered unless a selected transport profile supplies authenticated delivery evidence. It MUST NOT yield read or understood.¶
An effect_notice profile SHOULD deliver the notice no later than the effect notification. A filing-window profile claiming affected-party recourse MUST define how late notice affects the closing time. The base protocol does not infer receipt from issuance.¶
terms is the only per-authorization object over which the forum, selectors, issuer, and authorization binding need to converge. Let:¶
terms_digest = HASH("agent-contestation-terms-v1" || canonical(terms))
effect_policy_digest = HASH("agent-contestation-effect-policy-v1" ||
canonical(terms.effect_policy))
forum_terms = project(terms, authorization_id, authorization_binding_profile,
authorization_trust_profile,
authorization_issuer, authorization_validity,
action_digest, forum, standing_policy, procedure,
filing_window)
forum_terms_digest = HASH("agent-contestation-forum-terms-v1" ||
canonical(forum_terms))
acceptance_digest = HASH(canonical(forum_acceptance_evidence))
selection_input = HASH("agent-contestation-selection-v1" || terms_digest || acceptance_digest)
cpo_tbs = canonical(type, terms, forum_acceptance, selection_evidence, issuer)
cpo_digest = HASH("agent-contestation-cpo-v1" || canonical(signed_CPO))
¶
The domain-separation strings are part of the hash input. These equations describe the abstract signature topology. CBAP-1 instantiates them with the exact deterministic encoding and SHA-256 derivations in Sections 4.13 through 4.16. Another application profile MUST define an equally complete and non-ambiguous instantiation.¶
An Exact Forum Acceptance Statement signs forum_terms_digest plus its validity, filing-receipt profile, and withdrawal policy. A Forum Acceptance Manifest is independently signed and reusable; the CPO references its digest. Each selector signs selection_input, which still covers the complete terms. The CPO issuer signs cpo_tbs. The completed cpo_digest is then covered by the Authorization Artifact or companion binding statement.¶
No signature input contains the signature being computed. effect_policy_digest is used only by records created after the signed CPO and Authorization Artifact exist; it does not enter forum_terms_digest and does not make the forum authenticate the issuer's effect declaration. A producer or signer MUST construct each signature input from the exact profile-defined input. A verifier MUST verify the received object against that exact profile-defined signature input.¶
Exact acceptance is represented diagnostically as:¶
{
"type": "agent-forum-exact-acceptance-v1",
"forum_terms_digest": { "alg": "sha-256", "value": "base64url..." },
"valid_from": "2026-08-11T00:00:00Z",
"valid_until": "2026-09-10T00:00:00Z",
"submission_receipt_profile": {
"uri": "https://forum.example/profiles/filing-receipt/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"withdrawal_policy": {
"uri": "https://forum.example/policies/withdrawal/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"forum_key_id": "https://forum.example/keys/2026-1",
"signed_at": "2026-08-11T00:00:00Z",
"signature": "base64url..."
}
¶
Exact acceptance gives the strongest instance binding but requires the forum to process instance metadata before authorization. It SHOULD be used only when the deployment requires instance-specific forum acceptance and has addressed metadata disclosure, traffic analysis, latency, and forum availability in the authorization path.¶
A Forum Acceptance Manifest (FAM) is a reusable, signed acceptance statement:¶
{
"type": "agent-forum-acceptance-manifest-v1",
"manifest_id": "https://forum.example/manifests/2026-08",
"forum": {
"id": "https://forum.example/",
"submission_endpoint": "https://forum.example/cases",
"verification_key_id": "https://forum.example/keys/2026-1"
},
"accepted_authorization_classes": [
{
"abp_digest": { "alg": "sha-256", "value": "base64url-abp-digest..." },
"authorization_trust_profile_digest": {
"alg": "sha-256",
"value": "base64url-trust-profile-digest..."
}
}
],
"standing_policy": {
"uri": "https://example/policies/standing/7",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"procedure": {
"uri": "https://example/procedures/agent-actions/4",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"filing_window_rule": {
"permitted_bases": [
"authenticated_delivery_time",
"transparency_publication_time"
],
"minimum_duration_seconds": 2592000
},
"submission_receipt_profile": {
"uri": "https://forum.example/profiles/filing-receipt/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"withdrawal_policy": {
"uri": "https://forum.example/policies/withdrawal/1",
"digest": { "alg": "sha-256", "value": "base64url..." }
},
"may_bind_from": "2026-08-01T00:00:00Z",
"may_bind_until": "2027-08-01T00:00:00Z",
"maximum_filing_horizon_seconds": 7776000,
"issued_at": "2026-07-20T00:00:00Z",
"key_id": "https://forum.example/keys/2026-1",
"signature": "base64url..."
}
¶
The base profile does not define a general predicate language for accepted actions. Class membership is established only by an exact pair consisting of an ABP digest and an Authorization Trust Profile digest, followed by successful verification and projection of the Authorization Artifact under that pair. A profile label, URI, or locally substituted trust store MUST NOT establish membership.¶
The CPO's forum, Standing Policy, procedure, filing-window rule, and forum key MUST satisfy the manifest exactly or under a deterministic constraint explicitly defined by the manifest profile. may_bind_from and may_bind_until bound when a new Authorization Artifact may reference the manifest; they do not terminate a filing window already instantiated by a valid binding. maximum_filing_horizon_seconds bounds the latest filing obligation created by an authorization bound during that interval. A mismatch yields invalid_scope.¶
A FAM removes the forum from the per-authorization critical path and does not require disclosure of each authorization instance to the forum. It does not prove capacity or continued availability. The full FAM can be distributed with the CPO; only a digest need be transparency-registered to support equivocation detection.¶
The forum's signature acknowledges a scope. It MUST NOT be counted as evidence that the forum was selected non-unilaterally. Selection evidence signs selection_input, which includes both the Contestation Terms and the exact acceptance evidence used. This prevents a selector's signature for one forum acceptance from being replayed with another.¶
An entity can perform multiple roles, but role co-location remains visible in the result. When the issuer, forum operator, and external selector resolve to the same controlling trust domain under local policy, the verifier MUST NOT upgrade selection provenance solely because three keys signed.¶
The Contestability Binding Application Profile 1 (CBAP-1) is the mandatory-to-implement encoding and executable base profile for this document. CBAP-1 uses the Core Deterministic Encoding Requirements in Section 4.2.1 of [RFC8949]. It does not use the length-first map key ordering in Section 4.2.3 of [RFC8949], historically called canonical CBOR by [RFC7049].¶
A CBAP-1 encoder and verifier MUST enforce all of the following:¶
preferred and shortest serialization for every integer, length, and tag argument;¶
definite-length byte strings, text strings, arrays, and maps only;¶
bytewise-lexicographic ordering of the deterministic encodings of map keys;¶
rejection of duplicate map keys before conversion to a host-language map;¶
rejection of floating-point values, simple values other than false, true, and null, and tags other than the required outer COSE_Sign1 tag 18;¶
well-formed UTF-8 text strings, compared as encoded bytes without Unicode, URI, case, or percent-encoding normalization;¶
unsigned-integer member labels exactly as specified by the closed CDDL below.¶
Before allocating, slicing, advancing an input cursor, or iterating a declared collection length, a decoder MUST verify with checked arithmetic that the length is representable by the host and does not exceed the remaining input. A declared length or count that cannot be consumed from the received bytes MUST be rejected at the enclosing encoding boundary. It MUST NOT wrap an offset, panic, abort the process, or attempt an allocation based only on the received length.¶
Every uri value in CBAP-1 MUST satisfy the generic URI syntax of [RFC3986] and the https URI scheme requirements in Section 4.2.2 of [RFC9110], with these additional profile restrictions:¶
the scheme is the exact lowercase ASCII string https;¶
an authority introduced by // is present and contains a non-empty host;¶
user information is absent;¶
if a port delimiter is present, the port is a non-empty decimal integer in 0..65535;¶
every percent-encoded triplet is syntactically complete; and¶
a fragment component is absent.¶
Conformance is determined by the complete component grammar, not by a prefix test or a character allowlist. In particular:¶
authority, host, IP-literal, IPv6address, IPvFuture,
path-abempty, segment, pchar, and query have the meanings and ABNF
defined by [RFC3986];¶
a bracketed host MUST contain exactly one syntactically valid [RFC3986]
IPv6address or IPvFuture value;¶
[ and ] are permitted only as the delimiters of that IP-literal and
MUST be rejected in a registered name, path, or query;¶
a registered name is validated as reg-name; accepting the characters of
a putative hostname without parsing its component boundaries is
insufficient; and¶
IPv6 zone identifiers, including a percent-encoded zone suffix inside an IP-literal, are not supported by CBAP-1 and MUST be rejected.¶
[RFC9844] obsoletes [RFC6874] and does not define a replacement URI syntax for zone identifiers. CBAP-1 deliberately excludes them because a locally scoped zone identifier is not a stable signed identifier across verifiers.¶
Path and query components are permitted only when their complete [RFC3986]
grammar matches. CBAP-1 performs no URI normalization: the exact ASCII bytes
are the identifier and signature input. A different but allegedly equivalent
spelling is a different value. A prefix test such as
starts_with("https://"), a search for forbidden delimiters, or a
component-wide character allowlist is not URI validation.¶
The following examples are normative CBAP-1 URI conformance probes. Each value is evaluated as written, without normalization or network resolution.¶
| URI | Required result | Boundary exercised |
|---|---|---|
https://forum.example
|
accept | empty path |
https://forum.example:443/cases?open=1
|
accept | decimal port, path and query |
https://[2001:db8::1]/cases
|
accept | IPv6 address literal |
https://[v1.a]/cases
|
accept | IPvFuture |
https://forum.example/%2Fcase
|
accept | complete percent triplet in path |
HTTPS://forum.example/
|
reject | scheme is not exact lowercase https
|
https://
|
reject | empty host |
https://user@forum.example/
|
reject | user information |
https://forum.example:/
|
reject | empty explicit port |
https://forum.example:65536/
|
reject | port outside profile range |
https://forum.example/%2/
|
reject | incomplete percent triplet |
https://forum.example/#part
|
reject | fragment present |
https://[:::]/
|
reject | invalid IPv6 address literal |
https://[v1.]/
|
reject | invalid IPvFuture |
https://[fe80::1%25eth0]/
|
reject | zone identifier unsupported |
https://forum.example/a[b]
|
reject | brackets in path |
https://forum.example/?a=[b]
|
reject | brackets in query |
The following conformance probe distinguishes Section 4.2.1 ordering from length-first ordering. A conforming CBAP-1 encoder MUST encode the diagnostic map {100: -1, -1: 100} as hexadecimal a2186420201864. An encoder that places key -1 before key 100 is not conformant even if a library describes its output as canonical.¶
CBAP-1 fixes SHA-256 as specified by [RFC6234] as its only digest function. A digest is a 32-byte byte string; an algorithm identifier is not carried beside each digest. Algorithm substitution is therefore impossible inside the profile. Adding another hash function requires a new application-profile version.¶
Let dCBOR(x) be the exact CBAP-1 deterministic encoding of data item x. Domain-separated hashes are computed as:¶
H(domain, value) = SHA-256(dCBOR([domain, value]))¶
domain is the exact lowercase ASCII text string defined at each use. Digests of signed artifacts are SHA-256 over the complete tagged COSE_Sign1 byte sequence, including the tag, protected-header bytes, payload, and signature. Policy and action digests are SHA-256 over the exact supplied bytes. A verifier MUST NOT hash a decoded and reconstructed signed object in place of its received conforming bytes.¶
Every signed CBAP-1 object is an embedded-payload, tagged COSE_Sign1 object as defined by [RFC9052]:¶
18([protected, unprotected, payload, signature])¶
The protected header map MUST contain exactly:¶
{ 1: -19, 4: kid }
¶
Header label 1 is alg; value -19 is the fully specified Ed25519 algorithm registered by [RFC9864]. CBAP-1 MUST NOT use the deprecated polymorphic EdDSA value -8. Header label 4 is kid, encoded as a byte string of 1 through 64 bytes. The unprotected header map MUST be empty. The payload MUST be present as a byte string containing one closed CBAP-1 payload. Detached payloads, countersignatures, critical headers, and additional protected or unprotected headers are not supported by CBAP-1.¶
The signature is computed over the [RFC9052] Sig_structure with context Signature1, the received protected-header bytes, an empty external AAD byte string, and the embedded payload bytes. Ed25519 is defined by [RFC8032]. The signature MUST be 64 bytes. The public key is an Ed25519 COSE_Key as defined by [RFC9053], with kty = 1, crv = 6, and a 32-byte x coordinate. If its alg member is present, it MUST be -19.¶
kid is a key-selection hint, not a trust assertion. The verifier's local trust profile MUST resolve it to exactly one authorized public key for the required role and controlling trust domain. Zero matches, multiple matches, an unauthorized role, or a key/profile mismatch yields invalid or indeterminate as specified by the calling verification step. Each payload also carries the signer's key identifier as a text string; its UTF-8 bytes MUST equal the protected kid.¶
CBAP-1 intentionally implements the smallest end-to-end path that exercises the load-bearing claims: direct authorization binding, exact forum acceptance, issuer-only selection provenance, by-value policy verification, executor-attested pre-execution evidence, an execution-time filing clock, and effect_policy = none. Class manifests, companion bindings, notices, active execution effects, multiparty selection, and external selection remain part of the abstract protocol but are unsupported by CBAP-1 and require another named profile.¶
In CBAP-1, epoch is an unsigned integer counting seconds from 1970-01-01T00:00Z UTC on the POSIX numeric timeline described for nonnegative epoch-based date/time values in Section 3.4.2 of [RFC8949]. CBAP-1 encodes this integer directly as the untagged CDDL uint; it does not use CBOR tag 1. Fractional and negative epoch values are therefore outside the profile. Leap seconds follow POSIX-time handling: they are not represented as an additional distinct counted second, and comparisons and deadline arithmetic use the resulting POSIX timeline, including its one-second discontinuity at an inserted leap second.¶
The diagnostic CDDL [RFC8610] is:¶
digest = bstr .size 32
id16 = bstr .size 16
epoch = uint
key-id = tstr
uri = tstr
policy-ref = [uri, digest]
validity = [not-before: epoch, not-after: epoch]
forum = [forum-id: uri, submission-endpoint: uri, forum-key-id: key-id]
filing-window = [basis: 1, duration-seconds: uint]
effect-policy = [mode: 0]
affected-party-access = [method: 3, discovery-uri: uri, available-until: epoch]
cbap1-terms = {
1: id16, ; authorization-id
2: digest, ; abp-digest
3: digest, ; authorization-trust-profile-digest
4: key-id, ; authorization-issuer-key-id
5: validity, ; authorization-validity
6: digest, ; action-digest
7: forum,
8: policy-ref, ; standing-policy
9: policy-ref, ; procedure
10: filing-window,
11: effect-policy,
12: policy-ref, ; selection-policy
13: [1* affected-party-access],
14: epoch, ; issued-at
15: epoch, ; expires-at
16: id16 ; nonce
}
cbap1-cpo = {
1: 1, ; profile version
2: 1, ; object type: CPO
3: cbap1-terms,
4: [mode: 0, exact-acceptance-digest: digest],
5: [], ; no selection statements: unilateral
6: key-id ; issuer-key-id
}
cbap1-exact-acceptance = {
1: 1,
2: 2, ; exact forum acceptance
3: digest, ; forum-terms-digest
4: epoch, ; valid-from
5: epoch, ; valid-until
6: policy-ref, ; submission-receipt-profile
7: policy-ref, ; withdrawal-policy
8: epoch, ; signed-at
9: key-id ; forum-key-id
}
cbap1-authorization = {
1: 1,
2: 3, ; CBAP-1 test Authorization Artifact
3: id16, ; authorization-id
4: key-id, ; issuer-key-id
5: tstr, ; agent-id
6: digest, ; action-digest
7: epoch, ; not-before
8: epoch, ; not-after
9: digest, ; cpo-digest
10: id16 ; nonce
}
cbap1-executor-verification = {
1: 1,
2: 4, ; executor verification record
3: digest, ; authorization-digest
4: id16, ; authorization-id
5: digest, ; action-digest
6: digest, ; cpo-digest
7: 1, ; decision: execute
8: epoch, ; verified-at
9: id16, ; nonce
10: key-id ; executor-key-id
}
cbap1-execution-record = {
1: 1,
2: 5, ; execution record
3: digest, ; authorization-digest
4: digest, ; verification-record-digest
5: id16, ; authorization-id
6: digest, ; action-digest
7: 1, ; disposition: executed
8: epoch, ; executed-at
9: id16, ; nonce
10: key-id ; executor-key-id
}
cbap1-bundle = {
1: 1,
2: bstr, ; cpo-cose
3: bstr, ; exact-acceptance-cose
4: bstr, ; authorization-cose
5: bstr, ; executor-verification-cose
6: bstr, ; execution-record-cose
7: bstr, ; action-bytes
8: [+ [digest, bstr]] ; policy-digest, policy-bytes
}
¶
The following member-label registry is normative. The names identify protocol semantics, not merely implementation variables. An implementation that assigns a listed semantic value to another label is not CBAP-1 conformant even when its producer and verifier agree with each other.¶
cbap1-terms 1 authorization-id 2 abp-digest 3 authorization-trust-profile-digest 4 authorization-issuer-key-id 5 authorization-validity 6 action-digest 7 forum 8 standing-policy 9 procedure 10 filing-window 11 effect-policy 12 selection-policy 13 affected-party-access 14 issued-at 15 expires-at 16 nonce cbap1-cpo 1 profile-version 2 object-type 3 terms 4 exact-acceptance-reference 5 selection-statements 6 issuer-key-id cbap1-exact-acceptance 1 profile-version 2 object-type 3 forum-terms-digest 4 valid-from 5 valid-until 6 submission-receipt-policy 7 withdrawal-policy 8 signed-at 9 forum-key-id cbap1-authorization 1 profile-version 2 object-type 3 authorization-id 4 issuer-key-id 5 agent-id 6 action-digest 7 not-before 8 not-after 9 cpo-digest 10 nonce cbap1-executor-verification 1 profile-version 2 object-type 3 authorization-digest 4 authorization-id 5 action-digest 6 cpo-digest 7 decision 8 verified-at 9 nonce 10 executor-key-id cbap1-execution-record 1 profile-version 2 object-type 3 authorization-digest 4 executor-verification-digest 5 authorization-id 6 action-digest 7 disposition 8 executed-at 9 nonce 10 executor-key-id cbap1-bundle 1 profile-version 2 cpo-cose 3 exact-acceptance-cose 4 authorization-cose 5 executor-verification-cose 6 execution-record-cose 7 action-bytes 8 policy-pairs¶
In particular, executor-verification member 5 is always action-digest and member 6 is always cpo-digest. Execution-record member 5 is authorization-id and member 6 is action-digest. Reusing a semantic label number across different maps is not a CBAP-1 design rule; only the registry above assigns meaning.¶
The integer values have the following fixed meanings in CBAP-1: filing-window basis 1 is execution_time; effect mode 0 is none; affected-party access method 3 is public_transparency; forum-acceptance mode 0 is exact; executor decision 1 is execute; and execution disposition 1 is executed. An unknown integer is unsupported, not an extension point.¶
The filing-window duration-seconds value MUST be in the inclusive range 1..18446744073709551615. A zero-duration contestation window is not valid in CBAP-1 and fails at profile_binding_mismatch rather than being interpreted as an instantaneous window.¶
Policy pairs in bundle member 8 MUST be sorted in ascending bytewise order of policy-digest and MUST NOT repeat a digest. This makes the by-value bundle unique rather than treating arbitrary array order as a new encoding of the same evidence set.¶
cbap1-authorization is a deliberately small test Authorization Artifact and the mandatory ABP used only to make the base profile executable. It is not proposed as a universal agent-authorization format. Production authorization systems compose through their own ABPs.¶
CBAP-1 uses these exact derivations:¶
action_digest = SHA-256(action_bytes)
policy_digest = SHA-256(policy_bytes)
terms_digest = H("agent-contestation-terms-v1", cbap1-terms)
forum_terms = [terms[1], terms[2], terms[3], terms[4], terms[5],
terms[6], terms[7], terms[8], terms[9], terms[10]]
forum_terms_digest = H("agent-contestation-forum-terms-v1", forum_terms)
acceptance_digest = SHA-256(exact_acceptance_cose_bytes)
cpo_digest = SHA-256(cpo_cose_bytes)
authorization_digest = SHA-256(authorization_cose_bytes)
verification_record_digest = SHA-256(executor_verification_cose_bytes)
¶
The construction order is fixed:¶
Fix the action bytes, policy bytes, trust inputs, identifiers, validity, forum, filing window, access method, times, and nonces.¶
Compute the action and policy digests and construct cbap1-terms.¶
Project forum_terms, compute its digest, and obtain the forum-signed exact acceptance.¶
Hash the complete signed acceptance and place that digest in the CPO payload.¶
Sign the CPO and hash the complete tagged COSE_Sign1 bytes.¶
Place the CPO digest in the CBAP-1 Authorization Artifact and sign it.¶
Hash the signed Authorization Artifact and construct the executor verification record. Place authorization-digest at label 3, authorization-id at label 4, action-digest at label 5, and cpo-digest at label 6.¶
Sign that record, hash it, and construct the execution record. Place authorization-digest at label 3, executor-verification-digest at label 4, authorization-id at label 5, and action-digest at label 6.¶
Sign the execution record and assemble the unsigned by-value bundle.¶
No step signs or hashes a placeholder for an object that is completed later. Reversing steps 3 through 8 or reconstructing a signed artifact from decoded fields changes the relevant digest and MUST fail verification.¶
The bundle is evidence, not a trust store. A CBAP-1 verifier receives separately:¶
the expected CBAP-1 ABP digest;¶
the expected Authorization Trust Profile digest;¶
one issuer Ed25519 public key authorized for the kid and authorization scope;¶
one forum Ed25519 public key authorized for the forum identifier and kid;¶
one executor Ed25519 public key authorized for the executor kid;¶
the controlling trust domain for each role;¶
a verification-time input presented at the verifier boundary as an integer and validated before conversion to the CBAP-1 unsigned range.¶
The expected ABP digest is H("cbap1-authorization-binding-profile-v1", 1). The Authorization Trust Profile digest is supplied by local policy and MUST equal terms member 3; untrusted bytes carried in the bundle cannot replace it. Policy bytes in the bundle establish discoverability and digest equality only. They do not become trusted merely because the issuer supplied them.¶
The valid verification-time range is 0..18446744073709551615. A negative integer, an integer above that range, or an external representation that is not an integer fails with verification_time_invalid before any bundle byte is parsed. A public adapter MAY use a textual or wider host representation to expose this boundary, but parse and range failures MUST be converted to the closed reason. They MUST NOT cause an unhandled exception, panic, process abort, clamping, wrapping, or substitution. An internal API whose type cannot represent an invalid value does not by itself satisfy the externally observable conformance boundary.¶
CBAP-1 returns selection_provenance: unilateral, forum_acknowledgement: valid_exact, pre_execution_evidence: executor_attested, and declared_effect: none only after every corresponding signature, digest, identifier, validity, ordering, and role check succeeds. The execution record's authenticated executed-at value starts the filing window. This is an executor-signed clock claim under the supplied Executor Trust Profile, not an external wall-clock proof.¶
Given an Authorization Artifact, action, CPO, optional companion binding statement, verification time, local trust profile, and, when selected by local policy, an optional policy-freshness input consisting of a digest-identified profile and its required evidence, the verifier MUST:¶
Parse every object under its declared closed-object rules.¶
Recompute the canonical action digest and require equality with the Authorization Artifact and CPO.¶
Verify and project the Authorization Artifact under the claimed ABP and Authorization Trust Profile, require both digests and the projected tuple to match the CPO terms, and identify the authorization issuer.¶
Verify the direct binding or companion binding statement.¶
Recompute the CPO digest and require equality with the bound digest.¶
Require equality of authorization_id and action_digest across all objects.¶
Verify the CPO issuer signature and require the issuer to be the authorization issuer or an authority explicitly accepted by local policy.¶
Verify the selected pre-execution evidence profile for the same CPO digest and classify the evidence without treating an executor claim as physical proof of execution order.¶
Verify time validity and replay constraints.¶
Verify the digests of the Standing Policy, procedure, and selection policy. If the optional policy-freshness input is present, verify its digest-identified profile and required evidence and derive policy_freshness; if that input is absent or cannot be evaluated, return indeterminate for that field.¶
Recompute terms_digest and forum_terms_digest; verify either the Exact Forum Acceptance Statement or the FAM signature and digest.¶
For exact acceptance, require the accepted forum_terms_digest to match. For class acceptance, require the successfully applied ABP and Authorization Trust Profile digest pair to appear in the FAM and require all forum-relevant CPO terms to satisfy the FAM constraints.¶
Recompute selection_input from terms_digest and the verified acceptance evidence digest; verify each item of selection evidence against that exact input and the local trust profile.¶
Derive selection provenance as specified in Section 6.1, accounting for role co-location under the local trust profile.¶
Parse the effect policy as a closed object. For an active mode, verify every referenced profile digest, require the trigger profile to match the submission-receipt profile authenticated by the forum acceptance evidence, and verify the named executor under the selected trust profile.¶
Verify any Executor Effect Acceptance Statement against the exact Authorization Artifact, action, CPO, effect policy, forum acceptance evidence, executor identity, validity interval, and execution or refusal record. Do not infer application from acceptance.¶
Verify any Contestability Notice and classify it as issued, invalid, or absent; evaluate delivery evidence only when a selected transport profile defines it.¶
Evaluate each declared affected-party access method under the selected profile and derive access_binding from the integrity and profile constraints of those declarations. Evaluate retrievability separately; do not infer current availability from a signed URI.¶
Verify the event evidence named by filing_window.basis, compute the closing time, and return indeterminate if the required clock input is unavailable.¶
Verify any filing receipt under the exact trigger profile, forum key, Authorization Artifact digest, identifiers, CPO digest, time, and replay rules. Distinguish an accepted filing from a refused or invalid submission.¶
Verify any Effect Application Record against the exact policy, executor acceptance, trigger receipt, executor key, idempotency profile, state-machine profile, and application deadline.¶
Separately evaluate whether the trigger, application, execution, and finality transitions are ordered under the bound serialization profile. Do not substitute signed wall-clock fields for the required ordering evidence.¶
Return the structured result in Section 6.2.¶
An Authorization Artifact, CPO issuer signature, direct or companion binding, identifier, or action-digest failure makes binding invalid. A forum-acceptance failure changes forum_acknowledgement; a selection-signature failure changes selection_provenance; a notice failure changes notice_evidence; missing filing-clock evidence changes filing_window_status; and an effect acceptance, trigger, application, or ordering failure changes only its corresponding effect result. Those failures MUST NOT be collapsed into or misreported as a cryptographic binding failure. Failure to retrieve an otherwise valid digest-bound procedure makes discoverability incomplete; it does not rewrite a valid cryptographic binding as invalid.¶
The verifier derives exactly one value:¶
unilateral: only the authorization issuer selected or authenticated the forum;¶
multiparty: every selector role required by the local selection profile signed the same selection_input;¶
external: a locally trusted external Selection Authority selected or authenticated the forum under the referenced policy;¶
indeterminate: evidence is missing, invalid, ambiguous, or unsupported.¶
multiparty and external describe authenticated selection provenance. Neither means independent.¶
{
"binding": "valid | invalid",
"pre_execution_evidence": "executor_attested | transparency_prior | absent | invalid | not_claimed | indeterminate",
"discoverability": "complete | incomplete",
"forum_acknowledgement": "valid_exact | valid_class | invalid_scope | invalid | absent | indeterminate",
"forum_operational_status": "reachable | unreachable | not_checked | indeterminate",
"selection_provenance": "unilateral | multiparty | external | indeterminate",
"access_binding": "valid | invalid | not_claimed | indeterminate",
"notice_evidence": "issued | delivered | invalid | absent | not_claimed | indeterminate",
"retrievability": "available | unavailable | not_checked | indeterminate",
"filing_window_status": "not_open | open | closed | indeterminate",
"policy_freshness": "current | stale | indeterminate",
"declared_effect": "none | hold_before_execution | fence_after_execution | invalid | unsupported",
"effect_acceptance": "executor_accepted | absent | invalid | not_required | indeterminate",
"effect_trigger": "valid | refused | invalid | not_observed | not_applicable | indeterminate",
"effect_ordering": "verified | invalid | not_evidenced | not_applicable | indeterminate",
"effect_application": "executor_claimed_applied | executor_claimed_refused | too_late | already_applied | failed | invalid | not_observed | not_applicable | indeterminate",
"reasons": ["closed reason codes"]
}
¶
access_binding reports the integrity and selected-profile status of the declared affected-party access methods. It is valid when the required access declarations are present, covered by the verified CPO binding and signature, and satisfy the selected access-profile constraints; invalid when a required declaration or binding fails; not_claimed when the selected profile makes no affected-party access claim; and indeterminate when required evidence or profile interpretation cannot be completed. It does not report delivery or current retrievability.¶
policy_freshness is current only when a selected policy-freshness profile supplies authenticated freshness, version, or expiry rules and all required policy material satisfies them; stale only when such a profile is evaluable and its bound rule classifies required material as stale; and indeterminate when no selected freshness profile exists or its required evidence cannot be evaluated. CBAP-1 defines no policy-freshness profile and therefore returns indeterminate on its positive path.¶
Every named profile that instantiates the Section 6.2 structured result MUST define a closed vocabulary for reasons and a deterministic rule for populating and ordering that array on negative results. CBAP-1 defines its closed reason vocabulary and first-failure precedence in the CBAP-1 failure-precedence section below, and requires reasons: [] on its positive path.¶
A conforming implementation MUST NOT collapse this result into contestable: true or independent: true without applying an explicitly identified local policy. In particular, forum_acknowledgement: valid_exact does not imply forum_operational_status: reachable; notice_evidence: issued does not imply human receipt; effect_acceptance: executor_accepted does not imply that a filing occurred; effect_trigger: valid does not imply application; and effect_application: executor_claimed_applied does not prove physical state or remedy. An effect failure does not invalidate the contestation path unless a separate local policy expressly requires the effect as a condition of reliance.¶
The effect fields are derived independently. At minimum, a verifier applies the following rules:¶
| Evidence state | Acceptance | Trigger | Ordering | Application |
|---|---|---|---|---|
Declared mode is none
|
not_required
|
not_applicable
|
not_applicable
|
not_applicable
|
| Active mode, no acceptance statement |
absent
|
evaluated if supplied |
not_applicable until a valid trigger exists |
invalid if a record claims application; otherwise not_observed
|
| Valid acceptance, no filing receipt observed |
executor_accepted
|
not_observed
|
not_applicable
|
not_observed
|
| Valid acceptance, refused filing receipt |
executor_accepted
|
refused
|
not_applicable
|
not_observed
|
| Valid acceptance and trigger, no application record |
executor_accepted
|
valid
|
not_evidenced unless independently established |
not_observed
|
Valid record with disposition: applied, verified ordering |
executor_accepted
|
valid
|
verified
|
executor_claimed_applied
|
Valid record with disposition: applied, ordering unavailable |
executor_accepted
|
valid
|
not_evidenced or indeterminate
|
executor_claimed_applied
|
| Invalid or mismatched application record | preserve prior result | preserve prior result | independently evaluated |
invalid
|
| Conflicting valid executor records with no deterministic resolution | preserve prior result | preserve prior result |
indeterminate if affected |
indeterminate
|
The penultimate positive row is intentionally non-collapsed: it reports what the executor key claimed while refusing to report that the claim was correctly ordered against execution or finality. A user interface MUST NOT present that tuple as an effective hold or fence. Evidence supplied for an active transition when the declared mode is none is ignored for effect semantics. An implementation SHOULD retain an unexpected_effect_evidence operator diagnostic outside the reasons array; it does not alter the bound declaration.¶
In addition to the generic algorithm, a CBAP-1 verifier performs the following closed procedure in order:¶
Validate the verification-time input as an integer in 0..18446744073709551615. Return verification_time_invalid on a parse, type, sign, or range failure without parsing the bundle.¶
Parse the outer bundle without accepting duplicate keys, indefinite-length items, non-shortest arguments, disallowed tags or simple values, floats, invalid UTF-8, unknown members, values outside cbap1-bundle, or any declared length that cannot be consumed with checked cursor arithmetic. Re-encode the parsed bundle under Section 4.13 and require byte-for-byte equality.¶
Require every policy pair to contain exactly one 32-byte digest and one byte string. Reject duplicate policy digests. Recompute SHA-256 over each policy byte string and require equality. At this step only the internal shape, order, uniqueness, and digest integrity of the policy set are evaluated; referenced-policy presence is evaluated after the signed payloads are validated.¶
Parse each object byte string as exactly one tagged COSE_Sign1 object. Require the protected and unprotected header rules of Section 4.14, an embedded deterministic payload, a recognized profile version and object type, and exact kid equality between the protected header and payload signer field.¶
Resolve each kid in the supplied trust profile to exactly one Ed25519 public key authorized for the required issuer, forum, or executor role. Verify every signature over the received protected and payload bytes with empty external AAD.¶
Recompute action_digest from the bundle's action bytes. Require the same digest at terms label 6, Authorization Artifact label 6, executor-verification label 5, and execution-record label 6.¶
Require the CPO terms to use the expected CBAP-1 ABP digest and Authorization Trust Profile digest. Require effect policy [0], filing-window basis [1, duration] with duration in 1..18446744073709551615, at least one public-transparency access entry, an empty selection-statement array, by-value bytes for every policy referenced by the CPO and Exact Forum Acceptance, conforming HTTPS URIs, and all other single-object CBAP-1 profile constraints not assigned below to a cross-object boundary. Do not compare the Authorization Artifact projection or any signed-artifact digest at this step.¶
Require the Authorization Artifact's authorization identifier, issuer key, action digest, and validity projection to equal the corresponding CPO terms. Do not compare its CPO digest at this step.¶
Project forum_terms exactly as Section 4.16 specifies. Verify its digest in the forum's exact acceptance, the forum signature and key, and the equality of the CPO forum key and acceptance signer key.¶
Hash the complete signed exact acceptance and require equality with the CPO acceptance reference.¶
Hash the complete signed CPO and require equality with the Authorization Artifact's CPO digest.¶
Hash the complete signed Authorization Artifact and require equality at executor-verification label 3 and execution-record label 3.¶
Verify the executor verification record, require decision execute, and require its authorization identifier at label 4, action digest at label 5, CPO digest at label 6, executor key, nonce, and verified-at value to match the bound objects and profile.¶
Hash the complete signed executor verification record. Verify the execution record and require that digest at label 4, the authorization digest at label 3, authorization identifier at label 5, action digest at label 6, executor key, nonce, and disposition executed all match.¶
Require not-before <= verified-at <= executed-at <= not-after.¶
Compute filing_deadline = executed-at + duration-seconds with checked unsigned arithmetic. Require the Exact Forum Acceptance signed-at <= not-before, valid-from <= not-before, and valid-until >= filing_deadline; require CPO issued-at <= verified-at and expires-at >= filing_deadline; and require at least one declared access method with available-until >= filing_deadline. Compare the supplied verification time with executed-at and the deadline to derive not_open, open, or closed.¶
Return every Section 6.2 field independently. The positive CBAP-1 path yields binding: valid, pre_execution_evidence: executor_attested, discoverability: complete, forum_acknowledgement: valid_exact, forum_operational_status: not_checked, selection_provenance: unilateral, access_binding: valid, notice_evidence: not_claimed, retrievability: not_checked, policy_freshness: indeterminate, declared_effect: none, effect_acceptance: not_required, effect_trigger: not_applicable, effect_ordering: not_applicable, effect_application: not_applicable, and reasons: []; filing_window_status is derived as not_open, open, or closed from the supplied verification time. It does not yield forum reachability, delivery, independence, policy fairness, or physical execution order.¶
A deterministic-encoding, COSE structure, signature, required role, action digest, CPO digest, authorization digest, verification-record digest, identifier, validity, or ordering failure MUST produce a closed reason code identifying the first failed boundary. The implementation MUST continue to keep unrelated higher-level results separate where the failed input still permits them to be evaluated safely.¶
CBAP-1 closes the externally observable failure boundary. On the positive path, reasons MUST be the empty array. On a negative path, reasons MUST contain exactly one of the codes in the table below: the first failing boundary under the stated precedence. An implementation MAY retain more detailed diagnostics for operators, but it MUST NOT place implementation-specific strings in reasons or substitute a later, more specific failure for the first one.¶
| Precedence | Reason code | Boundary |
|---|---|---|
| 1 |
verification_time_invalid
|
The supplied verification time is not an unsigned integer representable in CBAP-1. |
| 2 |
outer_encoding_invalid
|
The outer item is truncated, has trailing bytes, violates Core Deterministic CBOR, or uses a forbidden CBOR construct. |
| 3 |
bundle_schema_invalid
|
The outer item is not the closed cbap1-bundle, has an unsupported profile version, or contains a member of the wrong CDDL type. |
| 4 |
policy_set_invalid
|
The policy array is empty, unsorted, duplicated, malformed, or internally digest-inconsistent. |
| 5 |
cpo_invalid
|
The CPO COSE envelope, payload schema, object type, kid, role resolution, or signature is invalid. |
| 6 |
forum_acceptance_invalid
|
The Exact Forum Acceptance COSE envelope, payload schema, object type, kid, role resolution, or signature is invalid. |
| 7 |
authorization_invalid
|
The Authorization Artifact COSE envelope, payload schema, object type, kid, role resolution, or signature is invalid. |
| 8 |
executor_verification_invalid
|
The executor-verification COSE envelope, payload schema, object type, kid, role resolution, or signature is invalid. |
| 9 |
execution_record_invalid
|
The execution-record COSE envelope, payload schema, object type, kid, role resolution, or signature is invalid. |
| 10 |
action_digest_mismatch
|
The action bytes do not hash to the one action digest required across the four signed payloads that carry it: CPO terms label 6, Authorization Artifact label 6, Executor Verification label 5, and Execution Record label 6. |
| 11 |
profile_binding_mismatch
|
The ABP, Authorization Trust Profile, effect mode, filing-window form or non-zero duration, referenced-policy presence, access form, HTTPS URI syntax, signer identity, validity form, or other mandatory CBAP-1 profile constraint does not match the supplied trust inputs and closed profile. |
| 12 |
authorization_projection_mismatch
|
The Authorization Artifact projection does not equal the authorization identifier, issuer, action digest, or validity required by the CPO terms. The signed CPO digest is evaluated only at precedence 15. |
| 13 |
forum_terms_mismatch
|
The accepted forum-terms digest is not the exact projection defined in Section 4.16, or the forum identifier and forum key are inconsistent. |
| 14 |
acceptance_binding_mismatch
|
The complete signed acceptance digest is not the digest bound into the CPO. |
| 15 |
cpo_binding_mismatch
|
The complete signed CPO digest is not the digest bound into the Authorization Artifact. |
| 16 |
authorization_digest_mismatch
|
The complete signed Authorization Artifact digest is not the digest bound into both executor records. |
| 17 |
executor_verification_mismatch
|
Executor Verification label 4 does not carry the bound authorization identifier, label 5 does not carry the action digest, label 6 does not carry the CPO digest, or its decision, key, nonce, or verification time is invalid or inconsistent. |
| 18 |
execution_record_mismatch
|
Execution Record label 4 does not bind the exact executor-verification record, label 5 does not carry the authorization identifier, label 6 does not carry the action digest, or its authorization digest, executor key, nonce, or required disposition is invalid or inconsistent. |
| 19 |
executor_ordering_invalid
|
The authenticated executor times do not satisfy authorization validity and verified-at <= executed-at. |
| 20 |
filing_deadline_overflow
|
Adding the filing duration to executed-at exceeds the CBAP-1 unsigned-integer range. |
| 21 |
filing_horizon_invalid
|
Exact Forum Acceptance signed-at is after not-before, valid-from is after not-before, or valid-until is before the filing deadline; CPO issued-at is after executor verified-at or expires-at is before the filing deadline; or no affected-party access declaration remains valid through the filing deadline. |
The verifier evaluates local input 1 first, then the outer item, the policy set, and the five signed objects in table order. Within a signed object it evaluates: tagged COSE_Sign1 shape; protected and unprotected headers; embedded deterministic payload; closed payload schema; protected-to-payload kid equality; unique role-authorized trust resolution; and signature. Within a closed map, member constraints are evaluated in ascending numeric-label order. Within a list, items are evaluated from index zero upward. Cross-object checks then follow precedence 10 through 21.¶
The first-reason rule is a reproducibility rule, not permission to collapse the Section 6.2 result. A verifier still evaluates independently derivable fields when doing so is safe. Fields that depend on the failed boundary take their existing invalid, incomplete, indeterminate, or not_checked value. In particular, policy_set_invalid does not by itself prove binding: invalid, and a reachability failure is outside this closed CBAP-1 byte-verification procedure.¶
The common pre-execution sequence is: forum manifest or exact acceptance; Contestation Terms; selection signatures; signed CPO; signed authorization binding; executor verification; optional Executor Effect Acceptance Statement; and an executor record binding the verification and, when present, effect-acceptance digests.¶
The remaining order depends on the effect mode:¶
| Mode | Required protocol order |
|---|---|
none
|
execution or refusal; notice, delivery, or publication; optional filing |
hold_before_execution
|
accepted filing receipt; verified trigger ordering before the execution boundary; Effect Application Record; executor hold or refusal record binding that application record |
fence_after_execution
|
execution; notice, delivery, or publication; accepted filing receipt; verified trigger ordering before finality; Effect Application Record |
An external dispute procedure, if any, is outside this document and may continue after any of those rows. This document ends after authenticating the filing-trigger and the executor's claimed state transition. It neither defines adjudication nor converts a hold or fence into a remedy.¶
Changing the forum, procedure, Standing Policy, filing window, or effect policy requires a new CPO and a new authorization binding. An active effect additionally requires a new Executor Effect Acceptance Statement. A replacement MUST NOT narrow an already-open filing window instantiated by the prior binding for an action that has executed unless the previously bound procedure itself authorized that transition.¶
This section follows the guidance in [RFC7942] and is intended to be removed before publication as an RFC.¶
As of 12 August 2026, CBAP-1 has a Python reference implementation, an oracle-blind Rust reconstruction produced with AI-based coding assistance in a context-isolated session, and a JavaScript cross-check. The cross-check re-encoded the positive bundle byte-for-byte and verified all five Ed25519 signatures. The shared positive bundle has SHA-256:¶
8a47e89abb2c77a9de27ffb59a5bc89a7226509236e35b0f11cf6819fd1b6646¶
The reconstruction received the specification and its declared public inputs without evaluator answers. The evidence record distinguishes mechanical byte access for integrity hashing from semantic evaluator access: before the relevant implementation freeze, no evaluator case was decoded, semantically inspected, or executed, and expected outcomes and reasons remained withheld.¶
The first frozen reconstruction assigned two digest labels differently from the retained evaluator and failed bidirectional verification at that boundary. The supplied challenge text had typed both members without assigning their labels in normative prose. That divergence was recorded before repair, and the original submission remains frozen at SHA-256:¶
956b88d2832e4265913cb73f93e69b960ef6f1d860f8acbc5b50ea453cbab2f0¶
After the assignment and other attributable ambiguities were repaired in the specification, the final A3 source-and-artifact package was frozen at SHA-256:¶
f2b9b0745ca8b751322f416ed62e73769b2396934b8beb811d5f71b4fc88b129¶
The reconstruction passed 56 local tests. It matched the retained evaluator outcomes
for the positive byte vector, the closed failure-precedence corpus, and all 28
URI cases. The URI result comprised eight valid acceptances and 20
profile_binding_mismatch rejections, with each case invoked once. Additional
differential checking of 255,022 generated IPv6 candidates found no divergence.¶
Automated tools could propose source, test, and analysis candidates, but did not assign evaluator outcomes. Recorded outcomes were determined under pinned rules and inputs after the corresponding implementation state had been frozen. The document author controlled the specification, evaluator design, retained inputs, and adjudication. The experiment therefore tests specification reconstructibility, ambiguity detection, and bounded behavioural agreement; it does not establish independence of authorship or evaluation.¶
The results do not constitute an independent human implementation, external review, interoperability certification, production deployment evidence, exhaustive parser safety, or a security audit.¶
A stable public location and an explicit software license for the implementation and evidence packages are to be designated as part of the verifiable release publication that follows this submission. Until then, this section records development evidence but does not claim public implementation or evidence-package availability.¶
Implementation and test-package contact: Tiago Pinto tiago@donttrustverify.pt.¶
A discoverable forum can still be captured. An issuer-only signature therefore yields unilateral, never external or multiparty.¶
The forum identifier, endpoint, verification key, procedure, and selection policy are digest- or signature-bound. A verifier MUST refuse substitution after authorization.¶
Serving different CPOs or policy documents to different audiences can move the fork from the authorization to the contestation layer. Deployments claiming cross-audience consistency SHOULD register CPOs or their digests in a transparency service and MUST define how readers detect split views.¶
Cryptographic binding and forum acknowledgement do not prove availability. A forum can refuse connections, selectively deny classes of filers, or disappear after signing. Availability evidence and service-level enforcement are deployment concerns. Discoverability MUST become incomplete when required material cannot be obtained within local policy. A failed reachability check MUST NOT retroactively invalidate a historically valid acknowledgement; the results remain separate.¶
An issuer can declare a filing window too short to use. Verification authenticates the declared filing-window inputs and computes the window; it does not establish fairness. Relying parties SHOULD apply minimum-window policy and MUST NOT infer legitimacy from syntactic validity.¶
A Standing Policy can exclude the person most affected by an action. This document makes the policy identity stable and, when the policy bytes are available, inspectable; it does not make the policy legitimate. Profiles claiming affected-party recourse MUST specify how affected parties are represented without requiring them to have participated in the original authorization.¶
Enumerating affected persons in a public CPO can create a privacy and safety risk. Standing SHOULD be expressed by role or policy where possible. Personally identifying evidence SHOULD be disclosed only to the forum under an appropriate confidentiality mechanism.¶
Attackers can submit repetitive or fabricated filings. Anti-replay, rate limiting, authentication, and abuse controls MUST NOT silently alter the bound standing policy or filing window.¶
An action can disable the only credential accepted by the contestation lookup or forum. An account-suspension action followed by an account-login-only contestation path is the canonical case. Profiles claiming affected-party access MUST define a surviving method, such as a separately delivered capability, an alternate verified identity, or a privacy-preserving public lookup. Merely declaring an authentication profile does not prove survivability.¶
An issuer can replay genuine forum acceptance evidence issued for a different ABP, Authorization Trust Profile, policy version, binding interval, or submission endpoint. Exact acknowledgements MUST match the forum_terms_digest. A FAM MUST bind accepted ABP and Authorization Trust Profile digest pairs, and the Authorization Artifact MUST be successfully verified and projected under a listed pair. Matching labels or URIs are insufficient. Failure to establish membership yields invalid_scope, not valid_class.¶
A signer can generate a valid Contestability Notice and never transmit it. The base result is therefore issued, not delivered. A delivered result requires an authenticated transport-specific receipt that identifies the same notice digest and intended delivery context. No protocol receipt proves that a human read or understood the notice.¶
A malicious notice can direct an Affected Party to an attacker-controlled endpoint or can use predictable authorization identifiers to expose sensitive actions. The notice MUST bind the CPO digest and authenticated access method. Deployments SHOULD use unguessable lookup capabilities or privacy-preserving authenticated retrieval when public correlation would reveal sensitive information.¶
An issuer can construct a valid CPO after execution and backdate issued_at. Signatures establish integrity and signer attribution, not when an executor possessed an object. A profile claiming pre-execution enforcement MUST carry authenticated ordering evidence from the enforcement path. Without it, the binding can remain cryptographically valid while pre_execution_evidence is absent. Even executor_attested proves only the executor key's signed claim and digest bindings, not the physical order of events inside the executor.¶
Exact acceptance exposes at least a stable terms digest and interaction timing to the forum before authorization. Depending on the action space, an unsalted action digest can also permit dictionary attacks. Deployments SHOULD prefer a class manifest when instance-specific acceptance is unnecessary, SHOULD register only a CPO or manifest digest in public transparency infrastructure, and SHOULD use profile-defined salted commitments for low-entropy action data where cross-artifact verification remains possible.¶
A forum can issue different FAMs to different audiences or replace a restrictive manifest with a broader one. The CPO and selection signatures bind one exact manifest digest, so substitution fails locally. Cross-audience detection requires transparency or gossip under a selected profile. A verifier MUST NOT select a newer, broader, or more available manifest in place of the digest bound by the CPO.¶
Key rotation MUST NOT permit a new forum key to rewrite old acceptance evidence. Historical verification requires the key that signed the exact statement or manifest, its validity evidence at signing time, and the selected compromise policy. A successor key can sign a new manifest or a continuity statement only under the previously bound withdrawal policy. A current key-discovery response alone is insufficient to validate a historical signature.¶
Multiple signatures do not necessarily represent multiple independent parties. An issuer can operate separate issuer, forum, and selector keys. Selection provenance therefore depends on role authorization and controlling trust domains supplied by local policy, not signature count. Three keys under one controlling party MUST NOT be reported as multiparty merely because all three signatures verify.¶
An issuer can publish an active effect policy while naming an executor that never agreed to implement it. The CPO signature authenticates that advertisement but not executor acceptance. Without a valid Executor Effect Acceptance Statement, effect_acceptance is absent or invalid; an implementation MUST NOT display the action as automatically held, fenced, stayed, or reversible. If the executor accepted and later ignores a valid trigger, the acceptance remains valid while application is not_observed, failed, or indeterminate as the evidence permits. Nonperformance MUST NOT be rewritten as a binding failure.¶
A valid filing receipt can be replayed against another authorization, CPO, policy, executor, or state transition. All identifiers and digests in Sections 5.4 and 5.5 MUST match, and the bound idempotency profile MUST make repeated processing deterministic. A receipt created under a different forum key or submission-receipt profile is not a trigger even if the bytes describe the same filing. Reusing a valid trigger to create multiple transitions yields already_applied or an equivocation condition, not multiple applications.¶
An attacker or merely concurrent system can cause the filing trigger and the execution or finality transition to cross between verification and application. Signed timestamps do not solve this time-of-check/time-of-use race. An active effect profile MUST bind a serialization mechanism enforced by the system of record, such as an authenticated monotonic sequence, compare-and-swap precondition, or atomic transaction. If the verifier cannot establish the required ordering, effect_ordering is not_evidenced or indeterminate, even when the executor signed disposition: applied.¶
An automatic hold can let inexpensive filings block expensive or urgent actions. The trigger profile can authenticate submissions, rate limits, deposits, or eligibility gates, but those controls MUST be bound before execution and MUST NOT silently change the Standing Policy or filing window. A forum receipt authenticates a record that the filing was accepted under the forum profile; it does not prove that the filer deserved to stop the action. Deployments SHOULD prefer fence_after_execution or none where pre-execution holds create unacceptable safety or availability risk.¶
An executor can claim applied while committing to a state encoding whose meaning is mutable, partial, or compatible with both fenced and unfenced outcomes. The state-machine profile and target-state digest MUST define the committed state and transition unambiguously. Unsupported, lossy, or non-deterministic state projection yields effect_application: indeterminate or invalid; signature validity alone is insufficient.¶
A hold result is satisfied only when the bound evidence records the profile-defined hold state and the required ordering places that record before the execution boundary. A fence result is satisfied only when the bound evidence records the profile-defined fence state and the required ordering places that record after execution and before the finality boundary. Neither result proves reversal of earlier observations, compensates an Affected Party, determines liability, or authorizes a new action. Implementations MUST NOT label an Effect Application Record as an award, reversal, restoration, refund, or remedy unless a separate protocol and authorization establish that result.¶
An executor can sign conflicting application records or share control with the issuer and forum. Conflicting records for the same idempotency key and sequence are equivocation evidence. Common control does not invalidate the signatures, but it weakens the governance inference a relying party may draw from them. This protocol reports authenticated role statements and never upgrades them to independent enforcement.¶
An Effect Executor can accept a hold or fence while lacking authority over the action executor or finality state. A message bus subscription or advisory callback is not control of the transition. When the parties differ, the serialization profile MUST bind the cross-system state machine, signer roles, and atomic or fail-closed handoff. Without that evidence, effect_acceptance can remain executor_accepted, but effect_ordering is not_evidenced or invalid and no effective hold or fence can be reported.¶
EP authorization receipts [I-D.schrock-ep-authorization-receipts] bind human evidence to an action and record authorization lifecycle facts. Other EP artifacts describe outcome, revocation, remedy, and reliance evidence.¶
This document specifies a transport-independent, pre-execution binding from an authorization to the contestation path, with a derived statement of forum-selection provenance. It neither replaces nor requires EP.¶
The Agentic Dispute Protocol [I-D.kotecha-agentic-dispute-protocol] defines filing, evidence, adjudication, awards, and arbitrator discovery. ADRP [I-D.stone-adrp] defines an Arbitration Mandate, dispute state machine, arbitrator pool, rulings, appeals, and remedy directives.¶
This document does none of those things. A CPO can identify an ADP or ADRP endpoint and procedure. Its contribution is the binding and verification layer that exists before either dispute protocol begins, including the distinction between issuer-declared and non-unilateral forum selection.¶
A CPO or companion binding statement can be registered as a SCITT Signed Statement [RFC9943]. SCITT registration can improve discoverability and equivocation detection but does not prove forum independence, policy fairness, or legal validity.¶
The reusable FAM has a role analogous to an endorsement in the RATS architecture [RFC9334]: a role-specific signer vouches for defined capabilities or scope, while the relying party applies its own policy. It is not attestation evidence and does not appraise a runtime. CBAP-1 selects tagged COSE_Sign1 with embedded payloads and fully specified Ed25519 signatures. It does not use COSE_Sign multi-signatures: each role emits a separate signed statement so that signature topology and failure attribution remain explicit.¶
The initial individual draft requests no IANA action. A later protocol revision may request media types, a well-known URI, or a registry of structured reason codes after the encoding and deployment model stabilize.¶
AI-based tools were used during the development and evaluation of this work. The author made the design decisions, reviewed and approved the submitted text, and remains solely responsible for its content and technical claims.¶