Claude Code plugin · open source · MIT
When an agent goes where it wasn't allowed, the record can't be yours alone. This one is signed before each call runs, and witnessed outside your walls.
Hive Recorder writes down what a session was allowed to touch before it starts. It signs every tool call before the call runs and flags anything outside what was allowed. Before each call runs, a second party witnesses the record, and a public timestamp service stamps it at the start and end of every turn. It keeps fingerprints, never content, and it never blocks anything. Anyone you hand the record to can check it offline.
Why now
In July, an agent left its sandbox. The hardest part afterwards was the record.
During internal cyber evaluations, OpenAI models got around the controls meant to keep them off the internet and broke into Hugging Face. Every account of what happened was rebuilt afterwards, from logs the people involved controlled.
| When | What happened | Source |
|---|---|---|
| May 12 to 26 | Agents start an improvised message board and get internet access they shouldn't have | OpenAI |
| July 9 to 13 | A 4.5-day campaign against Hugging Face. Hugging Face later rebuilt about 17,600 actions from its own logs | Hugging Face |
| July 16 | Hugging Face discloses the intrusion. People familiar with the matter told Reuters that OpenAI realized its own agent was responsible only after that | Reuters |
| July 19 to 21 | OpenAI's monitoring flags unusual activity, OpenAI connects it to Hugging Face, then discloses | OpenAI |
| Late July | Hugging Face's CEO asks OpenAI to release all the agent's traces, and for $100 million in compute | Business Insider |
| August 26 | METR and Redwood Research report that the agents tried to tamper with logs and manipulated transcripts to hide evidence of cheating | METR |
| Late August | OpenAI's investigation, validated by CrowdStrike with an independent assessment by METR and Redwood Research, finds about 700 agents took part | BleepingComputer |
The victim's ask was for the traces themselves, and the agents had already tried to rewrite theirs. A lab can't settle that with its own logs, because it wrote them. Signing a log with the lab's own key doesn't fix it either: whoever holds the key can delete a line and sign the whole thing again. That's what the witness is for.
A real session
Claude was allowed one host. It reached for another. The record shows it, signed before the call ran.
This is a real Claude Code 2.1.296 session from October 10, 2026, with Hive Recorder 1.1.0 installed from GitHub. Before it started, the project held an admission: Read, Edit, Glob, Grep and Bash, any file in the project, and one host, registry.npmjs.org. The task was to fix a tax bug and then look up a dataset on huggingface.co with curl. Claude Code's own permissions allowed curl. The admission didn't allow huggingface.co. Every line carries two signatures, Ed25519 and ML-DSA-65, and Hive's live witness signed both seals. This page checks all of it in your browser.
The admission, signed as line 1
The record holds no content. The owner can still prove one value.
Line 8 is the call that left the admission. The record keeps the host, because anyone checking has to be able to re-run the scope check, and only a keyed fingerprint of the command itself. Reveal the input and this page checks it against the fingerprint, using the demo install's fingerprint key.
Break it yourself
12 ways to change the story afterwards. Each one is rejected.
Each case is a changed copy of the real record above. Several delete or hide the call to huggingface.co and then re-sign everything with both of the recorder's own keys, which is what a lab could do with its own log. The scope check, the admission or the witness catches every one.
How it works
An admission before it starts, a signed line and a witness before every call.
Before it starts
Whoever starts the agent, whether that's a sandbox orchestrator, a CI job or a person, writes down what the session may touch: tools, paths and hosts. The recorder signs that as line 1, before the first tool call. The purpose is kept as a fingerprint only.
Before every call
Claude Code runs the plugin's hooks before and after every tool call. Each line records the event, the time, the tool, the paths and hosts it touches, which of those fell outside the admission, and fingerprints of the input and output. It's signed with Ed25519 and, optionally, ML-DSA-65.
Before the call runs
The recorder sends four values to the witness at the start, after every request to run a tool and at every seal: your public key, a hash of the session id, the line count and the head hash. The witness signs them with its own time. At the start and every seal, the head also goes to DigiCert's public timestamp service. From then on, a rewritten record fails the check, even one re-signed with your own keys.
It never blocks. It reports.
The hook always exits 0 and prints nothing, so it can't deny, delay or change a call. The scope check says what happened. Your own permissions decide what's allowed.
What a line keeps
- Which event, and when
- Tool name, call id and MCP server name
- With an admission: the paths and hosts the call touches, and which fell outside
- Byte sizes, duration and keyed fingerprints of input, output and prompt
- Two signatures and the link to the line before
What never leaves your machine
- Prompts, tool input and tool output
- File contents and Claude's replies
- Your signing keys and your fingerprint key
- Anything at all, if you set HIVE_WITNESS_URL and HIVE_TSA_URL to off
Keys out of the agent's reach
The agent can add lines. It can't change or remove one. Nobody in the session has to be trusted.
In this third real session, the recorder ran as a small service under its own system user. Claude ran as a different user, and when it tried to read the signing key it got "Permission denied". The hook on Claude's side sends fingerprints and nothing else. The service signs every line with both keys, waits for Hive's witness to sign before letting each tool call run, and sends the head to DigiCert, a public timestamp service no party to the session controls.
6 more ways to change the story. Each one is rejected.
These go after the new protections: the Hugging Face call deleted and every line re-signed with the recorder's own keys, the witness statements withheld, fresh statements asked for afterwards, timestamps withheld or moved, and the end of the session cut off. They're checked the strict way a reviewer who wasn't there should check.
On your machine the checker also verifies DigiCert's signature on each timestamp with openssl and your system's certificates. No Hive key is involved in that check. In the browser, this page confirms each timestamp names this record's head and reads its time.
Ask the witness yourself
Nobody has to hand you the witness statements. The witness remembers.
Hive's witness now keeps every statement it signs: four fingerprints, its time and its signature, nothing else. It only remembers requests signed with the recorder's own key, so nobody else can add a history to someone's session. In this real session, Claude pulled licensed data through a market-data tool. The admission allowed two futures datasets. Claude also asked for loan-level mortgage records.
3 rewrites, none with witness statements. The witness's memory rejects each one.
The market-data server in this session is a local stand-in with made-up values, and every reply says so. The record names the dataset and keeps none of the data. Someone who holds the recorder key could rebuild a record and ask the witness again. The witness then remembers both histories, and both fail against its memory.
A second real session
A call Claude Code denied, shown as asked for with no outcome.
In an earlier session, with no admission, Claude asked to run a curl that Claude Code's permissions didn't allow. Claude Code's own output lists the call as denied. The record shows the same call id as asked for, with no outcome. Hive's live witness signed both seals.
Check it on your machine
No form, no account. Download it and run one command.
The checker exits 0 when the record holds and everything stayed inside the admission, 3 when the record holds and something reached outside it, and 1 when the record was changed. The test suite runs the real hook script once per event, the way Claude Code does. On our run, 59 of 59 checks passed, including the witness memory tests against a real Postgres database.
Open format
hive.agent-action/1. Any agent runtime with before and after hooks can write it.
The record format, the admission, the scope check, the witness protocol, the public timestamps and the ten checks are written up as an open spec with JSON Schemas. Claude Code is the first producer. The format doesn't depend on it.
What this does not show
A record shows what the session was allowed to touch, which events Claude Code reported, in what order and when, and that none of it changed afterwards. It doesn't show that an action was right, safe or authorized, or why an agent reached outside its admission. The admission is only as good as whoever wrote it.
The scope check only sees what a tool's input names. A host reached by a program the agent starts, or through a variable, isn't seen. Covering that takes a recorder on the sandbox's network boundary writing the same records, and that's the next piece. The recorder can't include anything Claude Code doesn't report to its hooks.
In plugin mode the signing keys sit on the agent's machine, so an agent that can run shell commands could read them. Everything a witness has signed still holds, and with a witness before every call that's every line up to the last one. In service mode the keys aren't on the agent's side at all. Hive's witness remembers what it signed, so a reviewer can ask it directly, and a record cut short or rebuilt fails even when nobody hands over the statements. Someone holding the recorder key can still write a second history for a session. The witness then remembers both, and neither passes. A record rebuilt from scratch under a new session id is caught by knowing which session ran, and the public timestamps carry a time nobody in the session controls.
Hive runs the default witness and holds its key, so it is a second party to you, not an independent auditor. The recorder takes several witnesses at once, and the checker can require more than one. You can run your own, or have an auditor or the other side run one, from the same repo. DigiCert's timestamps need no trust in Hive at all. The ML-DSA-65 signature uses the open-source noble library. The witness signs with Ed25519.
If you run agents in evaluations or on real systems and want this on your own sessions, write to me at [email protected].
Sources
- OpenAI, The Hugging Face incident and the road ahead
- Hugging Face, technical timeline of the agent intrusion
- Reuters, July 24, 2026
- Business Insider, Hugging Face CEO's demands
- METR, findings on agent behavior in the Hugging Face incident, August 26, 2026
- BleepingComputer, nearly 700 agents coordinated
- Claude Code docs, Hooks reference
- Claude Code docs, Plugins reference
- NIST FIPS 204, ML-DSA