See: docs/spec/eta-core-v1.md for the minimal Execution-Time Authorization profile. Locked conformance vectors are published for canonicalization, authorization, PEP, and delegation, and pass across TypeScript, Go, and Python verification harnesses executed in CI. AuthorizationV1, PEP Gateway, and DelegationV1 are specified as Stable normative artifacts. SPEC overall remains v1.3.0.
This is the canonical normative specification for the OxDeAI protocol. Other documents (e.g. under /protocol) are companion references and must not be treated as normative.
This document defines the OxDeAI execution authorization protocol.
OxDeAI is a portable, language-agnostic protocol for deterministic pre-execution authorization and post-execution evidence verification in autonomous systems.
Artifact stability is defined per artifact. The SPEC version (v1.3.0) does not imply instability of individual artifacts. AuthorizationV1, DelegationV1, and the PEP Gateway are Stable normative artifacts as defined in docs/spec/**.
docs/spec/**→ normative (protocol definitions)docs/**→ non-normative (guides, architecture, examples)
If a conflict exists, docs/spec/** is authoritative.
docs/spec/core/canonicalization-v1.mddocs/spec/core/eta-core-v1.md
docs/spec/artifacts/authorization-v1.mddocs/spec/artifacts/delegation-v1.md
docs/spec/enforcement/pep-gateway-v1.md
docs/spec/verification/verification-v1.md
docs/spec/conformance/conformance-v1.mddocs/spec/conformance/test-vectors-v1.md
The protocol defines:
- portable authorization artifacts
- deterministic policy evaluation requirements
- canonical signing and verification rules
- a relying-party execution contract
- verifiable evidence artifacts
OxDeAI separates authorization decision logic from execution. A Policy Decision Point (PDP) evaluates whether an action is allowed. A Policy Enforcement Point (PEP) verifies authorization artifacts and executes the action only if verification succeeds.
The TypeScript implementation in this repository is the reference implementation of this protocol, but conformant implementations MAY exist in any language if they reproduce the same artifacts and verification behavior.
No valid authorization
→ no execution path
Normative protocol text uses RFC 2119 terms: MUST, MUST NOT, SHOULD, SHOULD NOT, MAY.
Note: locked conformance vectors are currently published only for canonicalization; PEP/Authorization/Delegation are validated via harnesses until vectors are added.
OxDeAI defines deterministic pre-execution authorization and post-execution evidence verification for autonomous systems.
A conformant implementation MUST produce deterministic outputs for equivalent inputs and MUST enforce the relying-party verification contract before execution occurs.
The protocol defines portable artifacts that can be issued by one system and verified by another, including across language runtimes or infrastructure boundaries.
OxDeAI is protocol-first:
- this repository provides the reference implementation
- other implementations MAY exist in other languages
- conformance is defined by protocol artifacts and verification behavior
Implementations are compliant if they reproduce the protocol artifacts defined in this specification and satisfy the conformance vectors for the targeted version profile.
OxDeAI defines the following first-class protocol artifacts. These artifacts are language-independent and MUST be interpreted identically across compliant implementations.
- Intent
- CanonicalState snapshot
- AuthorizationV1
- DelegationV1
- Audit events (hash chained)
- VerificationEnvelopeV1
- VerificationResult
- KeySet
Determinism is a core protocol invariant.
For identical (intent, state, policy configuration) inputs, a conformant implementation MUST produce identical authorization decisions and identical signed artifacts.
Implementations MUST use canonical encoding for signed and hashed payloads. Verification ordering and violation ordering MUST be deterministic. Policy-critical logic MUST NOT depend on ambient randomness. Malformed or ambiguous artifacts (including canonicalization failure) MUST be treated as DENY/fail-closed.
The core evaluation model is:
(intent, state, policy) → deterministic decision
The following requirements govern this model:
stateMUST be an explicit, discrete input to evaluation.stateMUST be deterministic for a given evaluation: the samestatevalue MUST produce the same decision when paired with the sameintentandpolicy.- Evaluation MUST NOT depend on implicit or external mutable context.
- Evaluation MUST be side-effect-free with respect to the input
state.
Implementations MAY maintain an internal mutable working copy of state during evaluation to accumulate module deltas. Implementations MUST NOT mutate the input state object through any such internal working state.
state.policy_version MUST equal the policy_version under which evaluation is performed.
If a mismatch is detected, evaluation MUST fail with:
POLICY_VERSION_MISMATCH
This check MUST be performed before any policy module runs. A POLICY_VERSION_MISMATCH denial is a structural evaluation failure, not a policy decision.
This invariant ensures that authorization artifacts are issued only under the policy version that was in effect when the intent was evaluated, preventing replay of artifacts across incompatible policy versions.
Concurrent evaluations MUST NOT share a mutable state object.
The state input to evaluation MUST be treated as an immutable snapshot for the duration of that evaluation. Implementations MUST ensure that each evaluation receives an isolated state instance. Sharing a mutable state object across concurrent evaluations is a protocol violation.
Rationale. Evaluation semantics are defined as a pure function of (intent, state, policy). If multiple concurrent evaluations share and mutate the same state object, the outcome of each evaluation becomes dependent on execution order and timing, violating the determinism requirement in Section 3.
Implications:
- Implementations MAY internally derive a working copy of state per evaluation.
- Callers MUST provide an isolated snapshot per evaluation call.
- Concurrent evaluations MUST NOT produce cross-call side effects on shared state.
Violation of this invariant results in undefined behavior: evaluations may produce non-deterministic decisions for identical inputs.
OxDeAI artifacts are language-agnostic protocol artifacts. Compliant implementations MAY be written in any language.
- Implementations MUST use protocol-defined canonical JSON rules.
- Implementations MUST reconstruct identical signing input bytes for signed artifacts.
- Implementations MUST verify Ed25519 signatures over the canonical payload and domain format defined by this protocol.
- Implementations MUST fail closed on:
- malformed payloads
- unsupported algorithms
- unknown key ids
- signature mismatch
- verification ambiguity
The TypeScript implementation is the reference implementation. Other implementations are compliant if they satisfy this specification and pass conformance vectors for the targeted version profile.
Compliant verifier behavior SHOULD include this sequence:
- Parse artifact and validate required fields.
- Canonicalize payload deterministically.
- Reconstruct signing input bytes exactly.
- Verify signature and key resolution (
alg,kid, issuer trust context). - Validate issuer/audience/policy binding constraints.
- Validate expiry and decision semantics (
ALLOWwhen required). - Fail closed on any malformed or ambiguous verification state.
AuthorizationV1 is the primary authorization artifact defined by the OxDeAI protocol.
It represents a deterministic authorization decision issued by a Policy Decision Point (PDP) and verified by a relying party, also referred to as a Policy Enforcement Point (PEP).
AuthorizationV1 is a portable protocol artifact, not an implementation detail.
It is designed to be verifiable independently of the system that produced it.
AuthorizationV1 is a portable authorization artifact issued by the OxDeAI Policy Decision Point (PDP) to permit a specific action under a specific policy state.
It is consumed by a relying party, also referred to as a Policy Enforcement Point (PEP), and MUST be verified before execution.
AuthorizationV1 is a first-class protocol artifact. It represents a decision bound to identity, audience, intent, state, policy context, and time.
An AuthorizationV1 artifact MUST include all of the following fields:
auth_idissueraudienceintent_hashstate_hashpolicy_id(may be namedpolicy_versionin artifacts; issuer and verifier MUST use a consistent field name)decisionissued_atexpiryalgkidsignature
Optional extension fields MAY include:
noncecapability
Implementations MAY carry additional metadata only if such metadata does not change the semantics of mandatory fields.
auth_id: Unique authorization identifier for this artifact instance.issuer: Identifier of the authorization issuer and trust domain.audience: Identifier of the relying party for which this authorization is valid.intent_hash: Canonical hash of the intended action to be executed.state_hash: Hash of the policy state snapshot against which authorization was granted.policy_id: Identifier of the policy configuration used for evaluation.decision: Authorization outcome (ALLOWorDENY).issued_at: Issuance time as Unix timestamp (seconds).expiry: Expiration time as Unix timestamp (seconds).alg: Signature algorithm identifier.kid: Key identifier used to select the verification key.signature: Cryptographic signature over the canonical authorization payload.
AuthorizationV1 has the following protocol properties:
- Single-use:
auth_idMUST be treated as consumable exactly once by the relying party. - Issuer-bound: validity is scoped to a trusted
issuer. - Audience-bound: validity is scoped to the designated
audience. - Intent-bound: validity is scoped to the exact
intent_hash. - State-bound: validity is scoped to the exact
state_hash. - Short-lived: validity is bounded by
issued_atandexpiry; expired artifacts are invalid.
These properties are mandatory protocol constraints, not operational recommendations.
Before execution, a relying party MUST verify all of the following:
decision == "ALLOW".- The authorization has not expired (
expiryis in the future under verifier time policy). issueris trusted for the current trust context.audiencematches the current relying-party identity.intent_hashmatches the exact action about to be executed.state_hashbinding is respected by the execution context.policy_idmatches the expected policy context.auth_idhas not already been consumed.algis supported and permitted by local algorithm policy.kidresolves to a trusted verification key for the expected issuer.signaturevalidates against the canonical payload and resolved key.
If any verification step fails, execution MUST NOT occur.
If verification state is ambiguous (for example, unresolved trust state, inconsistent key material, or parse ambiguity), verification MUST fail closed.
A reused auth_id MUST be rejected.
Non-forgeable verification ensures that authorization artifacts can be validated independently of the issuing system.
Verification MUST depend only on the artifact contents, canonical payload rules, and trusted verification keys. No verifier may rely on implicit runtime state or undocumented side channels.
In v1.2, AuthorizationV1 MUST support public-key verification via alg, kid, and signature.
For signed verification:
- The signature MUST be computed over the canonicalized AuthorizationV1 object using
canonicalization-v1rules, excluding thesignaturefield value. - Different artifact classes MUST use distinct signing domains to prevent cross-artifact signature confusion.
- Unsupported algorithms MUST fail closed.
- Canonicalization for authorization payloads MUST follow
docs/spec/canonicalization-v1.md.
Verifiers MUST NOT accept unsigned substitutions for artifacts that require signature validation under local policy.
Older pre-v1.2 authorization paths MAY exist for backward compatibility.
When legacy paths are supported, they SHOULD be explicitly mode-scoped and MUST NOT be confused with public-key verification mode.
Public-key verifiable AuthorizationV1 is the preferred v1.2 form.
{
"auth_id": "auth_01JY7K8Z4V3QH6N2M9P0R1S2T3",
"issuer": "oxdeai.pdp.prod.eu-1",
"audience": "payments.api.eu-1",
"intent_hash": "9f3e5c6ad7a4a2f8a2d93f0f31c65a88f95d7dbef4c9f9e30d5f0f6ce7f4a1b2",
"state_hash": "4e2b7f1a3d8c6e90b5f3a9d7c1e2f4a6b8d0c2e4f6a8b0c1d3e5f7a9b1c3d5e7",
"policy_id": "policy_prod_payments_v42",
"decision": "ALLOW",
"issued_at": 1770001200,
"expiry": 1770001260,
"alg": "Ed25519",
"kid": "2026-01-main",
"signature": "Wm9NQjN4d0M1N1dXQ0x4eFZ4Qm5hV2xQbUQ3SzdqQ0x0QnI0U2pQeQ=="
}DelegationV1 is a signed delegation artifact that allows a principal holding a valid AuthorizationV1 to delegate a strictly narrowed subset of that authority to a child agent.
DelegationV1 is locally verifiable without any control-plane interaction.
It is cryptographically bound to the parent AuthorizationV1 by hash and MUST be verified as a complete chain by the relying party.
DelegationV1 extends the OxDeAI protocol with delegated agent authorization.
It does not replace AuthorizationV1; it derives from it.
DelegationV1 enables a principal that has been authorized by the PDP to sub-authorize a child agent for a narrower set of actions, within the same policy context and time window, without requiring a new PDP evaluation.
The relying party verifies the complete chain - parent AuthorizationV1 and child DelegationV1 - before permitting execution.
A DelegationV1 artifact MUST include all of the following fields:
delegation_idissueraudienceparent_auth_hashdelegatordelegateescopepolicy_idissued_atexpiryalgkidsignature
delegation_id: Unique identifier for this delegation artifact instance.issuer: Identifier of the principal issuing the delegation. MUST equalparent.audience.audience: Intended audience for the delegation (typically the delegatee identifier).parent_auth_hash: SHA-256 hex digest of the canonical parentAuthorizationV1, including itssignaturefield. Used for cryptographic hash binding to the parent.delegator: Identifier of the principal granting authority. MUST equalparent.audience.delegatee: Identifier of the agent receiving delegated authority.scope: Constrained authority granted to the delegatee. MUST be a strict subset of the parent authorization scope. Sub-fields are defined in Section 5.4.policy_id: Policy context identifier. MUST equalparent.policy_id.issued_at: Issuance time as Unix timestamp (seconds).expiry: Expiration time as Unix timestamp (seconds). MUST be less than or equal toparent.expiry.alg: Signature algorithm identifier. MUST beEd25519in v1.3.kid: Key identifier used to select the verification key.signature: Ed25519 signature over the canonical delegation payload, using theOXDEAI_DELEGATION_V1signing domain.
The scope object MAY carry any combination of the following sub-fields:
tools: array of permitted tool or action names. If present, the child agent MUST only execute actions whose name appears in this array.max_amount: maximum permitted amount for a single action (bigint). MUST be less than or equal to anymax_amountin the parent scope if both are present.max_actions: maximum number of actions permitted under this delegation. MUST be less than or equal to anymax_actionsin the parent scope if both are present.max_depth: maximum recursion or nesting depth permitted. MUST be less than or equal to anymax_depthin the parent scope if both are present.
An absent scope sub-field imposes no constraint for that dimension from the delegation artifact itself. A relying party MAY enforce additional scope constraints beyond those carried in the artifact.
DelegationV1 has the following protocol properties:
- Single-use:
delegation_idMUST be treated as consumable exactly once by the relying party. - Issuer-bound: validity is scoped to the delegating principal identified by
issuer. - Audience-bound: validity is scoped to the designated
delegatee. - Parent-bound: validity is cryptographically bound to a specific parent
AuthorizationV1viaparent_auth_hash. A delegation presented with a mismatched parent MUST be rejected. - Policy-bound:
policy_idMUST equalparent.policy_id. Cross-policy delegation is prohibited. - Narrowing-only: delegated scope MUST NOT exceed the parent authorization scope in any dimension.
- Short-lived:
expiryMUST be less than or equal toparent.expiry. A delegation cannot outlive its parent. - Non-forgeable:
signatureMUST validate under theOXDEAI_DELEGATION_V1signing domain and the delegating principal's key.
These properties are mandatory protocol constraints, not operational recommendations.
A DelegationV1 MUST narrow authority relative to the parent authorization.
The following narrowing invariants MUST hold when both child and parent values are present:
scope.tools: child set MUST be a subset of parent set. A tool not present in the parent scope MUST NOT appear in the child scope.scope.max_amount: child value MUST be less than or equal to parent value.scope.max_actions: child value MUST be less than or equal to parent value.scope.max_depth: child value MUST be less than or equal to parent value.expiry: MUST be less than or equal toparent.expiry.
Verifiers MUST enforce these invariants. Scope widening is a protocol violation and MUST be rejected.
When the parent scope is not explicitly known to the verifier, the narrowing invariant for that dimension is the deployer's responsibility. Verifiers SHOULD require explicit parent scope when scope enforcement is a security requirement.
DelegationV1 is a single-hop delegation mechanism.
A DelegationV1 parent MUST be an AuthorizationV1.
A DelegationV1 MUST NOT be used as the parent of another DelegationV1.
Re-delegation chains are not permitted in this protocol version.
Verifiers MUST detect and reject multi-hop delegation attempts.
Specifically, a verifier MUST reject any DelegationV1 whose presented parent artifact contains a delegation_id field, as this indicates the parent is itself a DelegationV1.
A relying party verifying a DelegationV1 MUST perform all of the following checks in order.
If any check fails, execution MUST NOT occur.
Chain integrity checks (evaluated against the parent AuthorizationV1):
- Verify the parent
AuthorizationV1is itself a validAuthorizationV1artifact (all Section 4 relying-party obligations apply to the parent). - Verify the parent artifact is an
AuthorizationV1and not aDelegationV1(one-hop enforcement). - Compute the SHA-256 hex digest of the canonical parent
AuthorizationV1(including itssignaturefield) and verify it equalsdelegation.parent_auth_hash. - Verify
delegation.delegatorequalsparent.audience. - Verify
delegation.policy_idequalsparent.policy_id. - Verify
delegation.expiryis less than or equal toparent.expiry. - Verify the parent has not expired at the time of verification.
Delegation-level checks:
- Verify
delegation.expiryis strictly greater than the current verification time. An artifact whereexpiry <= nowMUST be rejected. - Verify
delegation.delegateematches the expected delegatee for the current execution context, when a specific delegatee is required. - Verify the delegation scope does not exceed the parent scope (narrowing-only invariant, Section 5.6).
- Verify
delegation.algisEd25519and is permitted by local algorithm policy. - Resolve a trusted verification key from
(delegation.issuer, delegation.kid, delegation.alg)using the key selection rules in Section 11. - Verify
delegation.signatureover the canonical delegation payload using theOXDEAI_DELEGATION_V1signing domain (Section 8.4). - Verify
delegation_idhas not already been consumed (replay protection).
Fail-closed behavior:
If verification state is ambiguous, if required trusted key material is absent, or if any check produces an indeterminate result, the verifier MUST fail closed. Execution MUST NOT proceed unless all checks succeed.
DelegationV1 is a stable artifact in the current protocol profile.
Relying parties that do not use delegation MAY reject DelegationV1 artifacts.
Implementations that do support delegation MUST implement the full verification obligations in Section 5.8.
DelegationV1 extends AuthorizationV1 without replacing it.
A deployment that does not use delegation continues to use AuthorizationV1 exclusively.
DelegationV1 verification is additive and does not alter the semantics of AuthorizationV1.
{
"delegation_id": "del_01JZ4X9K2V8QM7R3P5T0Y6W1U2",
"issuer": "agent-A",
"audience": "agent-B",
"parent_auth_hash": "9a3f5c8b2d1e4f7a9c0b3e6d8f2a5c7e9b1d4f6a8c0e2b5d7f9a1c3e5b7d9f1a3",
"delegator": "agent-A",
"delegatee": "agent-B",
"scope": {
"tools": ["provision_gpu"],
"max_amount": 300000000
},
"policy_id": "policy_prod_infra_v7",
"issued_at": 1770001200,
"expiry": 1770001260,
"alg": "Ed25519",
"kid": "agent-a-key-2026-01",
"signature": "4rQ9Xm2kPzJv7wN5aT8sL3cF1bY6eH0dU9oR4iW2nK8="
}Ed25519 is the preferred public-key verification algorithm for v1.2 artifacts.
New v1.2 signed artifacts MUST include alg, kid, and signature.
The signed payload MUST use canonical encoding.
The signature field MUST NOT be included in its own signing payload.
Any mutation of signed fields MUST invalidate signature verification.
Verifiers MUST fail closed on:
- unknown or unsupported
alg - unknown
kid - malformed
signature - missing required signed fields
- issuer mismatch
- audience mismatch
- policy mismatch when configured
- expiry failure
A verifier MUST NOT accept ambiguous trust state.
Legacy shared-secret artifacts MAY be supported for backward compatibility. If supported, verifier mode MUST be explicit and documented as legacy. Public-key verification SHOULD be used for third-party verification.
Signatures for different artifact classes MUST use distinct signing domains. At minimum, implementations MUST support distinct domains:
OXDEAI_AUTH_V1OXDEAI_ENVELOPE_V1OXDEAI_CHECKPOINT_V1OXDEAI_DELEGATION_V1
A signer MUST compute signature input as:
domain_separator || canonical_payload_bytes
Artifact classes MUST NOT share signing domains. This prevents cross-artifact signature confusion.
Canonical signing ensures cross-language interoperability.
All conformant implementations MUST produce identical signing input bytes for identical artifact payloads, regardless of programming language or runtime environment.
OxDeAI requires a deterministic, language-independent canonical signing format for all signed artifacts. For identical artifact content, compliant implementations MUST produce identical signing input bytes. Cross-language signature interoperability depends on this property.
The following artifact classes are signed in v1.3:
AuthorizationV1DelegationV1VerificationEnvelopeV1
Checkpoint artifacts MAY be signed when that profile is enabled.
Each signed artifact class MUST use a distinct signing domain.
Before signing, an artifact payload MUST be converted to the protocol canonical JSON representation.
Canonical payload requirements:
- Object keys MUST be sorted deterministically.
- Source-code field order or runtime object insertion order MUST NOT affect output.
- Insignificant whitespace MUST NOT be included.
- Payload text MUST be UTF-8 encoded.
- Numeric and bigint values MUST use the protocol canonical representation.
- Implementations MUST NOT use language-native object/binary serializers as signing format.
- Implementations MUST NOT sign pretty-printed JSON.
- Implementations MUST NOT sign runtime-dependent binary encodings unless explicitly defined by this protocol.
The following domain strings are mandatory:
OXDEAI_AUTH_V1- forAuthorizationV1artifactsOXDEAI_ENVELOPE_V1- forVerificationEnvelopeV1artifactsOXDEAI_DELEGATION_V1- forDelegationV1artifacts
If checkpoint signing is used, OXDEAI_CHECKPOINT_V1 MUST be used for that class.
Signatures for different artifact classes MUST use different domain strings. A verifier MUST reject a signature when the domain does not match the artifact class. Domain separation prevents cross-artifact signature confusion.
In particular, a DelegationV1 signature MUST NOT be accepted as a valid AuthorizationV1 signature, and vice versa.
Signing input bytes are constructed as:
SIGNING_INPUT = DOMAIN_UTF8 || 0x0A || CANONICAL_PAYLOAD_UTF8
Where:
DOMAIN_UTF8is the UTF-8 encoding of the domain string.0x0Ais one byte with value newline.CANONICAL_PAYLOAD_UTF8is the UTF-8 encoding of the canonical JSON payload.
Compliant implementations MUST use exactly this construction.
The signature field MUST NOT be included in the canonical payload that is signed.
All required artifact fields other than signature MUST be included in the signed payload.
For v1.2 AuthorizationV1, this includes alg and kid.
For DelegationV1, this includes all mandatory fields defined in Section 5.2 except signature.
Transport-specific metadata not defined by this protocol MUST NOT be included in the signed payload.
- Canonical payload bytes MUST be UTF-8.
- Signing input bytes MUST be byte-for-byte reproducible across implementations.
- Implementations MUST NOT depend on locale, platform, or runtime defaults.
- Implementations MUST preserve exact protocol field values.
If signatures are represented as base64 or hex for transport, that encoding is a representation layer only and is not part of signing input construction.
A verifier MUST:
- Determine artifact class and required signing domain.
- Reconstruct canonical payload using the same canonical JSON rules.
- Reconstruct signing input using the same domain and separator.
- Verify signature against that exact byte sequence.
Verification MUST fail if:
- canonical payload cannot be reconstructed deterministically
- required signed fields are missing
- artifact class/domain is unsupported
- reconstructed bytes differ from signer-intended canonical form
The following conditions MUST fail closed:
- malformed canonical payload
- unknown artifact type or domain
- unknown or unsupported algorithm
- ambiguous serialization state
Verification ambiguity MUST NOT be treated as success.
Example artifact class: AuthorizationV1
Domain string:
OXDEAI_AUTH_V1
Example canonical JSON payload (excluding signature):
{"alg":"Ed25519","audience":"payments.api.eu-1","auth_id":"auth_01JY7K8Z4V3QH6N2M9P0R1S2T3","decision":"ALLOW","expiry":1770001260,"intent_hash":"9f3e5c6ad7a4a2f8a2d93f0f31c65a88f95d7dbef4c9f9e30d5f0f6ce7f4a1b2","issued_at":1770001200,"issuer":"oxdeai.pdp.prod.eu-1","kid":"2026-01-main","policy_id":"policy_prod_payments_v42","state_hash":"4e2b7f1a3d8c6e90b5f3a9d7c1e2f4a6b8d0c2e4f6a8b0c1d3e5f7a9b1c3d5e7"}Conceptual signing input construction:
UTF8("OXDEAI_AUTH_V1") || 0x0A || UTF8(<canonical-json-payload-above>)
Example artifact class: DelegationV1
Domain string:
OXDEAI_DELEGATION_V1
Conceptual signing input construction:
UTF8("OXDEAI_DELEGATION_V1") || 0x0A || UTF8(<canonical-delegation-payload>)
VerificationEnvelopeV1 MAY carry signature metadata (issuer, alg, kid, signature).
If signature metadata is present, verifiers MUST validate it under the same fail-closed rules.
If a verifier runs in signature-required mode, missing envelope signature MUST fail closed.
A Relying Party, also referred to as a Policy Enforcement Point (PEP), is the system responsible for executing external actions after verifying an authorization artifact.
The relying party enforces the OxDeAI execution authorization boundary.
Before executing any action, the relying party MUST verify the authorization artifact according to the rules defined in this section.
This section covers both direct AuthorizationV1 verification and delegated DelegationV1 chain verification.
A Relying Party (Policy Enforcement Point, PEP) is the system that receives an authorization artifact and decides whether an external action may execute. Examples include tool wrappers, compute provisioning services, payment gateways, API execution layers, and orchestration runtimes.
The relying party is the enforcement boundary for OxDeAI authorization decisions. It MUST enforce this contract before action execution.
When the relying party receives an AuthorizationV1 artifact without a DelegationV1:
Before executing any action, a relying party MUST verify:
decisionequalsALLOW.- The authorization has not expired.
issueris trusted.audiencematches the current relying party identity.policy_idmatches the expected policy context.intent_hashmatches the exact action about to execute.state_hashbinding is respected by the execution context.auth_idhas not already been consumed.algis supported by verifier policy.kidresolves to a trusted verification key.signatureis valid for the canonical signed payload.
If any verification step fails, the relying party MUST reject the action.
When the relying party receives a DelegationV1 artifact and its associated parent AuthorizationV1:
The relying party MUST perform the full chain verification sequence defined in Section 5.8.
In addition to the chain verification, the relying party MUST verify that the proposed action falls within the delegation scope:
- If
scope.toolsis present, the action name MUST appear inscope.tools. - If
scope.max_amountis present, the action amount MUST NOT exceedscope.max_amount.
If any chain or scope check fails, the relying party MUST reject the action.
The delegation path is a local, control-plane-free verification.
The relying party MUST NOT require a live call to the PDP to verify a DelegationV1 chain.
AuthorizationV1 MUST be treated as single-use.
After successful execution, the relying party MUST record auth_id as consumed in durable or equivalently reliable replay state.
Any subsequent attempt to reuse the same auth_id MUST be rejected.
delegation_id MUST be treated as single-use.
After successful execution under a DelegationV1, the relying party MUST record delegation_id as consumed.
Any subsequent attempt to reuse the same delegation_id MUST be rejected.
Single-use consumption is required to prevent replay and reduce time-of-check/time-of-use (TOCTOU) abuse.
Execution MUST NOT occur unless all of the following are true:
For direct authorization:
- Authorization verification succeeds.
- Authorization is not expired at decision time.
- Verified
intent_hashmatches the intended action. - Verified
audiencematches the current relying party.
For delegation:
- All chain verification checks pass (Section 5.8).
- The proposed action is within the delegation scope.
- Parent
AuthorizationV1is valid and not expired. - Delegation is not expired.
Authorization MUST be verified immediately before execution.
The relying party MUST treat each of the following as authorization failure:
Direct authorization failures:
- malformed authorization artifact
- unknown issuer
- unknown
kid - unsupported
alg - invalid signature
- expired authorization
- reused
auth_id - intent mismatch
- audience mismatch
Delegation-specific failures:
- malformed delegation artifact
parent_auth_hashmismatchdelegatordoes not matchparent.audiencepolicy_idmismatch with parent- delegation
expiryexceedsparent.expiry - delegation expired
- delegatee mismatch
- scope violation (action not in
scope.tools, amount exceedsscope.max_amount) - invalid delegation signature
- multi-hop delegation attempt (
DELEGATION_MULTIHOP_DENIED) - reused
delegation_id - unknown delegation signing key
Authorization ambiguity MUST result in denial (fail closed).
This contract enforces:
- replay protection via single-use
auth_idanddelegation_id - intent binding via
intent_hash - state binding via
state_hash - trust boundaries via
issuerandaudience - forgery resistance via signature verification
- reduced reuse window via short TTL (
issued_at/expiry) - scope confinement via delegation narrowing invariants
- chain integrity via
parent_auth_hashbinding - depth confinement via one-hop enforcement
These checks collectively mitigate replay attacks, authorization forgery, scope escalation, and TOCTOU drift between verification and execution.
Sharing mutable state across concurrent evaluations can lead to:
- non-deterministic authorization decisions
- cross-request interference
- incorrect DENY outcomes due to cross-call budget or replay mutations
Implementations MUST enforce state isolation per evaluation to preserve the protocol guarantees in Section 3.3. Each evaluation call MUST receive an isolated state snapshot.
1. Receive AuthorizationV1 artifact.
2. Resolve verification key from (issuer, kid, alg) and verify signature.
3. Verify issuer trust and audience equality.
4. Verify decision == ALLOW and expiry is in the future.
5. Compute requested action intent hash and compare to intent_hash.
6. Verify policy_id and state_hash bindings for current context.
7. Check auth_id is not consumed.
8. Execute action.
9. Mark auth_id as consumed.
1. Receive DelegationV1 artifact and its parent AuthorizationV1.
2. Verify parent AuthorizationV1 (all steps in flow above, steps 1–7).
3. Verify parent is AuthorizationV1, not DelegationV1 (one-hop enforcement).
4. Compute SHA-256 of canonical parent AuthorizationV1 and compare to delegation.parent_auth_hash.
5. Verify delegation.delegator == parent.audience.
6. Verify delegation.policy_id == parent.policy_id.
7. Verify delegation.expiry <= parent.expiry.
8. Verify delegation.expiry > now.
9. Verify delegation.delegatee matches expected agent.
10. Verify scope narrowing constraints (Section 5.6).
11. Resolve delegation signing key from (delegation.issuer, delegation.kid, delegation.alg).
12. Verify delegation.signature using OXDEAI_DELEGATION_V1 domain.
13. Verify proposed action is within scope (tools, max_amount).
14. Check delegation_id is not consumed.
15. Execute action.
16. Mark delegation_id as consumed.
The KeySet model provides deterministic resolution of verification keys for authorization artifacts.
This model enables independent verification of OxDeAI artifacts without requiring online access to the issuing system.
OxDeAI signed-artifact verification depends on deterministic resolution of a trusted public key from the tuple:
issuerkidalg
The KeySet model defines a deterministic representation of trusted verification keys. This model is required for non-forgeable verification in v1.2.
A KeySet is a structured representation of verification keys for exactly one issuer.
A KeySet object MUST contain:
issuerversionkeys
Field meanings:
issuer: identifier of the entity that issues signed artifacts.version: version or revision identifier of the KeySet.keys: collection of verification keys associated with that issuer.
A KeySet MUST correspond to exactly one issuer. A verifier MUST NOT treat a KeySet as valid for any other issuer.
Each KeySet key entry MUST contain:
kidalgpublic_key
A key entry MAY also contain:
statusnot_beforenot_after
Field meanings:
kid: key identifier.alg: signature algorithm identifier.public_key: public verification key material.status: optional lifecycle state (for example, active, retired, revoked).not_before: optional lower bound on key validity time.not_after: optional upper bound on key validity time.
Within a KeySet, kid MUST be unique.
alg MUST identify the verification algorithm unambiguously.
public_key MUST be encoded in the format required by the active protocol profile.
When verifying a signed artifact, a verifier MUST:
- Identify the artifact
issuer. - Locate a trusted KeySet for that issuer.
- Select a key entry whose
kidequals the artifactkid. - Confirm the key entry
algequals the artifactalg. - Verify the signature using the selected
public_key.
Verification MUST fail if:
- no trusted KeySet exists for the issuer
- no matching
kidexists algdoes not match
These conditions are fail-closed requirements.
For DelegationV1 verification, the issuer in the artifact is the delegating principal (equal to parent.audience), not the original PDP issuer.
The verifier MUST hold a trusted KeySet for this delegation issuer separately from the PDP KeySet.
Issuer trust is an external security decision made by the verifier environment.
A verifier MUST trust issuers explicitly. Untrusted issuers MUST NOT be accepted. Issuer equality comparison MUST be exact. A trusted key from one issuer MUST NOT be reused for another issuer.
The core protocol does not require online issuer-trust discovery. Offline or preconfigured issuer trust is valid in v1.2.
Issuers SHOULD support key rotation without unnecessarily invalidating still-valid artifacts.
Multiple active keys MAY exist simultaneously for one issuer.
kid MUST distinguish rotated keys.
Newly issued artifacts SHOULD reference the currently active key via kid.
Verifiers MUST use the kid carried in the artifact and MUST NOT guess a latest key.
Rotation MUST NOT rely on implicit key ordering.
Key validity windows are optional key-entry constraints.
- If
not_beforeis present, a verifier MUST reject use of that key before that instant. - If
not_afteris present, a verifier MUST reject use of that key after that instant. - If windows are absent, the key has no protocol-defined time bound.
Key validity windows are distinct from artifact expiry.
Artifact expiry and key validity MUST be evaluated independently.
Verification MUST fail closed when:
- issuer is unknown
kidis unknownalgis unsupported- key entry is malformed
- key validity windows fail
- multiple ambiguous matching keys exist
public_keycannot be decoded- trust state is ambiguous
Ambiguity MUST NOT be treated as success.
{
"issuer": "oxdeai.pdp.prod.eu-1",
"version": "2026-01",
"keys": [
{
"kid": "2026-01-main",
"alg": "Ed25519",
"public_key": "MCowBQYDK2VwAyEAq7n1h7vJmV1b8v1z9fP0vQ8sQv1w8mR7Q3v0cV0YQ6k=",
"not_before": 1767225600,
"not_after": 1798761600
}
]
}Key distribution is external to the core protocol.
The base protocol assumes:
- Verifiers MUST have access to trusted KeySets per issuer.
- KeySets MAY be provisioned statically or retrieved from a well-known endpoint.
- Unknown issuer or unknown
kidMUST fail closed.
Recommended HTTP discovery format:
GET /.well-known/oxdeai-keyset.json
A verifier MAY cache KeySets. A verifier MUST fail closed if:
- issuer is unknown
kidis unknown- key cannot be resolved
Dynamic discovery is OPTIONAL and not required for protocol compliance.
OxDeAI supports verification across trust boundaries.
A relying party MUST:
- Maintain a set of trusted issuers.
- Resolve verification keys using
(issuer, kid, alg). - Verify artifacts locally without contacting the issuer.
The protocol does not require:
- a shared control plane
- runtime trust in the issuer
- synchronous validation
Trust is explicit and externally configured.
Verification ambiguity MUST result in denial.
OxDeAI artifacts are designed to minimize replay and time-of-check/time-of-use (TOCTOU) risks in distributed execution environments.
OxDeAI mitigates replay and check/use drift by combining:
- single-use
auth_idanddelegation_id - short TTL (
issued_at/expiry) - intent binding (
intent_hash) - state binding (
state_hash) - issuer and audience binding
- parent hash binding (
parent_auth_hash) for delegated authorization
Relying parties MUST enforce single-use state for auth_id.
Relying parties that support delegation MUST enforce single-use state for delegation_id.
Relying parties SHOULD minimize check-to-execute latency.
If execution context changes after verification, execution SHOULD be re-verified.
v1.2 adds non-forgeable public-key verification as the preferred path.
v1.3 adds DelegationV1 as a stable protocol artifact for delegated agent authorization.
Compatibility requirements:
- Implementations MAY support legacy artifacts.
- If legacy mode is supported, verifiers MUST distinguish legacy mode from public-key mode.
- Public-key mode SHOULD be default for third-party verification.
- Future versions MAY strengthen envelope-signing and key-distribution requirements.
DelegationV1 is a stable artifact introduced in v1.3.
- Relying parties that do not use delegation MAY reject
DelegationV1artifacts without violating protocol conformance. - Implementations claiming v1.3 delegation support MUST implement the full verification obligations defined in Section 5.8.
DelegationV1does not alter the semantics or structure ofAuthorizationV1. Existing v1.2 compliant implementations continue to operate correctly without modification.- A verifier that accepts
DelegationV1MUST also hold appropriate trusted KeySets for delegation issuers, which are distinct from PDP-issuer KeySets. - Multi-hop delegation (chaining
DelegationV1fromDelegationV1) is not supported. Implementations MUST NOT support or accept multi-hop chains.
Protocol conformance is determined by artifact compatibility and verification behavior.
An implementation is compliant if it reproduces the protocol artifacts defined in this specification and passes the conformance vectors for the targeted version profile.
A conformant implementation MUST reproduce expected conformance vectors for its targeted profile.
Violation ordering in VerificationResult MUST be deterministic.
For v1.3 delegation conformance, implementations MUST additionally satisfy delegation-specific conformance vectors covering the narrowing-only invariant, one-hop enforcement, parent hash binding, and fail-closed behavior for all DELEGATION_* violation codes.