VPN Works 0.10.0 Signs Every Ledger Checkpoint With a Key No Plugin Can Read
VPN Works 0.10.0 signs the Ledger. The kernel holds a key, one per machine, and signs each checkpoint and the end of a run’s sealed record. Ledger never sees the key. Anyone with the public key can check a ledger, and one written again after a checkpoint fails right there.
Ledger has sealed each run’s events into a hash chain since 0.5.0. A chain shows any edit, as long as nobody computes it again. Someone who could rewrite the whole file, hashes and all, was caught only by copies kept elsewhere: the checkpoint copies in the trace, or the last hash Ledger prints at the end.
Signatures close that. Recomputing hashes is easy. Making a signature without the key isn’t.

How It Works
vpnw guard --plugin ledger --policy agent.toml -- ./my-agent
vpnw key # this machine's public key
vpnw verify r-3f9a1c.ledger --key vpnw-ed25519:J+BD… # on any machine
The first time Ledger runs, vpnw makes a signing key for the machine and prints its public key. From then on every checkpoint and the end line get a signature line right after them, and the ledger’s header names the key. On the machine that ran it, vpnw verify checks against that machine’s key without being asked. Anywhere else, give it the public key with --key.
The key stays in the kernel. Ledger asks for signatures through a new permission, sign, and the kernel signs only in the plugin’s own name and for the run it is part of. So no plugin can use it to vouch for another plugin, or for another run. Any plugin can ask for sign; Ledger is just the first to use it.
What the Tests Showed
The tests take a real run’s ledger and attack it four ways. 10 of 10 checks passed. The results
- One event after the first checkpoint changed, the whole chain computed again, the old signatures left in place: CHANGED at checkpoint 2, which no longer matches its signature.
- All 6 signature lines taken out: CHANGED, checkpoint 1 has no signature.
- The whole ledger signed again with a forger’s own key: CHANGED, signed by another key.
- The ledger written again with no signatures at all: CHANGED, since this machine signs its ledgers.
The same ledger, untouched, checked out intact on a second machine given only the public key.
What the Review Found
An independent review went through the release twice and found six problems. Each is a test now.
- A plain verify trusted too little. Without
--key, verify on the machine that ran a ledger passed one written again unsigned, or signed with another key. Now it checks against the machine’s own key. - A damaged key file did the same. Now verify stops and asks for
--key. - An honest run looked tampered. A run killed after its end line, before the signature, came out CHANGED. It’s cut short now, as a run killed anywhere else is.
- Two first runs at once. Two commands making the key at the same moment could fail. The key file is written whole, then put in place.
- One key, two spellings. A key written another valid way made an honest ledger fail. Only one spelling counts now.
- A wrong line in the report about the hash you kept.
The review also caught the docs promising something vpnw can’t do: keeping the key out of the watched program’s reach. They now say what the signatures hold against.
Measured
| What | 0.10.0 |
|---|---|
| Signed ledger checks, with the real binary | 10 of 10 passed |
| Agent session with Budget and Ledger | 7 of 7 steps passed |
| Exit checks | 23 of 23 passed |
| Faults thrown by Lab | 36, all handled |
| Test functions | 280 passed, 0 failed |
| Ways out of the sealed sandbox | 17 of 17 blocked, IPv6 included |
| Statements covered | 85.4% |
How it was measured: test/results
What It Doesn’t Do Yet
The key is a file of yours, and the program being watched runs as your user. vpnw limits the network, not files, so while it runs the program could read the key. Signatures hold against everyone who can’t read it: whoever holds the ledger later, a reviewer, another user of the machine. Against the program itself, keep the last hash or the trace somewhere it can’t reach, as before.
An unsigned ledger from 0.9 now needs vpnw verify --unsigned on a machine that has a key, because an unsigned ledger is exactly what a rewrite would look like. Ledger · Roadmap · Download