1.2.0-rc.1 / Agreements and authority

Optional providers

Appoint a provider with explicit capabilities, scope, keys and a lifetime.

The 1.2.0-draft.3 authority contract defines the decision rules used by the integrated direct and delegated reference. This page specifies authority semantics; the free exchange and validation record describe the executed HTTPS composition.

The originator can run all services itself, appoint an external service for free agreements, or appoint separate agreement, reporting, asset and payment services. A provider acquires only the capabilities and scope explicitly published by the origin. Neither appointment nor a payment confirmation transfers ownership of assets or establishes a principal’s legal authority.

Artifacts and API

The schema identifier is reserved for this local candidate; it does not assert that an artifact exists at that public URL. JSON Schema validation is necessary but insufficient. Exact input bytes, duplicate members, integer tokens, calendar dates, canonical URLs, curve points, intervals and scope intersections require semantic validation. The engine reads at most 128 KiB each for authority and policy. It performs no network access, signing, authentication, spending, state persistence or access issuance.

validate_authority(document, policy_document) validates the complete document against the current policy identity and scope. validate_operation(operation) validates an operation’s shape and internal semantics. evaluate_authority returns a fail-closed allow/deny result and catches malformed input errors. Standalone validators raise errors; callers must treat any error as invalid input.

Publication and identity

The policy origin publishes /odexa.json and /odexa-service.json using HTTPS. An authority document contains exactly:

protocol_version: "1.2.0-draft.3"
policy_protocol_version: "1.2.0-draft.1"
origin, policy_id, revision, issued_at, expires_at
services: [service, ...]
delegations: [delegation, ...]

origin and policy_id must equal the decoded policy. revision is a positive safe integer. Validity uses whole-second UTC timestamps, inclusive start and exclusive expiry. Published integer values use unsigned JSON integer tokens; fractional/exponent tokens and negative zero are rejected even when a JSON Schema validator considers them integral. Unknown members and duplicate members are rejected. Current revision/digest rollback protection and cross-revision identifier immutability require the adapter’s retained history; the pure engine has no prior-state input.

A service has exactly id, base_url, issuer, capabilities, signing_keys, limits and scope. Its id is an origin-scoped canonical HTTPS identifier. The base_url is a canonical HTTPS directory URL, optionally on another origin, including any tenant-specific path. The independent issuer is the exact provider identity. Names, DNS ownership or an endpoint prefix alone do not substitute for these bindings. Query strings and fragments are prohibited on service, issuer, key, delegation and endpoint identifiers.

There are at most 16 services, 16 keys per service and 64 delegations. Canonical URL rules reuse the frozen policy parser: normalized HTTPS origin and path, no userinfo, unsafe encoded separators, dot segments, duplicate slashes or noncanonical port spelling. Request URLs may contain a query under policy rules; metadata identifiers may not. A source that uses an alternative URL alias must publish and authorize that exact canonical identity.

scope has resource_ids, actions, purposes, asset_id_prefixes and version_id_prefixes. Resource IDs name existing policy scopes, not immutable asset versions. Action and purpose arrays use the policy vocabulary. Prefix arrays contain origin-scoped directory URLs ending in /, at most 64 each; asset publication requires both arrays, other services leave them empty.

Services with any of issue_agreements, issue_tokens or introspect have non-null limits containing max_offer_seconds, max_access_seconds, max_use_seconds and payment_mode. Other services set limits to null. Maximum offer lifetime is 600 seconds; access/use bounds are positive seconds up to 31,536,000. payment_mode is none or external; external permits an optional payment condition and does not require a nonzero price.

Explicit delegation and intersections

A delegation contains exactly:

id, origin, delegate_service_id, capabilities
resource_ids, actions, purposes
issued_at, expires_at
max_access_seconds, max_use_seconds, payment_mode
allow_subdelegation: false
asset_id_prefixes, version_id_prefixes

Its ID and origin belong to the publisher. The delegate references one declared service. Its capability/resource/action/purpose sets must be subsets of that service’s sets. Validity must fit inside authority validity. Access/use ceilings cannot exceed the service’s ceilings. A delegation without grant capabilities uses zero duration ceilings. Manifest prefixes must fit inside the service’s prefixes. Delegation never authorizes subdelegation.

An external base_url requires one explicit, current delegation ID for every supported operation, including a zero-price agreement and reporting. A same-origin service may omit delegation; if it specifies one, its restrictions apply. The engine never combines two partial delegations to create a broader effective grant. A provider that needs another role obtains a separate direct appointment from the originator.

