Go reference implementation of the MCP SEP-3004 Tamper-Evident Audit Record Contract.
This package implements the canonicalization and verification specified in SEP-3004:
- §2.3 Canonical form: sorted-key JSON, no HTML escaping, extensions in type-keyed object form
- §2.4 SHA-256 hash chain:
event_hash = H(canonical_form(protected_body)) - §2.6 Verification: recompute hashes, check
previous_hashthreading
The two-extension known-answer digest from the SEP Conformance section reproduces byte-for-byte across this Go implementation and the TypeScript GIF reference implementation:
Known-answer digest: f733fed9cc757165f810b778e4baba1f51a45504988e937707aaab4361b2f064
Go implementation: f733fed9cc757165f810b778e4baba1f51a45504988e937707aaab4361b2f064 ✅
Reproduce from any shell:
printf '%s' '<preimage>' | sha256sum| Vector | Requirement | Status |
|---|---|---|
| AC-1 | Core fields present, event_hash excluded, extensions keyed by type id | ✅ |
| AC-2 | clearance_decision: admitted → outcome: allowed |
✅ |
| AC-3 | clearance_decision: denied → outcome: denied |
✅ |
| AC-4 | clearance_decision: deferred → outcome: deferred |
✅ |
| AC-5 | Invalid clearance_decision rejected; allowed ≠ denied |
✅ |
| AC-6 | Two-extension known-answer digest matches byte-for-byte | ✅ |
| AC-7 | Same record → same canonical bytes (deterministic) | ✅ |
import "github.com/deeparchi-ai/mcp-audit-go"
rec := audit.AuditRecord{
EventID: "evt-001",
OccurredAt: "2026-07-03T00:00:00.000Z",
PrincipalID: "agent-42",
EventType: "tool_call",
ToolName: audit.StringPtr("filesystem.read"),
Outcome: audit.OutcomeAllowed,
Extensions: map[string]any{
"admission-control": audit.AdmissionControlExt{
ServerID: "gmail-mcp-server",
ClearanceDecision: audit.ClearanceAdmitted,
ClearanceLevel: audit.StringPtr("restricted"),
RequestedTool: audit.StringPtr("filesystem.read"),
},
},
}
hash, _ := rec.ComputeHash()
// hash stores the SHA-256 digest of the canonical form