Status: Draft · Version: 1.0.0-draft · Updated: 2026-05-29
Raucle Provenance Receipt — v1
A signed, content-addressed, append-only record of one AI agent action — the call to a model, the use of a tool, a retrieval, a guardrail decision, a handoff, a sanitisation, or a merge. Receipts are JWS envelopes that chain into a directed acyclic graph (the provenance graph) describing how an output came to be.
This document defines the wire format, the semantics, and the verifier obligations. It is the protocol layer Raucle uses to represent agent provenance and is offered as a candidate standard for the wider AI infrastructure ecosystem. The conformance language (MUST, SHOULD, MAY) is used per RFC 2119.
Contents
- 1. Scope and design goals
- 2. Terminology
- 3. Envelope (JWS)
- 4. Payload
- 5. Operations
- 6. Identity, keys, and capability statements
- 7. Taint propagation rules
- 8. The provenance graph
- 9. Verifier obligations
- 10. Privacy
- 11. Interoperability profiles
- 12. Security considerations
- 13. IANA / Media-type registrations
- 14. Extension points
- 15. Worked example
- 16. References
1. Scope and design goals
The Raucle Provenance Receipt format describes how an output produced by an AI system was produced. It is designed to be emitted by guardrail engines, tool gateways, retrieval layers, and agent frameworks; consumed by verifiers, auditors, SIEMs, and regulators; and stored as offline-verifiable evidence of an agent's behaviour.
The format is designed to satisfy four invariants:
- Offline verification. A receipt MUST be verifiable against a known issuer key without contacting any external service.
- Content addressing. A receipt's identity is a deterministic hash of its signed bytes. Two parties MUST compute the same identifier for the same receipt.
- Taint monotonicity. Information about
upstream untrusted inputs MUST flow forward through the
graph; it can only be reduced by an explicit, signed
sanitisationoperation. - Privacy by default. Receipts MUST NOT carry prompt or output plaintext. Hashes only, with an opt-in slot for content-bearing receipts in deployments that require full payload disclosure (e.g. internal audit).
Non-goals: the spec does not define how chains are stored, how keys are distributed, how policies are evaluated, or how receipts are exchanged between organisations. Those layers are deliberately left to the deployer.
2. Terminology
- Action
- A single observable event in an agent's execution — one model call, one tool invocation, one retrieval, one guardrail scan, one handoff, one sanitisation, one merge.
- Receipt
- A JWS-encoded signed statement that an action occurred and produced an output with the stated hash, in the stated taint state.
- Agent
-
The signing principal. Identified by an
agent_idstring and an Ed25519 public key. Distinct agent identities SHOULD use distinct keys. - Capability statement
- A signed list of operations an agent is permitted to perform. See §6.
- Provenance graph
-
The DAG of receipts whose vertices are actions and whose
edges are the
parentsarrays in payloads. - Taint tag
-
A short ASCII string labelling an upstream untrusted input —
e.g.
untrusted_user,retrieval:knowledge_base.
3. Envelope (JWS)
A receipt MUST be encoded as a Compact JWS per RFC 7515 with the following header parameters:
{
"alg": "EdDSA",
"typ": "provenance-receipt/v1",
"kid": "<agent_key_id>",
"crit": ["raucle/v1"]
} -
The signing algorithm MUST be
EdDSAover Ed25519. Other algorithms are reserved. -
The
typheader MUST be the stringprovenance-receipt/v1. Verifiers MUST reject any othertyp. -
The
critheader MUST be present and MUST contain the stringraucle/v1. This prevents generic JWT libraries from accidentally accepting a receipt as a bearer token. -
The
kidheader MUST equal theagent_key_idfield in the payload (see §4). - The JWS MUST be detached-payload-free (i.e. the payload segment is non-empty and matches what is signed).
4. Payload
The payload MUST be a UTF-8 encoded, canonical-JSON object
(RFC 8785) containing exactly the fields below. Implementations
MUST NOT include extra top-level fields outside the
x_ namespace defined in §14.
| Field | Type | Description |
|---|---|---|
iss | string | Issuer URI (e.g. https://acme.example/raucle). MUST match the URI bound to the signing key. |
iat | integer | Issued-at, seconds since Unix epoch. |
agent_id | string | Stable agent identifier matching ^agent:[a-z0-9][a-z0-9_\-./]{0,127}$. |
agent_key_id | string | Opaque identifier for the Ed25519 key. MUST equal JWS kid. |
operation | string | One of the values in §5. |
parents | array of strings | Receipt IDs (see §8) of direct ancestors. MAY be empty only for user_input. |
input_hash | string | Hex SHA-256 of the input bytes. For user_input this is the raw prompt; for downstream operations, the assembled input. |
output_hash | string | Hex SHA-256 of the output bytes. |
taint | array of strings | Sorted set of taint tags carried by the output. See §7. |
ruleset_hash | string | Hex SHA-256 of the policy/ruleset effective at the moment of the action. MUST be present for guardrail_scan and sanitisation; SHOULD be present for all others. |
guardrail_verdict | string | One of ALLOW, BLOCK, SANITISE, NA. Required for guardrail_scan; NA elsewhere. |
model | object (optional) | Operation-specific descriptor; required for model_call. See §5. |
tool | object (optional) | Operation-specific descriptor; required for tool_call. |
corpus | object (optional) | Operation-specific descriptor; required for retrieval. |
tenant | string (optional) | Multi-tenant scope identifier. MUST be opaque to the verifier. |
5. Operations
Receipts describe exactly one of the following operations:
| Operation | Meaning | Required descriptor |
|---|---|---|
user_input | Raw input entered an agent's boundary. | — |
model_call | An LLM was queried. | model.{provider, name, version} |
tool_call | An external tool was invoked. | tool.{name, version, side_effects} |
retrieval | Documents were fetched from a corpus. | corpus.{id, snapshot} |
guardrail_scan | A policy decision was rendered. | —; guardrail_verdict required. |
agent_handoff | Control passed to a different agent. | — |
sanitisation | Taint tags were intentionally removed. | —; see §7. |
merge | Multiple parents combined into one output. | — |
Verifiers MUST reject receipts with an unknown
operation value. Future operations will be
introduced under a new typ (e.g.
provenance-receipt/v2); they will not be added to
v1.
6. Identity, keys, and capability statements
Each agent_id binds to one or more Ed25519 public
keys, each identified by an opaque agent_key_id.
The binding is published in a capability statement: a
JWS of type capability-statement/v1 listing the
operations the agent is permitted to perform and the keys it
MAY use.
In open-source mode an agent MAY self-sign its capability
statement with its own key. In commercial deployments the
capability statement SHOULD be issued by a separate authority
key. The binding mechanism is out of scope; the verifier obligation
is: before accepting a receipt from agent A, the verifier
MUST have a verified capability statement for A that permits the
operation in the receipt.
7. Taint propagation rules
The taint field carries a sorted set of tags
describing which untrusted upstream inputs the output may
contain. Taint MUST propagate monotonically:
-
For every receipt R with parents P1…Pn:
taint(R) ⊇ ⋃ taint(Pi) unless R has
operation = sanitisation.
-
A
sanitisation receipt MUST list the removed tags
in an x_removed_taint field. Tags not listed
there MUST remain present.
-
Tag strings are case-sensitive ASCII matching
^[a-z][a-z0-9_:\-]{0,63}$.
-
New tags MAY be introduced by any receipt; sanitisation MAY
only remove tags.
A verifier that observes a violation of (1) or (2) MUST treat
the chain as invalid from that receipt onward.
8. The provenance graph
A receipt's identifier is the hex SHA-256 of the
Compact JWS string of the receipt, computed as ASCII bytes
including the dot separators. This is deterministic: any party
handed the JWS computes the same identifier.
A receipt's parents array lists the identifiers of
its direct ancestors. The transitive closure of parents
forms a directed acyclic graph (the provenance graph).
Cycles MUST be rejected by verifiers.
A chain is any topologically-ordered subset of the
provenance graph that is closed under parents — i.e.
every parent reference in the chain is itself present in the
chain. Verifiers operate on chains.
9. Verifier obligations
To accept a chain C, a verifier MUST:
- Verify the JWS signature of every receipt with the key denoted by its
kid / agent_key_id. - Confirm each
typ = provenance-receipt/v1 and crit ⊇ ["raucle/v1"]. - Confirm that each receipt's identifier (as defined in §8) equals the value referenced by any descendant's
parents entry. - Confirm the graph is acyclic and closed under
parents. - Confirm taint monotonicity per §7.
- For each receipt, confirm there exists a verified capability statement permitting the receipt's
operation for the receipt's agent_id as of iat. - Where the operation is
guardrail_scan, confirm ruleset_hash and guardrail_verdict are present.
A verifier MAY perform additional policy checks (e.g.
“output_hash matches what was actually delivered to the
user”) but those are out of scope for v1 acceptance.
10. Privacy
Receipts MUST NOT contain prompt plaintext or output plaintext.
Only hashes. This enables a deployment to publish receipts to
external SIEMs and regulators without exposing the underlying
content.
Deployments that require content disclosure (e.g. internal
audit) MAY emit a paired content envelope alongside
the receipt — an out-of-band, separately-encrypted blob of the
pre-image bytes, addressable by input_hash /
output_hash. The format of the content envelope is
out of scope for v1.
11. Interoperability profiles
Two minimum profiles are defined:
- Base profile. All v1 receipts. A conformant
emitter or verifier MUST support this profile.
- Federated profile. Receipts whose
iss values may belong to different
organisations. Emitters MUST publish a capability statement
endpoint resolvable from iss + a
well-known path (/.well-known/raucle/agents.json);
verifiers MUST refuse to cross trust boundaries without it.
12. Security considerations
- Key compromise. Capability statements MUST
carry a
not_after; verifiers MUST treat receipts
whose iat exceeds not_after as
invalid, even if the signature checks out.
- Replay. Receipts are non-replayable in the
sense that their identifier is deterministic; treating two
copies as one is a feature, not a bug. Higher layers
(capability statements) carry expiry to bound key lifetimes.
- Hash collisions. The format binds itself to
SHA-256 in v1. A future v2 will introduce algorithm
agility via a
hash_alg header.
- Side-channel. Verifiers SHOULD compare
identifiers using constant-time string comparison; the field
is short and frequently compared in adversarial settings.
- JWT confusion. The
crit header
plus a distinct typ exist specifically to
prevent receipts from being mistaken for bearer tokens by
generic JWT libraries.
13. IANA / media-type registrations
The following media types are claimed:
application/vnd.raucle.provenance-receipt+jws — a single receipt. application/vnd.raucle.provenance-chain+jsonl — a chain as newline-delimited JWS strings, topologically ordered. application/vnd.raucle.capability-statement+jws — a capability statement.
14. Extension points
Implementations MAY add fields whose names begin with
x_. Verifiers MUST preserve unknown
x_ fields when re-serialising. Verifiers MUST NOT
let unknown x_ fields affect signature verification
or taint propagation.
Non-x_ fields not defined in this document are
RESERVED. Receipts containing reserved fields MUST be rejected.
14.1 Registered extension: x_tee_attestation
A receipt emitted from inside a hardware Trusted Execution
Environment (AMD SEV-SNP or Intel TDX) MAY carry a hardware
attestation quote that binds the receipt's signing key to a
measured enclave:
"x_tee_attestation": {
"tee_type": "sev-snp", // "sev-snp" | "tdx"
"quote": "base64…", // raw attestation report bytes
"report_data_alg": "sha512", // binds report_data to the signing key
"vcek_cert": "base64…" // optional leaf cert (else fetched from the vendor KDS)
}
The enclave requests its quote with
report_data = SHA-512(agent signing public key), so
the hardware signs the key's hash into the quote. A TEE-aware
verifier, if this field is present, MUST verify the quote
signature to the vendor root, MUST confirm report_data
binds to agent_key_id, and MAY enforce an allowlist
of approved enclave measurements. A verifier that does not
understand TEE attestation MUST ignore the field (it is
x_-namespaced) — the receipt remains valid as an
ordinary signed receipt. Full design:
tee-attested-provenance.md.
15. Worked example
A guardrail scan receipt covering the user's initial prompt.
The signed payload (canonical JSON, line-wrapped here for
reading):
{
"agent_id": "agent:raucle.scanner",
"agent_key_id": "k_8c2f4e1a",
"iat": 1748505600,
"iss": "https://acme.example/raucle",
"operation": "guardrail_scan",
"parents": ["c1d2…f4a9"],
"input_hash": "9f86d081884c7d65…",
"output_hash": "9f86d081884c7d65…",
"ruleset_hash": "1a79a4d60de6718e…",
"guardrail_verdict": "ALLOW",
"taint": ["untrusted_user"]
}
Wrapped as Compact JWS the on-wire form is roughly:
eyJhbGciOiJFZERTQSIsImtpZCI6Imtf8GMyZjRlMWEiLCJ0eXAiOiJwcm92ZW5hbmNlLXJlY2VpcHQvdjEiLCJjcml0IjpbInJhdWNsZS92MSJdfQ.eyJhZ2VudF9pZCI6…
Its identifier — what descendants cite in their
parents — is the SHA-256 hex of those ASCII bytes
including the two dots.
16. References
- RFC 2119 — Key words for use in RFCs.
- RFC 7515 — JSON Web Signature (JWS).
- RFC 8032 — Ed25519.
- RFC 8785 — JSON Canonicalisation Scheme (JCS).
-
Reference implementations (all emit + verify the same wire
format; cross-language interop verified):
Python (raucle-detect),
TypeScript,
Go,
Rust,
C#.