Effective authority is the intersection of current origin metadata, service capability and scope, the selected delegation where applicable, the operation’s exact identity/endpoint/key binding, and the requested duration/payment bounds. Every policy resource matched by the URL must be covered; overlapping scopes cannot bypass a narrower appointment. Every requested action and purpose must be covered. Policy evaluation retains its Cartesian action-by-purpose semantics and obligation aggregation.

For a new offer or acceptance, the current policy must return permit or require_agreement, with no unsupported duty. For other kinds the result answers operational authority only: an appointed collector may report prohibited behavior, for example. Current policy decisions and duties are returned, but token/access consumers must separately evaluate the authenticated, pinned agreement, its rights and obligations, current status and token binding. An operational allow never asserts a resource permission.

Supported operation contract

An operation contains exactly operation_id, payment_request_digest, kind, origin, service_id, issuer, endpoint, delegation_id, key_id, key_use, request, offer_seconds, access_seconds, use_seconds, payment_mode, asset_id and version_id. The kinds status, revoke, payment_mandate, payment_check and export_evidence additionally require a canonical UUIDv4 agreement_id; that member is forbidden on other operation kinds.

operation_id is a new canonical lowercase UUIDv4. request contains the canonical same-origin URL and explicit nonempty action/purpose arrays plus supported_obligations (which may be empty). Nonapplicable IDs/digests are null and durations zero, not omitted. Applicable grant durations are positive and access duration cannot exceed use duration.

Kind Required capability Exact endpoint Required signing use
offer issue_agreements base_url + "offers" odexa-receipt+jws
accept issue_agreements base_url + "agreements" odexa-receipt+jws
status issue_agreements base_url + "agreements/" + agreement_id + "/status" odexa-status+jws
revoke issue_agreements base_url + "agreements/" + agreement_id + "/revoke" odexa-status+jws
payment_mandate issue_agreements base_url + "agreements/" + agreement_id + "/payment-mandate" null
payment_check issue_agreements base_url + "agreements/" + agreement_id + "/payment-check" null
export_evidence export_evidence base_url + "exports" odexa-evidence-export+jws
token issue_tokens base_url + "tokens" null
introspect introspect base_url + "introspect" null
report receive_events base_url + "events" odexa-event-record+jws
verify_payment verify_payments base_url + "verify" odexa-payment-status+jws
publish_manifest publish_assets exact version_id odexa-asset-manifest+jws

Offer/acceptance checks bind the receipt-capable service key; this does not introduce a signed-offer format. Offer lifetime must also fit the remaining policy, authority, key and delegation lifetime. A manifest operation separately intersects logical asset and immutable version prefixes. Token/introspection operations use null signing fields because their current request/response channel is authenticated HTTPS, not a new JWS type.

Status and revocation use zero offer/access/use durations and payment mode none; neither creates a grant. Their agreement ID binds the exact dynamic route. The draft-3 free service now integrates those operations and authenticated original-receipt retrieval. Historical retrieval is not a new operational grant. The portable free-evidence builder integrates export_evidence as a trusted in-process API. Its operation has zero durations and payment mode none. The paid agreement service integrates the mandate/check operations with zero durations and payment mode external; the service and selected delegation must permit that mode. Payer signing authority is separately provisioned and is not an origin service signing role. Services must resolve each actual report_usage destination and cannot treat declared duty support or this decision as proof that a report was sent.

Current trust, keys and revocation boundary

The trusted adapter supplies observation with exactly source, origin, authority_url, policy_url, authority_digest, policy_digest, checked_at, available, tls_verified, redirected and revalidated. This object is internal testimony from the authenticated transport or colocated transaction, never an agent-supplied claim.

The two digests cover the exact retrieved bytes. URLs must name the two origin publication paths. An unavailable origin, redirect, missing revalidation, future observation or observation older than five seconds produces denial. HTTPS observations require verified TLS. An external service requires the https observation source; colocated is only the direct origin-service path. The five-second maximum bounds computation/queue delay, not permission to reuse an observation for unrelated operations: adapters must acquire current authority for each operation and bind that operation ID and digest.

Current metadata is served with Cache-Control: no-store; clients request revalidation and do not accept a stale cache fallback. Policy must be revalidated for the same operation. Immutable historical records may be cached. A colocated service can read authority and commit its decision in one database transaction. Remote observation and local commit cannot be globally atomic. Remote revocation becomes effective for operations that observe the changed authority; already admitted in-flight delivery may finish according to the gateway’s declared boundary. The adapter retains revision, exact digest and check time and must not claim instantaneous distributed revocation. Protected cached bodies need the same current authorization check as newly generated bodies.

