VAL-RF — Receipt Format Specification

Version: 0.1 Status: Draft License: Apache License 2.0 Editor: Open VAL Foundation (pending donation; currently VAL Inc.)


1. Abstract

This specification defines the VAL Receipt Format (RF) — a cryptographically signed record of an agent action decision and its outcome, bound to a VAL-AM manifest and a VAL-CPL policy set hash, chained to a tamper-evident ledger, and verifiable by any third party without trusting the issuer.

2. Goals

A VAL-RF receipt MUST:

  1. Bind to a specific Action Manifest by hash.
  2. Bind to a specific Conduct Policy Set by hash.
  3. Bind to the immediately prior receipt by hash (tamper-evident chain).
  4. Be signed by a key controlled by the operator (NOT by VAL Inc.).
  5. Include an independent RFC 3161 timestamp.
  6. Be verifiable offline given (a) the receipt, (b) the operator's public key, (c) the spec.

3. Threat Model

VAL-RF is designed to resist:

VAL-RF is NOT designed to resist:

4. Receipt Structure

A receipt is a CBOR-encoded object (RFC 8949) wrapped in a COSE_Sign1 structure (RFC 9052) for the operator signature. Top-level CBOR map (decoded into JSON for human readability below):

4.1 The signed payload

{
  "receipt_id": "<UUIDv7 string>",
  "spec_version": "0.1",
  "issued_at": "<RFC 3339 UTC timestamp>",
  "issuer": "<operator URN>",
  "agent": {
    "id": "<agent id from manifest>",
    "substrate": {
      "vendor": "<vendor>",
      "model": "<model id>",
      "version": "<version>"
    }
  },
  "manifest_hash": "<SHA-256 hex digest of canonicalized VAL-AM manifest>",
  "policy": {
    "policy_set_hash": "<SHA-256 hex>",
    "decision": {
      "effect": "ALLOW" | "DENY" | "ESCALATE" | "REFUSE" | "PAUSE",
      "matched_rules": [
        { "name": "<rule>", "policy_name": "<policy>" },
        ...
      ],
      "external_signals_used": ["<signal path>", ...]
    }
  },
  "approval": {
    "required": <boolean>,
    "approver_urn": "<URN of approver, or null>",
    "approver_method": "human" | "policy_attached" | "none",
    "approved_at": "<RFC 3339 UTC timestamp, or null>"
  },
  "outcome": {
    "executed": <boolean>,
    "status": "success" | "failure" | "blocked" | "timeout",
    "error_class": "<short error class, or null>",
    "executed_at": "<RFC 3339 UTC timestamp, or null>",
    "duration_ms": <integer, or null>
  },
  "chain": {
    "prev_receipt_hash": "<SHA-256 hex of prior receipt's signed payload, or null for genesis>",
    "sequence_number": <integer, monotonic per operator>
  },
  "timestamp": {
    "tsa_url": "<URL of TSA>",
    "tsa_token": "<base64-encoded RFC 3161 TimeStampToken>"
  },
  "extensions": {
    "<namespace>": { ... }
  }
}

4.2 The COSE_Sign1 envelope

The payload above is RFC 8785 JCS canonicalized → CBOR-encoded → wrapped in a COSE_Sign1 structure with the operator's signing key. The signature algorithm SHALL be one of:

AlgorithmCOSE identifierNotes
ES256-7ECDSA over P-256 with SHA-256. RECOMMENDED default.
ES384-35ECDSA over P-384.
EdDSA-8Ed25519. RECOMMENDED for long-term archival.
RS256-257RSASSA-PKCS1-v1_5 with SHA-256. Permitted for compatibility.

5. Hash Chain

Each receipt's chain.prev_receipt_hash is the SHA-256 of the prior receipt's signed payload (the COSE_Sign1 protected bytes, not the inner CBOR alone). The chain starts at a genesis receipt with prev_receipt_hash = null and sequence_number = 0.

The hash chain provides tamper evidence: alteration of any past receipt invalidates every subsequent receipt's chain. An auditor verifies the chain by walking from genesis forward (or from the most recent receipt backward).

Operators MAY publish periodic chain checkpoints — a signed root hash of the chain at a given height — to anchor the chain externally (e.g., to a public blockchain, a notary, or a third-party transparency log). Checkpoint format is defined in a separate VAL-RF Extensions document.

6. Signing Key Management

The operator's signing key SHALL be controlled by the operator, NOT by VAL Inc. or any reference implementation provider.

Recommended key management practices:

7. RFC 3161 Timestamping

