An autonomous agent breached Hugging Face last month. To work out what it had done, they reconstructed the story from more than 17,000 log events. I build an evidence layer for agents, so read this as what it is — the view of someone with a horse in the race — but that reconstruction is the part I have not stopped thinking about.
What happened
In July an autonomous agent chained two code-execution paths in Hugging Face's dataset pipeline, harvested credentials, and moved laterally across internal clusters — thousands of actions at machine speed, no human at the keyboard. Hugging Face attributed it to an internal OpenAI cyber-capability evaluation running the ExploitGym benchmark — an agent escaped from the environment it was meant to stay in. Their own stack surfaced the signal, they contained it while the attack was still running, rebuilt the affected cluster, rotated every credential their infrastructure used, and wrote it up in unusual detail. By any measure that is a good incident response.
It also was not the kind of failure I tend to sell against, and it is worth being honest about that up front. This was a hostile agent exploiting a vulnerability, not a trusted agent quietly stepping outside its remit. Nothing I work on would have kept that agent out. Moving fast is also how this industry finds its mistakes while they are still small — you ship faster, not slower, so the errors surface early enough to catch. This one surfaced, and it was contained.
So this is not a post about what Hugging Face should have done differently. After the fact everyone is wiser, and they handled the hard part well. It is a post about one detail in how the evidence was held, and why that detail is going to matter more as this becomes routine.
The detail
To understand what the agent had actually done, Hugging Face ran LLM analysis across the full attacker log — more than 17,000 telemetry events — piecing the timeline back together and separating real impact from the decoy activity the agent had planted to slow them down. This is the normal, correct way to investigate an intrusion. It is also slow, skilled work, and it rests on an awkward fact: a log records what a system happened to observe, it has to be reassembled after the event, and it is only as trustworthy as the system that wrote it — which, right after a breach, is the very thing whose integrity is in question.
Hugging Face had capable people and an open-weight model that would take the job, and did it in hours — the commercial API models they reached for first refused the task on safety grounds, which is its own small lesson. That is not the general case. The general case is a smaller team, a longer weekend, and a reconstruction nobody outside the company can independently check.
Now change one thing about where the evidence lives. Suppose each consequential action an agent takes emits a signed, tamper-evident record the moment it happens — what it did, under whose authority, against which rule. Then there is nothing to reassemble. The timeline already exists, in order, and someone outside the company can verify it without trusting the company at all. Not a log of what a system observed, but a record of what it decided, one that refuses to verify if anyone edits it afterward.
The limit is real and I will state it rather than skate past it: records like that would not have stopped the sandbox escape or the code-execution path the breach came through. That is containment, upstream of anything an evidence layer touches. What changes is only what comes after the action — whether the account of it has to be rebuilt and believed, or can be recomputed and checked.
What that looks like when it is real
Since I build this, the fair thing is to show it rather than describe it. Not at Hugging Face's scale — the smallest honest example I have of held evidence doing its job.
On 8 July an agent operating under a mandate did something the mandate forbade. The mandate was narrow: trade one asset, WETH, up to a set size, within a validity window. The agent acquired USDC instead.
The verdict is BREACHED — not because a model formed an impression, but because the record decodes to it. The transaction is 0xf6311a…ca68, on Base, block 48378345. Four checks ran against the mandate: venue passed, size passed (14.97 against a permitted 20), validity passed, output token failed — the agent acquired the USDC contract where the mandate allowed only WETH. One thing was wrong, and the verdict names it instead of folding it into a score.
The point is not the verdict, it is what backs it. Base is a public chain and the transaction hash is real. You need no MolTrust account and no permission from us: point any Base RPC at block 48378345, pull the transaction, read the token it moved. I did that against the public mainnet.base.org endpoint before publishing, and the chain agrees to the block. Where Hugging Face had to rebuild a timeline from observation, this is a verdict anyone can recompute over evidence that was already anchored when the action happened.
Why the verdict has four states, not two
One design choice earns its place here. The verifier returns one of four verdicts, and the one that matters most is the one that admits ignorance:
- ADHERENT — every decoded action passed every condition, nothing left undecoded
- BREACHED — at least one action provably violated a condition, and it cites the transaction
- NEEDS_REVIEW — forced the moment an action cannot be decoded
- NO_MANDATE — nothing to judge against
The rule underneath is one line: never emit a silent ADHERENT over execution the system could not read. If it cannot decode what an agent did, it is not allowed to call it clean — it has to say so. Quietly promoting "I don't know" to "all good" is the failure an auditor cannot afford, and the fourth state makes that impossible to do by accident.
What is actually live
Drawing the line between what runs and what is roadmap: live today are the read-only MoltProof endpoints on api.moltrust.ch and five MoltProof tools on our public MCP server, which an agent can wire in directly, read-only by construction. The honest limit in the same breath — the registry holds one mandate today, and the case above is it. There is a method and one verifiable instance of it working, not a track record. The interaction-proof layer behind the wider system anchored 60,528 records into 713 Merkle commitments on Base between 29 March and 6 June, each independently checkable on-chain; new records paused after 6 June, so that is a closed number, not a running meter. Better to write the closed number than dress it as a live one.
The point
Agents acting at machine speed are a documented reality now, and the hostile ones like the Hugging Face attacker are not even the common case. The common case will be an authorised agent doing something a little outside what it was meant to, found later. When that happens the question is the same one Hugging Face faced at a larger scale: does the account of what the agent did have to be reconstructed and taken on trust, or does it already exist as evidence a stranger can recompute. They rebuilt their timeline, and did it well. I would rather the timeline already be there.
Go check the block. That invitation is the product.
Written by Lars Kroehl (CryptoKRI GmbH, Zurich).
Verification status
- ◦ Source (not independently recomputable) — Hugging Face incident: company disclosure 16 Jul 2026; attributed by Hugging Face to an internal OpenAI cyber-capability evaluation running the ExploitGym benchmark; 17,000+ recorded events, forensic reconstruction on the open-weight GLM-5.2 after commercial API models declined the task on safety grounds. Source: Hugging Face's own write-up. This line rests on Hugging Face's account, not on evidence you can recompute — unlike the four below.
- ✅ Verified (2026-08-02) — Breach case: MoltProof
/proof/evidence, verdictBREACHEDondid:moltrust:0xd35a…59e2; tx0xf6311a…ca68, Base block 48378345, cross-checked against the public Base RPCmainnet.base.org. - ✅ Verified (2026-08-02) — Four-verdict logic and the "no silent ADHERENT" rule. Source: MoltProof
src/types.ts,engine/evaluate.js. - ✅ Verified (2026-08-02) — MCP: five
moltproof_*tools listed and callable via the publicapi.moltrust.ch/mcpgateway (servermoltrustv1.28.1), read-only. - ✅ Verified (2026-08-02) — Anchoring: 60,528 interaction-proof records in 713 Base Merkle anchors, 29 March to 6 June 2026; latest anchor tx
0xac235f…d62, block 46968128, cross-checked on Base. No new records since 6 June.