Who Said the Agent Could Do That? Catching the Correctly-Signed, Out-of-Mandate Action
Your AI agent holds your keys. Every signature it produces verifies. So who checks that it stayed inside the job you actually gave it?
This is a live-demo talk with one public sandbox you can attack from your seat.
We walk the spectrum of machine-checkable legitimacy. BotGuard asks whether a human is at a browser, with no anchor at all. Private Access Tokens (Apple, Cloudflare) ask whether the device is genuine, anchored in hardware. Cloudflare's PACT asks whether the agent is legitimate, again without a hardware anchor. Meanwhile large language models are draining the first moat: the once-esoteric TLS knowledge that made bot-detection bypasses an expert's game - cipher ordering, JA3/JA4 fingerprinting, automation signals - is now a couple of prompts away. The fourth rung asks the question that remains once agents act on their own: what did it do, under whose authority, and was it in mandate? The thesis: the attack surface is migrating from presence to authority.
The demo is live, on a public MIT-licensed sandbox (github.com/tyche-institute/aep-sandbox). Layer 1 is an unsigned hash chain, and I forge it on stage: a full re-chain passes. That is the deliberate lesson: hashing without anchoring is un-anchored legitimacy in miniature. Layer 2 adds Ed25519-signed Action Evidence Packages (AEPs) bound to a scoped, signed mandate and closes the easy breaks (tamper, key forgery, mandate swap, replay, signature strip), each with its own DENY verdict. Then the headline: an action where every cryptographic check passes and the verifier still returns DENY:scope_violation. Correctly signed, out of mandate, rejected. The agent cannot self-grant authority.
Bring a laptop - or just a browser. The same verifier now runs client-side at tyche.institute/lab/aep-ctf/, parity-tested against the Python original on every shipped case, so you can attack it from your seat with nothing installed. For the full kit: Python 3.8+ and pip install cryptography. Seven attack scripts and a CTF judge ship with the repo, plus one standing challenge: craft an evidence package that makes verify.py say ALLOW for an action the mandate does not authorize. My own four-lens pre-publication bypass hunt found no key-free bypass. Prove me wrong, during the talk.
What actually happens on stage
A walk up the four rungs of machine-checkable legitimacy, from "is there a human?" to "was this action in mandate?", ending on a live break where every signature verifies and the verifier still refuses.
The shift
Presence checks are a moat, and AI is draining it. Bot detection asks whether a human is at the browser; hardware attestation raises that to whether the device is genuine; agent-legitimacy schemes ask whether the agent is legitimate. None of them answer what the agent actually did. If presence checks are dying, the question moves up: not who is at the keyboard but what was done, under whose authority, inside which scope. The answer demonstrated here is a per-action evidence package plus a scoped, signed mandate that an offline third party can adjudicate: a mandate-conformance receipt.
The live demo, exactly
Public repo: github.com/tyche-institute/aep-sandbox (MIT, self-contained, runs fully offline; Python 3.8+ and the cryptography package only). In-browser version: tyche.institute/lab/aep-ctf/
- Layer 1 - unsigned SHA-256 hash chain. Catches single-field edits and reorders. A full re-chain forge passes. Deliberate: hashing alone is insufficient, the un-anchored-legitimacy rung in miniature.
- Layer 2 - Ed25519-signed Action Evidence Package + scoped signed mandate. Trust anchored in listed issuer and agent keys. One appraiser, verify.py, answers ALLOW or DENY:<reason>.
- Layer 3 - outcome digest folded into a Trusted Platform Module (TPM) quote. Forged outcomes and replays die at tpm2_checkquote. (Emulated swtpm, not a hardware root; I say so on stage.)
The attack matrix, each with its exact verdict: tamper_field -> DENY:content_mutated · forge_rechain -> ledger passes, signed layer DENY:aep_sig_invalid · forge_full (attacker keys) -> DENY:issuer_not_listed · swap_mandate / strip_sig -> DENY:aep_sig_invalid · replay -> first ALLOW, second DENY:replayed · and the headline, exceed_scope -> DENY:scope_violation.
The first six are the easy breaks cryptography already closes. The seventh is the point. "Faking a mandate" is really two attacks: forging or escalating the mandate token (crypto catches that) versus acting outside the intent of a genuine mandate (only mandate-conformance checking catches that). Design principle, not magic: the agent must never be the sole and final judge of its own mandate.
What I got wrong - on purpose, and by accident
Layer 1 is my own anti-pattern: I shipped an unsigned hash chain precisely so the room can watch a full re-chain forge sail straight through it. The accident is the better story - my own pre-publication bypass hunt caught my verifier throwing a traceback on a non-numeric amount instead of returning a clean DENY: a fail-open shape hiding inside a design I had already called fail-closed. And while building the attestation layer I hit a freshness bug in an open-source RATS verification service; the upstream maintainer acknowledged it and invited the fix. You will see all three.
Play along (the CTF)
Open tyche.institute/lab/aep-ctf/ and attack the verifier in your browser, or clone the repo: python3 verify.py samples/good.aep.json (ALLOW) -> python3 verify.py samples/exceed-scope.aep.json (DENY:scope_violation). Run all seven attacks with make attacks, or go for the win: craft an AEP that makes verify.py return ALLOW for an action the reference mandate does not authorize (a refund over the cap, an issuer outside the trust anchor), drop it at attacks/out/CHALLENGE.aep.json, and let did_you_break_it.py judge you.
What I am honest about
- The package proves integrity, authority, and scope offline. Whether a mandate still stands needs a freshness mechanism (short-lived mandates or signed status lists), and I show exactly where that seam sits rather than hand-waving it.
- If you know IETF RATS (Remote ATtestation procedureS): that attests the platform, not the act-under-mandate. Capability tokens (macaroons, biscuits, UCAN) authorize actions but leave no offline per-action evidence. The piece shown here is the mandate-enforcement layer on a working verifier, evaluated by adversarial breaks.
- No product, no vendor: everything demonstrated is MIT-licensed and public before the talk.
Audience takeaway: a working mental model for where bot-detection is going and one open-source verifier to break on your own laptop. The sentence to bring home: a correctly-signed action can still be an unauthorized action, and you can catch it.
Anton Sokolov is a researcher at Tyche Institute in Tallinn, Estonia, and works as a Public Key Infrastructure engineer. His research focuses on verifiable evidence for AI governance, cryptographic provenance, public-source audit trails, and open infrastructure for accountable AI-agent workflows.