Authorisation Stamp, format v1 (final)¶
Status: draft, published with Phase 2 of the Authorisation Layer programme. Read with Authorisation Warrant v1. Feedback: security@xybern.com.
An Authorisation Stamp is the proof of authorisation that travels with an AI agent's action. It is issued by the organisation whose Authorisation Layer authorised the action, bound to that decision and, when the sender provides it, to the hash of the artefact the action produced, and signed with the issuer's published key. A receiver checks it with no account and no trust in the issuer's database.
Token¶
About 1.4 KB encoded (an optional agent.passport id and a slice hash prefix joined in the Authority Control Plane, Phases 1 and 3). Carried as the HTTP or MCP header Xybern-Authorisation, the email header X-Xybern-Authorisation (folded with spaces so no line exceeds 998 characters; every decoder drops whitespace), document metadata (xybern_authorisation), or, where a rail cannot carry the full token (ISO 20022 remittance information, 140 characters), the short reference XYBERN <resolver>/<stamp_id> which the receiver resolves to the full stamp. Information-flow labels (Phase 8) will be added as a labels field; the compiled rule set hash lives in the receipt.
Body¶
Canonical JSON: keys sorted, no whitespace, UTF-8.
| Field | Meaning |
|---|---|
format |
"xybern-stamp-v1" |
stamp_id |
stp_ followed by 12 hex characters |
issuer |
{"issuer_id": <workspace id>, "key_id": <signing key id>, "resolver": <url prefix of the public resolver>} |
decision_id |
The decision this stamp proves (its receipt id is rcpt_ + decision_id) |
decision |
{"outcome": "authorised" or "authorised after review", "decided_at", "action_type", "content_sha256", "metadata_sha256"} |
charter_hash |
The Charter version the decision was taken under (public sha256 over the mandate list) |
accountable |
{"id": "acp_…" or null, "kind": "human" or "system" or "none"}. The id is pseudonymous: an HMAC of the signer known only to the issuer, who resolves it on lawful request (decision D8). No name or email ever appears in a stamp |
agent |
{"agent_id", "fingerprint"} |
warrant |
{"warrant_id", "body_hash", "depth"} when the action ran under a warrant, else null |
bounds |
The warrant's action_families and argument_bounds, else null |
artefact_sha256 |
sha256 of the artefact the stamp is bound to, or null |
issued_at, expires_at |
ISO 8601 UTC. Stamps are long lived (default 365 days); the receipt is the durable proof |
Signature¶
{"algorithm": "ecdsa-p256-sha256", "key_id", "value": base64(DER)} over the canonical body bytes, with one of the issuer's published keys.
Issuer record¶
GET <host>/.well-known/xybern-issuer/<issuer_id>
{"format": "xybern-issuer-v1", "issuer_id", "display_name", "resolver", "issuer_record", "keys": [...],
"stamp_format": "xybern-stamp-v1", "algorithm": "ecdsa-p256-sha256", "status": "active", "published_at"}
Every issuer publishes its own record on its own host (a Sovereign install included), so a receiver can pin an issuer directly. GET <host>/.well-known/xybern-issuers lists the issuers on that host that opted into the public mirror (decision D10).
Checks¶
Offline, with the issuer record's keys:
- the token decodes,
formatisxybern-stamp-v1, the algorithm is supported signature.key_idis a published key of the issuer and the signature over the canonical body verifiesnow < expires_at- when the receiver knows the artefact, its sha256 equals
artefact_sha256(a substituted artefact fails)
Issuer state, one call to <resolver><stamp_id> (JSON, or HTML for a browser), or a receiver's own resolver mirror:
- the stamp is known to the issuer and its body hash matches the issuer's record
- the stamp is not revoked
A revoked stamp means "do not honour this any more" (for example a compromised agent's outstanding instructions); it does not rewrite the receipt, which remains the historical proof that the action was authorised at the time.
Inbound rule¶
The inbound_stamp rule primitive lets a receiver's Charter say "refuse or hold any received instruction, payment or message that carries no valid stamp from a trusted issuer": {"type": "inbound_stamp", "action_types": ["receive_*"], "conditions": {"trusted_issuers": ["*"] or [ids], "require_outcome": "authorised"}, "decision": "block" or "escalate"}. The stamp is read from the action metadata (stamp, xybern_authorisation, or a headers map).
Counterparty handshake¶
When the receiver's Authorisation Layer honours a stamp from an issuer on the same install, the receiver's decision is sealed in the issuer's Provenance Vault as stamp_honoured (receiver workspace, receiver decision id, outcome). Both sides hold the record.
Reference implementations¶
- Issuer, resolver, inbound rule:
package/xybern_api/stamps.py,package/stamp_public_routes.py - Python:
xybern.stamps(verify_offline,verify,resolve,http_headers,attach_email,payment_reference,document_metadata,python -m xybern.stamps <token>) - JavaScript:
verifyStampOffline,decodeStamp,stampHeaders,paymentReference - Command line:
tools/xybern-verify/verify.py --stamp <token> --keys keys.json [--artefact <file>] - Browser:
<host>/check