A service key has kid, exact public P-256 public_jwk, uses, not_before, not_after, state, retired_at and revoked_at. No private JWK material is accepted. The engine checks curve validity, service/key-use compatibility and unique key IDs. A key ID cannot name different material within the authority document. Active signing requires an active key inside its validity interval. Retired/revoked keys cannot authorize new operations. Historical receipt verification may retain earlier authority/key bytes, but requires an explicit historical verification path and must expose missing provenance or known compromise. A historical signature is never current delegation authority.

Rotation requires a new key ID, overlapping publication before use, historical retention and durable revision checks. These are adapter/history requirements; this pure module tests current key selection and denial states, not a deployed rotation lifecycle.

Decision use and payment binding

A denial has decision: "deny", authority: null and resource_permission_granted: false. An allow also has resource_permission_granted: false, plus policy_decision, aggregated obligations, obligation_status: "not_verified" and an authority context containing:

operation_id, operation_digest, payment_request_digest
request, request_digest
origin, service_id, issuer, capability, endpoint
key_id, key_use, delegation_id
authority_revision, authority_digest, policy_digest, checked_at

Consumers must check the full decision’s explicit allow value before using its context, then compare every relevant binding to their pending operation. This object is not a bearer credential, signed proof or an assertion that an action/duty happened. The operation/request digests use SHA-256 over the reference crypto.json_bytes encoding (UTF-8, sorted object keys, compact JSON; array order retained). They are deterministic internal correlation values, not an invitation to replace exact signed-payload byte retention with JSON reserialization.

For verify_payment, the operation ID equals the pending check ID. payment_request_digest is required and binds the exact canonical check bytes constructed from the retained quote, accepted offer, request scope and separate payer mandate. The authority engine treats this digest as opaque. The payment consumer must reconstruct and compare it, compare request_digest against the accepted resource scope, and require the exact verifier service, provider issuer, endpoint and payment-status key use. Reusing a valid decision for another quote/check/resource must fail. A free agreement uses payment_mode: "none" and requires no payment provider. A provider’s service fee and originator’s resource price remain separate payment line items. Acceptance alone never authorizes a debit.

Provider replacement and completion gates

Replacing a provider publishes a new origin-owned descriptor/delegation revision with the intended endpoint, issuer and key; an old provider cannot nominate its replacement. Removing the old appointment denies its next current operation. Existing signed agreements and evidence retain their original service, key, bytes and authority snapshots. Importing them must not silently rewrite the issuer, transfer client secrets/tokens or reactivate access. A migration requires authenticated export/import, explicit new authority, preserved exact evidence and a documented credential transition; the supported fresh-agreement handover now demonstrates those steps using existing contracts. It preserves original paid evidence without claiming transparent rights assignment.

The focused command for the original resolver component is:

python3 -m unittest discover -s tests -p 'test_delegation_profile.py' -v

The bundled Python runtime passed 24 test methods on 17 September 2026, including same-origin/free external operation, scope intersections, endpoint/tenant/key substitution, no subdelegation, policy prohibitions/duties, expiry/freshness/outage, key states, byte parsing, asset prefixes, payment correlation and fixture semantics. This is a pure-module result. Independent structural validation and combined payment integration are included in current validation; the earlier count is specific to this component checkpoint.

The protocol retains direct free operation and optional providers. This authority profile must be combined with the transport, lifecycle, persistence and evidence contracts selected by an implementation. A passing resolver test alone does not establish that combination; see current validation and release status.

Integrated capabilities

The reference combines bounded HTTPS acquisition, durable authority history, two-origin payment verification and the direct/delegated draft-3 free service and gateway. These capabilities do not relabel the historical draft-2 service. Selected integrations add durable delivery reporting, paid agreements, free archives, paid archives, continuing storage, native assets, fresh-agreement handover and declared observation coverage. The installed quickstart and separate independent clients have recorded checks in current validation. Publication status is tracked separately in release status.

Odexa / Protocol explorer

This page. Your terms.

Inspect this website’s published policy and see how a proposed use is evaluated.

Current pagehttps://odexa.io/guides/providers/
Loading policy…

Published JSON
Open JSON

This is a local policy check, not a signed agreement or proof of agent compliance. Other published licences and applicable rights still apply. How policy evaluation works →

Odexa / Get in touch

Start a conversation.

Tell us what you have in mind. We’ll respond where we can.

We use these details to review and respond to your enquiry. Please leave out confidential information. Submitting does not subscribe you to marketing. Privacy policy.