DEV Community

Teo Crispin
Teo Crispin

Posted on

An independent verifier audited my compliance API's hash chain byte-by-byte — in public, same day, both sides shipped fixes

I'm a solo developer in Bogotá, Colombia. This week something happened on a GitHub issue that I think is worth documenting, because it shows what "trustless verification" actually looks like in practice — not the whitepaper version, the real one with bugs found and fixed in public.
The setup

I build VeraData — a LATAM compliance data API for autonomous agents. Sanctions screening (OFAC + UN + EU + UK, 59,000+ entries), KYB against official registries (RUES Colombia, CNPJ Brazil, RFC Mexico), central bank rates. Everything pay-per-call via x402: an agent hits the endpoint, gets a 402, signs a USDC micropayment on Base or Solana, gets the data. No API key, no account.
Every screening response includes an AAT block — a SHA-256 hash chain (query_hash → event_hash → chain_hash) designed as EU AI Act Art.12 audit evidence.
I opened an issue on x402-foundation/x402 positioning it as a compliance use case. What happened next was better than a listing.
The audit

An independent verifier (babyblueviper1, who builds the ERC-8299/WYRIWE reference implementation) didn't just read my docs. They ran a live call against /sanctions, took the AAT block apart, and recomputed every hash independently.
What they found, in public:

A silent ambiguity in my spec. My recomputation instructions said SHA256(query_hash + "|" + ...) — but didn't state that hash values carry their own sha256: prefix as input to the next hash. They tried the bare hex first, got a mismatch, and only matched with the prefix. Any third recomputer would have silently failed the same way. It's now documented as a load-bearing detail in a public conformance fixture.

The honest gap. chain_stored: true proves the entry exists in my database — it does not prove when it was written. That's exactly the question an auditor asks first: "could this record have been generated after the fact?" A hash chain regenerates wholesale by whoever holds the data. The fix (independent signatures + Bitcoin OTS temporal anchoring) is real but not built yet — so we named it publicly instead of papering over it.

A missing matches: [] field. On CLEAN results I omitted the matches array. Their deterministic check flagged it: "checked and found nothing" is structurally different from "field not populated". Fixed same day, commit linked in the thread.

What I found on my side, because the audit forced honesty:
My marketing said sanctions screening covered SARLAFT (Colombia), CNBV (Mexico), COAF (Brazil) regional lists. When the live call returned lists_checked: ["OFAC_SDN", "UN_CONSOLIDATED"], I had to face it: those regional lists are not publicly downloadable — they're restricted to regulated financial entities. My copy overstated what was running.

So I said so, in the thread, before they found it. Then I replaced the phantom lists with real ones: EU Consolidated (29,759 entries) and UK HM Treasury (9,605 entries), seeded and live the same day. The stack is now honest: OFAC + UN + EU + UK.

The result
Two real /review calls against my live paid endpoint, two published decision_ref proofs:
verdict: approve
confidence: 0.95
decision_ref: sha256:3eeb2c6c6e0f5c90c8c9823e593791cfb56a2774611a1bca9c3a5eda1ced39b6
source_class: agent_reported
sanctions_screening is now a first-class artifact_type in their ERC-8299 implementation — shipped because this exchange motivated it. My fixture is a test case in their conformance repo. Anyone can run python3 check_chain.py and verify the whole chain from declared inputs, zero dependencies.
Their framing of the bar, which I'll steal forever:

"Not that nothing was wrong, but that everything wrong got found, said out loud, and fixed in public, same day, by both sides."

Why this matters beyond my API
The x402 ecosystem is at ~$1.1M volume / 3.7M transactions per month. The winning categories are machine-readable data and gateways. But there's a trust problem: how does an agent know a compliance verdict wasn't fabricated? "Trust me" doesn't survive a skeptical auditor.

The answer that's emerging: recomputable evidence + independent attestation. Your endpoint produces a deterministic chain. An independent party signs over it. A third party who trusts neither of you can verify both. That's what we closed the loop on this week — as far as I know, the first documented instance for a compliance API on x402.

Try it
Agents can screen an entity right now, free (5 trial calls/day per endpoint):

curl -X POST https://api.veradata.dev/sanctions/quick \
-H "Content-Type: application/json" \
-H "X-TRIAL: true" \
-d '{"name": "ACME Corp", "country": "CO", "type": "company"}'

Or install the skill in Claude Code / Codex / Cursor:

npx skills add teodorofodocrispin-cmyk/veradata-skills --skill veradata-latam-compliance

Full thread with all the hashes, fixes, and proofs: x402-foundation/x402#2749

Top comments (0)