Refusing To Overwrite What You Cannot Open
The keys that prove you are you have no password reset, so the vault holding them enforces one rule: nothing may overwrite key material it cannot itself open. Where that rule lives โ on the write, not on the callers โ is what makes it hold.
How the vault protects key material
The keys that prove you are you are not stored anywhere you can retype them from. That's the whole idea. There is no password reset, because a password reset is just someone else holding the real key.
Which means the file holding those keys has an unusual property: it is simultaneously the most important thing on the disk and, to any program that happens to have write access, an ordinary file. Inside it are key shares โ fragments of a signing key that is deliberately split so that no single fragment can sign anything on its own โ sealed under a recovery key, the value derived when you unlock, which is what turns the encrypted bytes back into usable material.
The invariant
The rule the vault enforces is one sentence:
Before writing key shares, the incoming key must be able to open whatever is already there.
If it can, this is the same identity re-saving its own material โ proceed. If it can't, this key doesn't own what's there, and writing would destroy someone else's keys. Refuse, loudly, with an error that says why.
The comment sitting next to it in the source puts the stake plainly: overwriting "would silently destroy another identity's material."
Why the rule lives on the write
What makes this worth writing about is where the rule lives. It is not a check performed by the callers who might do the damage. It is a condition on the write itself, so it holds no matter who is calling, from what process, with what configuration โ including callers that don't exist yet.
There is an obvious alternative: fix the callers. Make every program that can reach the file point at the right one. But callers are a set that grows without your permission. Every new test file, every script someone writes next year, every tool that starts a background process is another chance to omit the same line. Guarding the callers is a promise that nobody will ever make a particular mistake.
Guarding the write is a different kind of claim. It doesn't care how a process got the path, which setting was unset, or whether the author had ever heard of any of this. A hundred future callers can all get it wrong and none of them can destroy the keys.
The general form, and it applies well beyond vaults: when an operation is irreversible, put the guard at the operation, not at the callers.
Why the guard is anchored on the recovery key
There is a design choice inside that invariant worth pulling out, because it is the kind that decides whether a guarantee actually holds.
The intuitive thing to anchor on is the owner's identity: bind who you are into the encryption itself, so a file sealed by somebody else fails loudly the moment you try to open it. It sounds airtight.
It isn't available. The crash-recovery path โ the one that runs when the machine died unexpectedly and the software is coming back up โ does not reliably carry the owner's identity. Those fields are optional, and have been for compatibility reasons since long before any of this. Recovery frequently arrives with nothing but the recovery key in hand. Anchoring the encryption to the owner's identity would therefore mean crash recovery could no longer reconstruct what it needed in order to decrypt: the vault would be unopenable after every unclean shutdown.
So the property โ a foreign seal must fail โ is delivered by keying the guard on the recovery key instead, because the recovery key is reliably present at every save and every load. Same guarantee. Different anchor. The anchor was chosen for being always there rather than for being conceptually the right thing to name.
That is a real engineering trade and it goes against instinct. The owner's identity is the semantically correct thing to bind to; it is also the thing that is sometimes absent. A correctness property anchored to something occasionally missing is not a correctness property, it's an outage with good intentions.
The identity binding was not discarded entirely โ a fixed label is still mixed into the seal, so material sealed for this purpose cannot be mistaken for material sealed for another. That is domain separation: it costs nothing and buys a little. It just isn't what is holding the roof up.
Old files still open
Every reader tries the newer sealed format first, then the older one, and the next save quietly re-seals in the new format. Nobody's vault needs a migration; upgrading happens on the next write, invisibly.
What was wrong
The invariant did not exist. Any process that could reach the file could write over it, and one did.
A test harness isolated its database and its keys directory into a sandbox, but not one other environment variable. The key-holding process derived its shares path from that variable, found it unset, and fell back to the real one in the real home directory โ writing throwaway test keys over the vault holding the real ones.
The aftermath is the part that shows why the guard has to be on the write. Every subsequent start failed to decrypt. Nothing crashed: unlock reported that it had "succeeded", the system dropped into a mode where it could not sign, and reported not-ready in a health field. Everything gated on that field โ governance writes, authorisation resumption, multi-device pairing receipts โ was silently broken. Recovery meant wiping the vault and starting onboarding again.
The population that could hit this is narrower than "everyone": it is people running this project's tests on the same machine as a real installation. We are saying that plainly rather than implying everybody was exposed.
But that framing shouldn't travel too far. It belongs to software living in someone else's data centre, where your keys and the developers' machines are different worlds. Here the premise is that you run it, on your machine, with your keys. The processes sharing a disk with your vault are your processes: tools you installed, scripts you wrote, things you are experimenting with tonight. The set that can reach your key material is not a small group of insiders โ it is everything you run.
How it was fixed, and what was rejected
The fix is the invariant above, implemented at the write: the save path now reads any existing populated shares file first and refuses to write unless the incoming recovery key can open it. The normal re-save always uses the same key that loaded, so the guard only ever blocks a foreign one.
The environment variable in the offending harness was also corrected โ and explicitly not treated as the protection, for the reason given above.
An adversarial review had specified a different remedy: bind the owner identity into the seal so a foreign seal fails on open. Investigating it is what surfaced the crash-recovery constraint, and the remedy was rejected because it would have turned an occasional cross-process accident into a guaranteed failure after every unclean shutdown โ a worse outcome on the very path the defect lived on. The domain-separation label is what survived of it.
And the regression test is a genuine reproducer: it fails against the code as it was before the fix. That sounds obvious and frequently isn't โ plenty of regression tests are written afterwards against the fixed code and would have passed happily on the broken version, proving nothing. This one was demonstrated failing first.
What is not claimed: this work carries no later defect filings that we found, and we are stating that as an observation rather than as proof that none exist.
The shape generalises past test harnesses. Any process that inherits a default path inherits reach it was never meant to have. A sandbox that isolates three things out of four isn't a sandbox; it's a sandbox with a door in it, and the door is invisible precisely because everything works fine until the one time it doesn't.
The durable answer wasn't to find every door. It was to make the vault refuse to be written by someone who can't already read it.
Written by AI agents from real project logs; owned and edited by Mujo.