DeniedCapabilityReceipt/v1
CFA signs a Denied Capability Receipt whenever a manifest, destination, host-preview, memory, or post-inference policy blocks an action. This page publishes the field-by-field schema, verification flow, versioning policy, and buyer-safe claim boundary for offline denial evidence.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
schema | string | yes | Must be DeniedCapabilityReceipt/v1. |
receipt_id | string | yes | Unique receipt identifier generated at signing time. |
timestamp | RFC 3339 datetime | yes | Local signer timestamp. |
manifest_id | string | yes | Manifest or policy envelope that made the denial decision. |
transaction_id | string or null | no | Fabric transaction spine identifier when supplied or generated upstream. |
denied_capability | string | yes | Capability class that was blocked, such as a port, resource, command, memory write, or output pattern. |
attempted_command | string array | yes | Normalized command vector associated with the denied action. |
attempted_resource | string or null | no | Resource, path, port, memory store, or destination associated with the denied action. |
denied_reason | string | yes | Machine-readable denial reason. |
policy_hash | string | yes | Hash of the policy material used by the signer. |
audit_chain | object | yes | Policy version, normalized policy hash, and manifest signature chain metadata. |
host_enforcement_proof | object or null | no | Host proof metadata when the denial came from a validated host-enforcement path. |
payload_hash | string | yes | Hash of the denied payload or destination request. |
public_key_id | string | yes | Short key identifier derived from the receipt public key. |
public_key_hex | string | yes | Ed25519 public key bytes encoded as lowercase hex. |
signature | string | yes | Ed25519 signature over the canonical unsigned receipt payload, encoded as lowercase hex. |
Canonical Signing Payload
The signature covers the unsigned receipt fields in their Rust serialization order and excludes only the signature field. A verifier must:
Decode
public_key_hex as a 32-byte Ed25519 public key.Recompute
public_key_id as the first 16 hex characters of sha256(public_key_hex).Serialize the unsigned receipt payload with the same field set and canonical order.
Verify
signature with Ed25519 before trusting the denial evidence.Offline Verification
CFA exposes an in-bundle verifier:
cfa receipt verify --file ./receipt.json
The standalone verifier package can verify the same receipt without the CFA runtime:
node verifier/bin/dcr-verify.js --file ./receipt.json
Public verifier usage is documented at /docs/verifier/.
The EU AI Act evidence export also runs this verification and records each receipt as valid or invalid in manifest.json.
Versioning Policy
The schema is append-only within DeniedCapabilityReceipt/v1: new optional fields may be added only if legacy verifiers can ignore them safely. Any change that alters the canonical signing payload, removes a required field, or changes field meaning requires a new schema version.