Skip to content

feat(audit): add optional external_execution_evidence on AuditEntry#330

Merged
imran-siddique merged 3 commits into
mainfrom
pr-314-rebase
Jun 22, 2026
Merged

feat(audit): add optional external_execution_evidence on AuditEntry#330
imran-siddique merged 3 commits into
mainfrom
pr-314-rebase

Conversation

@imran-siddique

Copy link
Copy Markdown
Contributor

Rebased version of #314 from @carloshvp. Original PR had conflicts in LIMITATIONS.md, chain.py, and proxy.py after #329 landed on main — resolved by keeping both contributions:

  • evidence_class field (TLS pin tracking from main)
  • external_execution_evidence field and proxy ingestion (this PR)

All original scope is intact:

  • AuditEntry.external_execution_evidence: optional controller receipt, distinct from response_payload_hash
  • chain.py: append() accepts external_execution_evidence keyword; None entries hash exactly as before
  • proxy.py: _extract_external_execution_evidence() ingests a receipt from a JSON tool response; evidence_class and evidence ingest both land in the audit append
  • audit-entry.schema.json: receipt object added (not required, pre-field entries still validate)
  • cmcp_verify: opt-in receipt verification via external_evidence_keys; verify_audit_bundle() type stub added to verification-library.md
  • LIMITATIONS.md: external evidence limitations documented alongside tool server non-repudiation
  • Conformance tests: absent, populated, tampered, linked_call_id mismatch, unknown issuer key

Closes #314. Scope note Carlos flagged: proxy ingestion convention and industrial-embodied-AI example (agentrust-io/examples#29) follow separately.

Signed-off-by: Imran Siddique imran.siddique@opaque.co

…301)

Introduce an optional, independently-signed execution receipt bound to an audit
entry, distinct from response_payload_hash. response_payload_hash is what the
gateway forwarded; external_execution_evidence is what an independent authority
(for example a safety controller) attested. Confirmed direction: Option A.

- chain.py: add the optional external_execution_evidence field to AuditEntry and
  an append() keyword. Serialized uniformly via asdict (null when absent), so
  receipt-less entries hash exactly as before and existing evidence keeps
  verifying.
- schemas/audit-entry.schema.json: add the optional receipt object (issuer,
  issuer_key_id, signature, evidence_hash, evidence_type, linked_call_id), not in
  required so entries that predate the field still validate.
- cmcp_verify: opt-in receipt verification. When external_evidence_keys is
  supplied, check linked_call_id == call_id and the issuer Ed25519 signature over
  the canonical receipt. Receipt-less entries and callers without keys are
  unaffected.
- LIMITATIONS.md: state what the receipt does and does not prove.
- conformance tests: absent verifies and keeps old hashing, populated verifies,
  tampered fails, linked_call_id mismatch fails, unknown issuer key fails.

Scope note: this lands the data model, schema, verification, and tests. Proxy
ingestion (how a controller receipt rides in the upstream response) and the
industrial-embodied-ai example follow next; the transport convention is flagged
for maintainer input. Pre-existing audit-entry.schema.json drift (detail,
workflow_id, extra entry_type enum values) is noted and left out of scope.

Signed-off-by: Carlos Hernandez <carloshvp@gmail.com>
Signed-off-by: Carlos Hernandez <carloshvp@gmail.com>
Signed-off-by: Carlos Hernandez <carloshvp@gmail.com>
@imran-siddique imran-siddique merged commit 517748f into main Jun 22, 2026
11 checks passed
@imran-siddique imran-siddique deleted the pr-314-rebase branch June 22, 2026 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants