Odexa 1.2.0-draft.2

Wire profile

The implemented same-origin free service and evidence contracts.

1.2.0-draft.2 · 16 September 2026 · development implementation

This document describes the implemented same-origin free profile. Where earlier planning documents discuss payments, delegated providers or future key rotation, those are design directions rather than supported capabilities of this server. Machine schemas accompany this document; cross-field, cryptographic and state checks remain mandatory.

Discovery and authority

An origin publishes /odexa.json for its policy and /odexa-service.json for its service metadata. The policy identifies its own origin, revision, validity window, exact resource scope, actions, purposes and obligations. The default is no_grant. All requested action-purpose pairs must be permitted or eligible for agreement, and all applicable obligations must be supported. Unknown vocabulary is rejected.

The service metadata identifies its issuer, base URL, capabilities and public signing keys, including each key’s allowed uses and validity. This reference uses one service on the origin with no delegation. Discovery and resource requests use HTTPS. The test client additionally receives independent public key pins during provisioning; it does not trust a key merely because a signed record names it.

Exact policy, authority and human-terms bytes are retained under immutable URLs. An offer binds their SHA-256 digests. JSON parsing rejects duplicate object members and ambiguous integer forms; do not parse a JSON object and reserialize it to reconstruct signed or hashed bytes.

The policy vocabulary stays at draft 1 while the new service and evidence envelopes use draft 2. Metadata names both versions explicitly. Neither version label silently implies support for the other service capabilities.

Participants and credentials

The administrator provisions clients locally. An agent client has a random secret, a P-256 signing key, a reporter identifier and an explicit list of allowed principal identifiers. Gateway and administrator roles have separate credentials. No public registration service or verified business-identity service is included.

Service API authentication uses HTTP Basic over HTTPS with generated high-entropy secrets. Protected assets use separately issued opaque bearer tokens. Client secrets and access tokens are different credentials. Bearer possession does not establish who actually operated an agent. Store only token hashes in the service database.

Compact JWS uses ES256 with exact UTF-8 payload bytes, a recognized typ and a provisioned kid. P-256 signatures use the JWS fixed-width encoding. Unsupported algorithms, untrusted keys, malformed signatures and type substitution are rejected. The artifact types are acceptance, receipt, status, event, event intake and asset manifest; a valid signature for one type cannot be substituted for another.

API surface

All paths in this table are relative to the discovered base URL, /api/ in the fixture. JSON bodies use application/json; signed messages use application/jose. Read APIs require authentication unless explicitly public.

Method and path Caller Result
POST offers Agent A zero-price offer for its principal, URL, requested actions/purposes and bounded access/use duration
GET offers/{offer_id} Owning agent Original offer bytes
POST agreements Agent Verify signed acceptance and persist agreement; return original signed receipt
GET agreements/{id}/receipt Owner or operator role Original immutable receipt, including after revocation
GET agreements/{id}/status Owner or operator role Signed current access state
POST agreements/{id}/revoke Administrator Idempotent future-access revocation
POST tokens Owning agent Opaque token for its active agreement
POST introspect Gateway Live token/scope decision bound to the actual request; persist admission before allowing access
POST events Agent or gateway Verify signed evidence and return signed intake
POST events Anonymous Accept only an unverified client-use declaration in a separate namespace
GET export?limit=N&after=CURSOR Authenticated caller Paginated original signed intake records within the caller’s scope
GET materials Authenticated caller Retained offers, acceptances, receipts, status history, public context documents and admissions within its scope

Administrator and gateway accounts are trusted origin-operator roles with wider access. Agent exports include their own records and verified gateway records for their own agreements. Anonymous claims cannot attach themselves to the authenticated owner index by naming an agreement.

Agreement lifecycle

  1. The client discovers the policy and service, then requests a scope it supports. The fixture requests retrieve and store for public_retrieval on one exact URL.
  2. The service checks principal ownership, policy validity, every requested action-purpose pair and current service authority. The narrow profile requires access_seconds <= use_seconds.
  3. The client fetches all retained context, verifies the exact digests and separately approves human terms. The fixture uses a preapproved synthetic terms digest; accepting arbitrary real terms automatically is not demonstrated.
  4. The client signs an acceptance binding the service, offer ID, exact offer digest, principal, nonce, acceptance time and idempotency key.
  5. The service checks signature, client/principal binding, time, current policy/authority and offer freshness. A single SQLite transaction persists the acceptance, agreement, original signed receipt, status and local transition evidence.
  6. An identical authenticated retry returns the original receipt, even when the ES256 signature bytes differ. A changed decoded acceptance under the same idempotency key conflicts. An offer cannot create a second agreement.
  7. The client requests an access token separately. The receipt is evidence of the agreement, not a bearer access token.

A free agreement becomes active directly. No paid state is simulated. Expiry stops new access; administrator revocation changes future access without rewriting the accepted receipt or claiming to recall delivered bytes. A request already admitted may finish after revocation. Use rights and duties remain governed by the retained terms and use window; the server cannot inspect a recipient’s storage or model.

Successful transaction acknowledgements follow commit. The tests kill child processes immediately before and after commit and check recovery. These tests establish process-crash behavior in the tested environment, not arbitrary power-loss or storage-hardware guarantees.

Protected delivery

The fixture serves only /licensed/about.txt through its protected gateway. The caller supplies:

Authorization: Bearer <opaque-token>
Odexa-Actions: retrieve
Odexa-Purposes: public_retrieval

These are explicit declarations of the requested use. The gateway does not infer purpose from a User-Agent string. It calls live introspection for each GET, HEAD, range and conditional request and checks the returned request ID, URL, origin, method, actions and purposes before returning content.

The admission is durable before content is served. The completed observation binds to that admission. If a process dies between admission and final observation, retained material exposes an admission with no terminal event. That is an unknown delivery outcome, not a completed transfer or a zero-use assertion.

The transport rejects duplicate critical headers, unsupported transfer encoding, malformed content lengths, oversized bodies, wrong Host and noncanonical request lines. It compares the raw request target because the underlying HTTP library can normalize leading slashes. Public manifests contain metadata and digests, not the protected text. Internal files have no public file-serving route.

The asset response supplies an immutable manifest link, selected representation ID, media type, language, ETag and explicit private/no-store cache behavior. Full GET, HEAD, a single supported byte range and conditional 304 have separate evidence classifications. Unsupported range forms receive an error. Authorization failure or unavailable authority withholds the protected body.

Export and verification

Preserve original compact JWS values, exact decoded payloads, offer/context bytes and manifest bytes. The independent client verifies cryptography, identities, context digests, acceptance/receipt linkage, status history and representation binding without importing Python verification code.

The export cursor is scoped to the authenticated client and pages records in insertion order. It is not a signed snapshot token or a general cross-database cursor. The materials endpoint takes an atomic, bounded local snapshot, with a 1,000-record global ceiling and a 1 MiB serialized-response limit; it is not a production bulk-export service. Oversize responses return 413. Close the workload before comparing snapshots. The demonstration exports the pre-revocation history, then separately tests revocation.

Offline verification uses separately retained public trust. It can check the included records and their historical snapshot bindings. It cannot infer that an exporter supplied every record, establish trusted historical time, or prove that a key remains trusted now. A tampered record must fail verification; a missing record requires an independent inventory or expectation to detect.

Optional providers

No field in the free path appoints Ortello implicitly. A future delegated provider profile must name its capabilities, permitted scopes, keys, lifetime, revocation boundary and payment authority explicitly. Payment authorization remains separate from agreeing to terms and observing traffic. Those wire contracts and adapters are not implemented by this release.

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/wire-profile/
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.