Each receipt SHALL include a timestamp.tsa_token field containing an RFC 3161 TimeStampToken issued by an independent TSA. The TSA SHOULD be one that maintains its own audit trail and root-anchored CA chain (e.g., DigiCert, GlobalSign, or a national TSA).

The TSA's timestamp covers the signed payload hash (not the receipt's signature). This independently bounds the receipt's existence time. A receipt issued at sequence number N with TSA timestamp T proves the operator knew the payload no later than T.

Operators in jurisdictions without easy TSA access MAY use a publicly auditable alternative (e.g., publishing the receipt hash to a blockchain). Such alternatives MUST be declared in extensions["org.openval.alt_timestamp"].

8. Verification Procedure

A third-party verifier (regulator, auditor, insurer, court) verifies a receipt as follows:

  1. Parse the COSE_Sign1 envelope; extract protected header, signed payload, signature.
  2. Fetch the operator's public key from the URL referenced in the protected header's kid (key identifier).
  3. Verify the signature with the public key.
  4. Validate the RFC 3161 TimeStampToken against the operator-archived TSA chain.
  5. Verify the hash chain — for each receipt in the verification window, compute SHA-256 of the prior receipt's signed payload and compare to chain.prev_receipt_hash.
  6. Verify the manifest binding — if the original manifest is available, canonicalize via JCS, hash via SHA-256, and compare to manifest_hash.
  7. Verify the policy binding — if the original policy set is available, compute the set hash per VAL-CPL Section 8 and compare to policy_set_hash.

A receipt that passes all six checks is cryptographically authentic. Authenticity does not imply correctness of the policy decision — only that the decision was emitted by the operator-controlled key at the time claimed.

9. Worked Example

Genesis receipt for operator acme.example:

{
  "receipt_id": "01963d2a-2e4f-7d6a-9c01-b3a7f8e9c2d1",
  "spec_version": "0.1",
  "issued_at": "2026-06-07T14:23:51.490Z",
  "issuer": "urn:val:operator:acme.example",
  "agent": {
    "id": "support-fleet/refund-handler-v3",
    "substrate": {
      "vendor": "anthropic",
      "model": "claude-opus-4-7",
      "version": "claude-opus-4-7"
    }
  },
  "manifest_hash": "a3f5b8c7d9e2f1a4b6c5d8e7f0a3b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
  "policy": {
    "policy_set_hash": "b4e6c9d8e3f2b1a5c7d6e9f8a1b4c3d2e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0",
    "decision": {
      "effect": "ESCALATE",
      "matched_rules": [
        { "name": "refund-cap", "policy_name": "acme-support-agent-conduct" }
      ],
      "external_signals_used": ["approver.role"]
    }
  },
  "approval": {
    "required": true,
    "approver_urn": "urn:val:user:acme.example:support-lead:lpark",
    "approver_method": "human",
    "approved_at": "2026-06-07T14:25:09.103Z"
  },
  "outcome": {
    "executed": true,
    "status": "success",
    "error_class": null,
    "executed_at": "2026-06-07T14:25:11.522Z",
    "duration_ms": 819
  },
  "chain": {
    "prev_receipt_hash": null,
    "sequence_number": 0
  },
  "timestamp": {
    "tsa_url": "https://timestamp.digicert.com",
    "tsa_token": "<base64-encoded RFC 3161 TimeStampToken>"
  }
}

The above payload is JCS-canonicalized, CBOR-encoded, signed via ES256 with the operator's key, and wrapped in COSE_Sign1.

10. Receipt Storage and Retention

The receipt format does not mandate a storage backend. Operators choose:

Retention SHOULD match the longest applicable regulatory window (e.g., 7 years for most financial regimes, indefinite for healthcare in some jurisdictions). The receipt format imposes no upper bound.

11. Policy Archive Practices

Receipt verification depends on the operator's ability to produce the policy text whose hash matches policy_set_hash. Operators SHOULD:

A receipt whose policy_set_hash cannot be matched to an archived policy version is verifiable as authentic, but its policy decision becomes unauditable. Operators that fail to retain policies effectively weaken their own audit posture.

12. Conformance

An implementation conforms to VAL-RF v0.1 if:

  1. It emits receipts with all REQUIRED fields per Section 4.
  2. It uses one of the signature algorithms in Section 4.2.
  3. It includes a valid RFC 3161 TimeStampToken (or declared alternative).
  4. It correctly chains receipts per Section 5.
  5. It supports the verification procedure in Section 8.
  6. It passes the VAL-RF Conformance Test Suite (published separately).

13. Security Considerations

14. Privacy Considerations

15. Change Log

16. References


End of VAL-RF v0.1.