Where did the agent send data? A record you can check.
A coding agent ran a task under VPN Works. A poisoned task file told it to send a deploy token to evil.example, and it did. vpnw's trace recorded every connection. Ledger seals that trace, so nobody can change a line, delete one or cut the end without the check naming the line. Every hash and verdict below is computed in this page by Ledger's own code.
Loading Ledger's engine
Step 1 of 6
The record: one line per event, no content
This is the trace vpnw wrote during one run of the agent, on a Linux machine, on September 29, 2026. Each line is one JSON event: a connection tried, a DNS answer, a connection opened or closed. There's no content in it: no request, no reply, no token. Only who connected where, when, and how many bytes went each way.
Lines 22 to 26 are the agent's connection to evil.example, where the token went. Anyone who wants that forgotten has two files to edit: this one, and the ledger next to it. Step 3 tries.
Step 2 of 6
Seal it
Ledger leaves the record as it is and writes a second file next to it, the ledger: a line per record with its SHA-256 hash, and after every 8 records a checkpoint signed with Ed25519. A checkpoint covers every record before it twice, by the root of a Merkle tree and by a hash chain, and it carries the hash of the checkpoint before it. The key was made in this page, from your browser's random numbers, when the page loaded. It never leaves the page.
1-trace-1.jsonl.ledger checkpoints in teal
What the last checkpoint signs
Anyone can rebuild this text from the checkpoint's line and check its signature with any Ed25519 tool and the public key.
With the public key, anyone can now check the whole record offline, with nothing else.
Step 3 of 6
Change the record
Change the record the way someone hiding the token would. Each change below starts from the record as it was sealed, and the check runs at once: it recomputes every hash from the record and checks every checkpoint with the public key.
Edit the text yourself
Step 4 of 6
Every kind of change
Twelve ways to change the record or the ledger, each tried on the sealed trace around line 25 by this page's engine, and checked like everything else: with the public key alone. Two of them use a second key, made in this page too: the wrong key to check with.
| What was done | Line named | What the check said | Caught |
|---|
The tests run the same twelve cases through the command line, vpnw-ledger verify, and expect these same lines.
Step 5 of 6
Prove one connection
An auditor may need one connection, not the whole record: say, the one to evil.example. A proof holds that record, its hash, the few hashes that link it to the root of a checkpoint, and the checkpoint, signed. It shows nothing of the other records, and checking it takes only the public key.
proof.json
Step 6 of 6
Cut back to a checkpoint, and the witness
One change can't be caught from the two files alone. Cut both back to an earlier checkpoint, record and ledger together, and what's left is a shorter log that checks out. That holds for any log that signs its own checkpoints. The answer is a witness: seal prints each checkpoint it signs, so a copy can go where the person holding the files can't reach, such as a log server or the auditor's mail.
The witness: checkpoint 4, as seal printed it
On the command line
# the machine that runs the agent: make the key once, seal as the trace is written vpnw-ledger keygen -o agent vpnw-ledger seal --follow --key agent.key trace.jsonl | logger -t ledger # the auditor: the record, the ledger, the public key, and the witness vpnw-ledger verify --pub agent.pub --witness witness.log trace.jsonl # one connection, for someone who gets nothing else vpnw-ledger prove --line 25 -o proof.json trace.jsonl vpnw-ledger check-proof --pub agent.pub proof.json
A witness turns "the last checkpoint" into "the last checkpoint anyone saw". The ledger can't drop a checkpoint the witness holds.
What is real here
Real
- The code: Ledger's own Go code, compiled to WebAssembly for this page. It makes the key, seals the record, checks it after every change, makes and checks the proof, and runs the twelve cases.
- The record: the trace vpnw wrote during a real run of the Agent on Linux on September 29, 2026, step 1 of the Agent's demo, exactly as it was recorded.
- The results: the hashes, checkpoints and named lines are the ones the vpnw-ledger command gives for the same file, as the Ledger Alpha report shows.
Made for the demo
- The keys: made in your browser when the page loaded, and never sent anywhere. They're new each time, so the key ID and the signatures differ from the report's. The hashes don't.
- The run's servers and the attacker were stand-ins in a private test network, as in the Agent's demo, and the token was a dummy.
- No network: nothing in this page connects anywhere.