| Internet-Draft | CCS Runtime Verification Receipt | August 2026 |
| Wang & Wang | Expires 8 February 2027 | [Page] |
The Correctover Conformance Shape (CCS) defines a tamper-evident, cryptographically bound receipt format that provides runtime verification for agent tool invocations. Each CCS receipt captures a seven-dimensional verification outcome -- Structure, Schema, Latency, Cost, Identity, Integrity, and Security -- as a single artifact suitable for consumption by audit, compliance, and observability systems.¶
CCS is designed as a pluggable runtime verification infrastructure layer that complements -- but does not replace -- existing and emerging agent protocol work at the IETF. Specifically: (1) the AUDIT effort (draft-kuehlewind-audit-architecture) defines an auditing architecture with Action Record and Authorization Transition Record types; a CCS receipt provides the verifiable, tamper-evident evidence payload that can populate these record types with cryptographically bound proof of runtime governance decisions. (2) The agentproto WG-forming effort (IETF 126 BoF) addresses agent-to-agent and agent-to-tool communication protocols; CCS provides per-invocation, sub-millisecond runtime verification that operates beneath the session/transport layer, complementing protocol-level context exchange with evidence-level integrity guarantees.¶
Version 1.1 of the CCS receipt comprises 29 fields with full Ed25519 signature coverage, including three causal chain fields (rule_version, tool_call_id, args_digest) that elevate the Integrity dimension from behavioral traceability to verifiable decision causality. The reference implementation (ccs-verifier v1.1.0, PyPI) passes 154 conformance tests across all verification dimensions.¶
This document specifies the CCS Receipt Schema, the Canonical Configuration model, the nine binding mechanisms, key management, transport requirements, verifier source classification, conformance levels, and negative test cases. CCS is protocol-agnostic: it is not bound to Model Context Protocol (MCP), Agent2Agent (A2A), or any other specific agent protocol, and can be integrated into any runtime that governs tool invocations.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 8 February 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Correctover Conformance Shape (CCS) is a receipt-and-binding specification that produces a single, tamper-evident, cryptographically bound artifact for every tool invocation decision made by an agent runtime's governance layer. A CCS receipt answers: "Given this exact request, this exact configuration, this exact runtime context, and this exact set of rules, the verifier decided ALLOW/DENY/ESCALATE, and here is the proof."¶
CCS is defined as a seven-dimensional runtime verification standard: (1) Structure -- output structural completeness; (2) Schema -- field value conformance; (3) Latency -- within SLA bounds; (4) Cost -- within budget; (5) Identity -- correct model version; (6) Integrity -- HMAC untampered; (7) Security -- RCE/SSRF/credential hijacking interception. CCS is a general-purpose agent verification framework, not limited to any specific protocol such as MCP or A2A.¶
CCS is not a policy language, an authorization framework, or a transport protocol. It is the shape of the evidence that a verifier produces when it finishes evaluating a command. This evidence is intended to be consumed by downstream systems -- including an executor- side Action Evidence Boundary (AEB) as defined in [I-D.schrock-action-evidence-boundary] -- as one native artifact within a larger Authorization Evidence Chain (AEC).¶
The reference implementation (ccs-verifier v1.1.0, available on PyPI under Proprietary Commercial License) provides an in-process verifier with Ed25519 receipt signing covering all 29 receipt fields, including the three v1.1 causal chain fields (rule_version, tool_call_id, args_digest). The implementation passes 154 conformance tests and supports both in-process and out-of-process deployment modes.¶
CCS specifies:¶
A receipt schema (Section 3) that binds a verdict to the exact invocation context.¶
A canonical configuration model (Section 5) that binds the receipt to the exact rule set and policy under which verification occurred.¶
Nine binding mechanisms (Section 6) that connect the receipt to the request bytes, response bytes, runtime context, action identity, parameter identity, issuer, audience, nonce, and freshness window.¶
Transport requirements (Section 8) including fail-closed semantics.¶
Conformance levels and test vectors (Section 10 and Section 11).¶
CCS does NOT define:¶
A new authorization receipt format that replaces or competes with [I-D.schrock-ep-authorization-receipts]. CCS is a verifier-side decision record, not an organizational authorization artifact.¶
A policy language. Rules are pluggable; CCS specifies how rule outcomes are recorded and bound, not what the rules are.¶
A transport protocol for inter-process communication. The reference implementation uses in-process function calls; the out-of-process transport has been implemented with Unix-socket and TCP with TLS.¶
A universal evidence taxonomy. CCS defines one artifact shape for one class of decision (tool-invocation governance).¶
A session management protocol or agent-to-agent communication protocol. CCS operates at the per-invocation verification layer, beneath session and transport protocols.¶
Two active areas of IETF work are directly relevant to the problem of agent runtime verification and auditing. This section clarifies how CCS relates to each effort and what gap it fills.¶
In summary, CCS occupies a distinct layer in the agent protocol stack: it is neither a session protocol (like agentproto), nor an audit data model (like the AUDIT architecture), nor a communication protocol (like MCP or A2A). It is the runtime verification infrastructure layer that produces the tamper-evident receipts that both audit systems and protocol implementations can consume as proof of governance.¶
This Internet-Draft is a protocol specification derived from and complementary to the following academic publications:¶
DOI: 10.5281/zenodo.21783723 -- "CCS 7-Dimensional Runtime Verification Framework v0.4.1 Three-Endpoint Closed Loop." This work documents the complete three-endpoint closed loop: IETF Internet-Draft + Zenodo DOI + PyPI ccs-verifier v1.1.0. It covers the seven-dimensional verification model and its implementation.¶
DOI: 10.5281/zenodo.21271910 -- "CCS Formal Framework." This paper defines the mathematical foundation: the Required(tau) subset of Supported(tau) conformance criterion, the transition model, and the formal proof that fail-closed enforcement satisfies the governance criterion. This I-D does not reproduce the formal framework; it specifies the wire-level receipt and binding mechanisms that implement it.¶
DOI: 10.5281/zenodo.21603250 -- "Action Receipts." This paper defines the concept of an action receipt as a tamper-evident record binding a decision to a specific action invocation. The CCS receipt in this I-D is a concrete instantiation of that concept, specialized for tool-invocation governance in agent runtimes.¶
A Palo Alto Networks (PANW) contributor cited CCS DOI in a fork of Palo-Alto-AI-Research-Lab/semantic-kernel (PR #14199, closed by Microsoft). This citation is noted as evidence of external interest in the CCS DOI; it does not constitute adoption by Microsoft or the Semantic Kernel project. Major frameworks including CrewAI and AutoGen are part of the broader agent ecosystem that CCS is designed to serve; CCS DOI has been cited in related research contexts.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
CCS-specific terms:¶
Command: An immutable, structured representation of a tool invocation request, comprising at minimum: agent_id, tool name, parameters, timestamp, and trace_id. The Command is the input to verification.¶
Verifier: A component that evaluates a Command against a set of Rules and produces a VerificationResult. The verifier MAY run in- process (same address space as the agent) or out-of-process (separate address space, separate crash domain).¶
Rule: A pluggable unit of policy evaluation. A Rule accepts a Command and returns a RuleResult with a verdict (allow, deny, escalate), an optional reason string, and a latency measurement.¶
VerificationResult: The output of a verification. Contains the verdict, signed receipt, rule results, and metadata.¶
Receipt: A cryptographically signed digest (HMAC-SHA256 or Ed25519) that binds the verification context to a signing key, providing tamper-evident audit.¶
Config Hash: A SHA-256 digest of the canonical JSON representation of the verifier's configuration (rule set, policy version, signing key identifier). Binds the receipt to the exact policy under which verification occurred.¶
Fail-closed: A property of the enforcement mechanism whereby any failure in the verification path -- exception, timeout, missing input, ambiguous state -- results in the tool invocation being blocked, not allowed. This is the opposite of fail-open (CWE-636).¶
Conformance Shape: The complete set of fields, bindings, and semantic constraints that a CCS receipt MUST satisfy to be considered conformant at a given level.¶
A conforming CCS Receipt is a JSON object conforming to I-JSON [RFC7493]. The receipt comprises 29 fields. Version 1.1 (ccs-verifier v1.1.0) includes all 29 fields with full Ed25519 signature coverage. Fields marked "Implemented" are present and operational in ccs-verifier v1.1.0.¶
+====================+========+===========+===========+=================+ |Field |Type |Status |Required |Description | +====================+========+===========+===========+=================+ |trace_id |string |Implemented|MUST |SHA-256 of | | |(16-char| | |time.time_ns(), | | |hex) | | |truncated to 16 | | | | | |hex chars. | | | | | |Uniquely | | | | | |identifies this | | | | | |verification | | | | | |event. | +--------------------+--------+-----------+-----------+-----------------+ |verdict |string |Implemented|MUST |One of: "allow", | | |enum | | |"deny", | | | | | |"escalate". | +--------------------+--------+-----------+-----------+-----------------+ |timestamp |float |Implemented|MUST |Unix timestamp | | | | | |at verdict time. | +--------------------+--------+-----------+-----------+-----------------+ |tool |string |Implemented|MUST |The tool name | | | | | |from the Command.| +--------------------+--------+-----------+-----------+-----------------+ |params_hash |string |Implemented|MUST |SHA-256 of | | |(16-char| | |canonical JSON of| | |hex) | | |Command.params, | | | | | |truncated to 16. | +--------------------+--------+-----------+-----------+-----------------+ |rule_summary |string |Implemented|MUST |Pipe-delimited | | | | | |rule_name=verdict| | | | | |pairs. | +--------------------+--------+-----------+-----------+-----------------+ |receipt |string |Implemented|MUST |Ed25519 (or HMAC-| | |(hex) | | |SHA256) signature| +--------------------+--------+-----------+-----------+-----------------+ |verified_at |float |Implemented|MUST |Unix timestamp of| | | | | |verification. | +--------------------+--------+-----------+-----------+-----------------+ |block_reason |string |Implemented|Conditional|Reason for deny/ | | | | | |escalate. Empty | | | | | |for allow. | +--------------------+--------+-----------+-----------+-----------------+ |request_hash |string |Implemented|MUST |SHA-256 of | | |(hex) | | |canonical request| | | | | |bytes. | +--------------------+--------+-----------+-----------+-----------------+ |response_hash |string |Implemented|SHOULD |SHA-256 of tool | | |(hex) | | |response bytes. | +--------------------+--------+-----------+-----------+-----------------+ |runtime_context_hash|string |Implemented|SHOULD |SHA-256 of | | |(hex) | | |runtime context. | +--------------------+--------+-----------+-----------+-----------------+ |action |string |Implemented|MUST |CAID-compatible | | | | | |action identifier| +--------------------+--------+-----------+-----------+-----------------+ |config_hash |string |Implemented|MUST |SHA-256 of | | |(hex) | | |canonical config.| +--------------------+--------+-----------+-----------+-----------------+ |issuer |string |Implemented|MUST |Verifier URI | | |(URI) | | |identifier. | +--------------------+--------+-----------+-----------+-----------------+ |audience |string |Implemented|MUST |Intended consumer| | |(URI) | | |URI identifier. | +--------------------+--------+-----------+-----------+-----------------+ |nonce |string |Implemented|MUST |Single-use anti- | | |(hex) | | |replay value. | +--------------------+--------+-----------+-----------+-----------------+ |sequence |integer |Implemented|SHOULD |Monotonic counter| | | | | |per issuer. | +--------------------+--------+-----------+-----------+-----------------+ |issued_at |float |Implemented|MUST |Receipt issuance | | | | | |timestamp. | +--------------------+--------+-----------+-----------+-----------------+ |expires_at |float |Implemented|MUST |Receipt expiry | | | | | |timestamp. | +--------------------+--------+-----------+-----------+-----------------+ |max_clock_skew |float |Implemented|SHOULD |Max clock skew | | | | | |tolerance (sec). | | | | | |Default: 30.0. | +--------------------+--------+-----------+-----------+-----------------+ |rule_version |string |Implemented|MUST |Decision rule | | | | | |version (v1.1). | +--------------------+--------+-----------+-----------+-----------------+ |tool_call_id |string |Implemented|MUST |Unique tool call | | |(UUID) | | |ID (v1.1). | +--------------------+--------+-----------+-----------+-----------------+ |args_digest |string |Implemented|MUST |SHA-256 of exact | | |(hex) | | |exec args (v1.1).| +--------------------+--------+-----------+-----------+-----------------+
The receipt field is computed over a signing payload. In v1.1 (ccs-verifier v1.1.0), Ed25519 is used with the following payload:¶
v1.1_payload = "{trace_id}:{verdict}:{timestamp}:{tool}:{params_hash}:{rule_summary}:{rule_version}:{tool_call_id}:{args_digest}"
¶
The Ed25519 signature is computed over UTF-8 encoding of this payload. The full 64-byte Ed25519 signature is included in the receipt field.¶
Extended signing payload (for full AEC mapping with all 29 fields):¶
extended_payload = "{trace_id}:{verdict}:{timestamp}:{tool}:{params_hash}:{rule_summary}:{request_hash}:{response_hash}:{runtime_context_hash}:{action}:{config_hash}:{issuer}:{audience}:{nonce}:{sequence}:{issued_at}:{expires_at}:{rule_version}:{tool_call_id}:{args_digest}"
¶
Critical property: The signed bytes cover the full verification context. Any change to any signed field invalidates the receipt.¶
The following is an example CCS receipt as produced by ccs-verifier v1.1.0 with all 29 fields populated and Ed25519 signature:¶
{
"trace_id": "a1b2c3d4e5f67890",
"verdict": "allow",
"timestamp": 1722384000.123456,
"tool": "search_web",
"params_hash": "1234567890abcdef",
"rule_summary": "ssrf_protection=allow|rce_protection=allow|credential_leak=allow",
"receipt": "ed25519:<64-byte-hex-signature>",
"verified_at": 1722384000.123890,
"block_reason": "",
"request_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb924...",
"response_hash": "",
"runtime_context_hash": "sha256:7d865e959b2466918c180089...",
"action": "ccs:tool-invoke:search_web:sha256:1234567890abcdef",
"config_hash": "sha256:aabbccdd0011223344556677...",
"issuer": "https://verifier.example.com/ccs/v1",
"audience": "https://executor.example.com/aeb",
"nonce": "f47ac10b58cc4372a5670e02b2c3d479",
"sequence": 42,
"issued_at": 1722384000.123000,
"expires_at": 1722384060.123000,
"max_clock_skew": 30.0,
"rule_version": "1.1.0",
"tool_call_id": "550e8400-e29b-41d4-a716-446655440000",
"args_digest": "sha256:9f86d081884c7d659a2feaa0c55ad015..."
}
¶
Version 1.1 introduces three fields that extend the CCS Integrity dimension from "behavioral traceability" to "verifiable decision causality chains." These fields address two attack scenarios:¶
Scenario 1: Legitimate chain masking garbage decisions. An attacker constructs a valid CCS receipt chain where each receipt passes cryptographic verification, but the underlying decision rules are systematically degraded. Without rule_version binding, the chain appears valid despite decisions being produced by different rules.¶
Scenario 2: Silent-Drop (approval-execution decoupling). An attacker obtains a valid approval, silently drops the approved invocation, and substitutes a different invocation with different arguments. Without tool_call_id and args_digest, the executor cannot detect the swap.¶
rule_version: A version identifier identifying the specific version of the decision rule set that produced this verdict. Enables detection of rule drift.¶
tool_call_id: A UUID (RFC 4122) uniquely identifying a single tool invocation instance from dispatch. Creates an unbreakable link between the approval decision and the specific execution. The executor MUST verify that the tool_call_id in the CCS receipt matches the invocation being executed.¶
args_digest: SHA-256 of the exact arguments passed to the tool at execution time (hex string). Distinct from params_hash: params_hash captures pre-verification parameters as seen by governance; args_digest captures post-approval execution-time arguments as seen by the executor. Divergence indicates argument modification between approval and execution.¶
Signing requirement: All three fields MUST be included in the Ed25519 signature scope (see Section 3.2).¶
Backward compatibility: The three new fields are OPTIONAL for existing Level 0-2 implementations. Implementations targeting Level 3 or claiming v1.1 conformance MUST include all three fields.¶
A CCS Canonical Configuration is a JSON object that describes the exact state of the verifier at the time a receipt was issued. It MUST contain:¶
+==================+==========+==========+=======================+ | Field | Type | Required | Description | +==================+==========+==========+=======================+ | rules | array of | MUST | Ordered list of rule | | | strings | | names as registered. | +------------------+----------+----------+-----------------------+ | policy_version | string | MUST | Version identifier of | | | | | the policy. | +------------------+----------+----------+-----------------------+ | signing_key_id | string | MUST | Identifier of the | | | | | signing key. | +------------------+----------+----------+-----------------------+ | verifier_version | string | MUST | Software version of | | | | | the verifier. | +------------------+----------+----------+-----------------------+ | schema_version | string | MUST | CCS receipt schema | | | | | version (e.g. "1.1"). | +------------------+----------+----------+-----------------------+ | deployment_mode | string | MUST | "in-process" or "out- | | | enum | | of-process". | +------------------+----------+----------+-----------------------+
The canonical configuration MUST be serialized using JSON Canonicalization Scheme (JCS) as defined in [RFC8785]:¶
def canonical_config(config: dict) -> bytes:
"""Serialize config to canonical JSON per RFC 8785 (JCS)."""
return json.dumps(
config,
sort_keys=True,
separators=(",", ":"),
ensure_ascii=True,
allow_nan=False
).encode("utf-8")
¶
Key properties: keys sorted lexicographically, no whitespace between tokens (compact form), ASCII-only encoding, NaN and Infinity not permitted.¶
The config_hash is computed as:¶
config_hash = hashlib.sha256(canonical_config(config)).hexdigest()¶
The config_hash MUST be included in the extended signing payload (Section 3.2) when the extended fields are in use.¶
This section defines the nine binding mechanisms that connect a CCS receipt to the various elements of the invocation lifecycle.¶
Purpose: Bind the receipt to the exact request bytes as received by the verifier.¶
def canonical_bytes(command) -> bytes:
return json.dumps({
"agent_id": command.agent_id,
"tool": command.tool,
"params": command.params,
"timestamp": command.timestamp,
"trace_id": command.trace_id,
}, sort_keys=True, separators=(",", ":")).encode("utf-8")
request_hash = "sha256:" + hashlib.sha256(canonical_bytes(command)).hexdigest()
¶
Purpose: Bind the receipt to the exact response produced by the tool invocation.¶
response_hash = "sha256:" + hashlib.sha256(response_bytes).hexdigest()¶
Timing: Computed after tool invocation completes (post-hoc binding).¶
Purpose: Bind the receipt to the runtime execution environment.¶
context_bytes = json.dumps(context, sort_keys=True,
separators=(",", ":")).encode("utf-8")
runtime_context_hash = "sha256:" + hashlib.sha256(context_bytes).hexdigest()
¶
Purpose: Provide a CAID-compatible action identifier.¶
action = "ccs:tool-invoke:{tool_name}:{params_hash}"
¶
The source media type is "application/x-ccs-receipt+json".¶
Purpose: Bind the receipt to the exact tool parameters.¶
def params_hash(params: dict) -> str:
return hashlib.sha256(
json.dumps(params, sort_keys=True,
separators=(",", ":")).encode()
).hexdigest()[:16]
¶
Implementations targeting Level 2+ SHOULD use full SHA-256 digest.¶
Purpose: Identify the verifier that produced the receipt. The URI MUST be stable across key rotations and covered by the signature.¶
Purpose: Identify the intended consumer. A receipt whose audience does not match the consumer MUST be rejected.¶
Purpose: Prevent replay. The consumer MUST maintain a replay cache of seen (issuer, nonce) pairs. A previously-seen nonce MUST be rejected. The cache MUST persist across restarts.¶
Purpose: Bound the temporal validity of the receipt.¶
def check_freshness(receipt, local_time, max_clock_skew=30.0):
skew = receipt.max_clock_skew or 30.0
if local_time < receipt.issued_at - skew:
return False
if local_time > receipt.expires_at + skew:
return False
return True
¶
Recommended expiry: issued_at + 60 seconds for tool-invocation governance.¶
HMAC-SHA256 (backward compatible): signing_key = secrets.token_bytes(32). The key MUST NOT be derived from predictable sources.¶
Ed25519 (implemented in ccs-verifier v1.1.0):¶
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey, Ed25519PublicKey
)
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()
¶
HMAC: shared secret via secure channel. Ed25519: public key pinned via out-of-band mechanism.¶
Phased: Announce -> Dual-sign -> Cutover -> Retire. Overlap window MUST be at least 2x maximum receipt lifetime.¶
In-process: shared address space, signing key accessible. Out-of-process: separate process, signing key protected. Out-of-process is RECOMMENDED for security-critical applications.¶
CCS enforcement MUST be fail-closed. If the verifier raises an exception, times out, returns ambiguous result, or is unreachable, the tool invocation MUST be blocked.¶
def govern(fn, policy="default"):
def wrapper(*args, **kwargs):
try:
result = verifier.verify(command)
if not result.allowed:
raise PermissionError(result.block_reason)
except Exception:
raise PermissionError("Verification failed")
return fn(*args, **kwargs)
return wrapper
¶
This is the fundamental difference from observer-pattern hooks (which fail-open per [CWE-636]).¶
Verifier timeout: invocation MUST be blocked. Receipt timeout: expired receipts MUST be rejected. Both are independent and both MUST be enforced.¶
+==================+==================+=======================+ | Property | In-Process | Out-of-Process | +==================+==================+=======================+ | Process boundary | None (shared | Full (separate | | | address space) | process) | +------------------+------------------+-----------------------+ | Signing key | Vulnerable to | Protected | | exposure | agent compromise | | +------------------+------------------+-----------------------+ | Crash isolation | None | Full | +------------------+------------------+-----------------------+ | Latency | ~7.5us P50 | ~133us P50 | | | (ccs-verifier | (Unix-socket/TCP+TLS) | | | v1.1.0) | | +------------------+------------------+-----------------------+ | Implementation | Implemented | Implemented: | | status | (v1.1.0) | Unix-socket + TCP/TLS | +------------------+------------------+-----------------------+ | Conformance | Level 0-1 | Level 2-3 | | level | | | +------------------+------------------+-----------------------+
Note: P50/P99 latency figures are informational measurements, not normative requirements.¶
Built, operated, and audited by the relying party's own organization. Assurance: Highest.¶
Built by third party, independently audited. Assurance: High.¶
Operator claims conformance without independent audit. Assurance: Low.¶
Level 0 -- Baseline: Signed receipt covering trace_id, verdict, timestamp, tool, params_hash, rule_summary. Fail-closed implemented.¶
Level 1 -- Extended Bindings (ccs-verifier v1.1.0): Adds request_hash, config_hash. Ed25519 signing. All 29 fields populated including v1.1 causal chain fields. 154 tests passed.¶
Level 2 -- Full AEC Readiness: Adds response_hash, runtime_context_hash, action, issuer, audience, nonce, sequence, issued_at, expires_at, max_clock_skew.¶
Level 3 -- Out-of-Process with Full Isolation: Separate process, key protection, distributed replay prevention.¶
CV-001: Basic ALLOW receipt (Level 0). CV-002: Basic DENY receipt. CV-003: Config hash binding (Level 1). CV-004: Request hash binding. CV-005: Issuer/audience binding (Level 2). CV-006: Freshness enforcement.¶
ccs-verifier v1.1.0 passes 154 conformance tests across all levels.¶
Ten negative test cases: eight original plus two v1.1.¶
Attacker modifies tool parameters. params_hash mismatch detects it. Binding defeated if removed: params_hash binding (Section 6.5).¶
Attacker modifies tool response. response_hash mismatch detects it. Binding defeated if removed: response_hash binding (Section 6.2).¶
Attacker replays receipt. Nonce in replay cache detects it. Binding defeated if removed: nonce/sequence binding (Section 6.8).¶
Attacker presents old receipt. expires_at check detects it. Binding defeated if removed: freshness binding (Section 6.9).¶
Attacker redirects receipt. audience mismatch detects it. Binding defeated if removed: audience binding (Section 6.7).¶
Attacker forges receipt with own key. Issuer trust check detects it. Binding defeated if removed: issuer binding (Section 6.6).¶
Verifier always returns ALLOW. Statistical monitoring + Class B/A audit mitigates. Not a cryptographic attack.¶
Transport unavailable, runtime falls back to allow. Fail-closed semantics (Section 8.1) MUST block the invocation.¶
Attacker replays receipt from old rule version. rule_version mismatch detects it. Binding defeated if removed: rule_version binding (Section 4).¶
Attacker substitutes invocation after approval. tool_call_id and args_digest mismatch detects it. Binding defeated if removed: tool_call_id and args_digest binding (Section 4).¶
Truncated hashes: params_hash truncated to 16 hex chars (64 bits) in 0.4.1 HMAC mode. Cross-deployment SHOULD use full-length. v1.1 Ed25519 mode uses full 64-byte signatures.¶
HMAC key exposure in in-process mode: compromised agent can read signing key. Out-of-process mitigates this (Unix-socket and TCP/TLS implemented in v1.1.0).¶
Float timestamp precision: IEEE 754 double provides ~15-17 significant digits. Implementations SHOULD use monotonic clocks for latency and wall clocks for issuance.¶
JSON canonicalization: params_hash and config_hash depend on deterministic serialization per Section 3.2 and Section 5.2.¶
Rule evaluation ordering: DENY short-circuits, so rule_summary MAY differ. config_hash (Level 1+) binds to exact rule set.¶
TOCTOU: runtime_context_hash (Level 2) mitigates environment change between verification and execution.¶
Receipt chaining: not defined. Use sequence field (Section 6.8) or external chaining.¶
Causal chain integrity (v1.1): rule_version, tool_call_id, args_digest derive security from Ed25519 scope. Private key MUST be verifier-only. rule_version from canonical config. tool_call_id generated before approval. args_digest from exact execution bytes.¶
params_hash vs args_digest: params_hash = pre-verification (governance view); args_digest = post-approval (executor view). Divergence for same tool_call_id indicates silent-drop attack (Section 11.10).¶
This document does not request any IANA allocations.¶
+==+====================+=======+=====+===========+======+============+ |# |Field |Type |Level|Status |Signed|Description | +==+====================+=======+=====+===========+======+============+ |1 |trace_id |16-char|0 |Implemented|Yes |Unique event| | | |hex | | | |identifier | +--+--------------------+-------+-----+-----------+------+------------+ |2 |verdict |enum |0 |Implemented|Yes |allow / deny| | | |string | | | |/ escalate | +--+--------------------+-------+-----+-----------+------+------------+ |3 |timestamp |float |0 |Implemented|Yes |Verification| | | | | | | |time | +--+--------------------+-------+-----+-----------+------+------------+ |4 |tool |string |0 |Implemented|Yes |Tool name | +--+--------------------+-------+-----+-----------+------+------------+ |5 |params_hash |16-char|0 |Implemented|Yes |SHA-256 of | | | |hex | | | |params | +--+--------------------+-------+-----+-----------+------+------------+ |6 |rule_summary |string |0 |Implemented|Yes |Pipe-delimited| | | | | | | |rule results| +--+--------------------+-------+-----+-----------+------+------------+ |7 |receipt |hex |0 |Implemented|N/A |Ed25519 / | | | | | | | |HMAC sig | +--+--------------------+-------+-----+-----------+------+------------+ |8 |verified_at |float |0 |Implemented|No |Verification| | | | | | | |timestamp | +--+--------------------+-------+-----+-----------+------+------------+ |9 |block_reason |string |0 |Implemented|No |Deny reason | +--+--------------------+-------+-----+-----------+------+------------+ |10|request_hash |hex |1 |Implemented|Yes |SHA-256 of | | | |string | | | |full request| +--+--------------------+-------+-----+-----------+------+------------+ |11|config_hash |hex |1 |Implemented|Yes |SHA-256 of | | | |string | | | |config | +--+--------------------+-------+-----+-----------+------+------------+ |12|response_hash |hex |2 |Implemented|Post |SHA-256 of | | | |string | | | |response | +--+--------------------+-------+-----+-----------+------+------------+ |13|runtime_context_hash|hex |2 |Implemented|Yes |SHA-256 of | | | |string | | | |runtime ctx | +--+--------------------+-------+-----+-----------+------+------------+ |14|action |string |2 |Implemented|Yes |CAID action | | | | | | | |identifier | +--+--------------------+-------+-----+-----------+------+------------+ |15|issuer |URI |2 |Implemented|Yes |Verifier ID | | | |string | | | | | +--+--------------------+-------+-----+-----------+------+------------+ |16|audience |URI |2 |Implemented|Yes |Consumer ID | | | |string | | | | | +--+--------------------+-------+-----+-----------+------+------------+ |17|nonce |hex |2 |Implemented|Yes |Anti-replay | | | |string | | | | | +--+--------------------+-------+-----+-----------+------+------------+ |18|sequence |integer|2 |Implemented|Yes |Monotonic | | | | | | | |counter | +--+--------------------+-------+-----+-----------+------+------------+ |19|issued_at |float |2 |Implemented|Yes |Issue time | +--+--------------------+-------+-----+-----------+------+------------+ |20|expires_at |float |2 |Implemented|Yes |Expiry time | +--+--------------------+-------+-----+-----------+------+------------+ |21|max_clock_skew |float |2 |Implemented|Yes |Clock skew | | | | | | | |tolerance | +--+--------------------+-------+-----+-----------+------+------------+ |22|rule_version |string |3 |Impl(v1.1) |Yes |Rule version| +--+--------------------+-------+-----+-----------+------+------------+ |23|tool_call_id |UUID |3 |Impl(v1.1) |Yes |Tool call ID| +--+--------------------+-------+-----+-----------+------+------------+ |24|args_digest |hex |3 |Impl(v1.1) |Yes |Exec args | | | |string | | | |digest | +--+--------------------+-------+-----+-----------+------+------------+
Each conformance test vector is encoded as a JSON object:¶
{
"vector_id": "CV-001",
"description": "Basic ALLOW receipt verification",
"level": 0,
"category": "positive",
"input": {
"command": {
"agent_id": "test-agent",
"tool": "search_web",
"params": {"query": "weather in Tokyo"},
"timestamp": 1722384000.0,
"trace_id": "0000000000000001"
},
"rules": ["ssrf_protection", "rce_protection", "credential_leak"],
"signing_key_hex": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
},
"expected": {
"verdict": "allow",
"block_reason": "",
"receipt_valid": true,
"rule_summary_pattern": "ssrf_protection=allow|rce_protection=allow|credential_leak=allow"
}
}
For negative test vectors:
{
"vector_id": "NV-001",
"description": "Changed arguments detected by params_hash mismatch",
"level": 0,
"category": "negative",
"attack": {
"type": "changed_arguments",
"modification": "params changed"
},
"expected": {
"detection_point": "params_hash mismatch",
"verdict": "deny",
"binding_defeated_if_removed": "params_hash (Section 5.5)"
}
}
¶