Ledger
Ledger keeps a record of a run that can’t be changed without it showing. It’s a built-in plugin in VPN Works since 0.5.0: an Observer that seals every event as it happens, and an Advisor that checks the record and names the line anyone changed.
After an incident or in an audit, “where did this program send data?” needs an answer people believe. An ordinary log can be edited by anyone who can reach it, and a careful edit leaves no mark. Ledger makes every edit leave one.
vpnw guard --plugin ledger --policy agent.toml -- ./my-agent
vpnw verify ~/.local/state/vpnw/ledger/r-3f9a1c.ledger

How It Seals a Run
Ledger writes each event to its own file the moment it arrives, exactly as vpnw recorded it, with a SHA-256 hash that covers the line before it. Every 100 events, and at the end, it writes a checkpoint, and when the run finishes it writes an end line. Each of those is a link in the same chain, so nothing in the file can be changed, removed, added or moved without the chain breaking right there.
Two copies go somewhere else. Each checkpoint is also written into the run’s trace, and at the end Ledger prints the ledger’s path and its last hash. Kept out of reach, either one catches the one thing a chain can’t: a whole ledger written again from scratch.
Writes go straight to the file. A run that’s killed halfway leaves a ledger that ends where the run did, and everything in it still checks out.
How It Checks
vpnw verify reads the ledger line by line, as it is on disk. Its answer is one of three:
- intact: every line matches its hash, the run ended normally, and the checkpoint copies and the kept hash, when given, match too.
- CHANGED: with the file and the line. An edited event, a line removed, copied or added, two lines swapped, a checkpoint removed or added, the header or the end line edited, bytes added after the end. When the chain was written again from some line on, the copies in the trace catch it, and the trace’s own events name the line.
- cut short: the ledger stops without an end line, or halfway through a line. The run was killed there, or someone removed the end; what is there checks out.
Built as Plugins
Ledger is two plugins, and neither has any way in that other plugins don’t. The Observer writes its file through the file.write permission, new in 0.5.0 and open to every plugin: vpnw creates one new file for the plugin, and the plugin can only add to it. It can’t read it, move around in it, or reach any other file. The checker reads the ledger through another addition every Advisor can use: it’s handed the lines of its files exactly as they are, since a checker that sees a tidied-up copy can’t tell what changed.
What It Can’t Show
Anyone who can write the file and knows the format can write a new ledger from scratch. That includes the program being watched, while it runs: vpnw limits the network, not files, and the program runs as your user. The copies are the answer. Keep the last hash, or the trace, somewhere the program and whoever holds the ledger can’t change.
The 0.2.0 Ledger, a separate engine, also signed its checkpoints with Ed25519 and could prove one connection was in a record without showing the rest. Signing needs a key that a plugin can use without being able to read it, and that isn’t in the plugin interface yet. Roadmap
Earlier
In VPN Works 0.2.0, Ledger caught 12 of 12 edits to an AI agent’s sealed record at the exact line. The case study