Skip to content

Recovery & Escrow

An encrypted garden has exactly one failure that nothing can undo: losing every way to open it. This guide is how to keep that from happening. All commands here are CLI-only. None are exposed to Claude.

The garden’s data key is stored wrapped, not in the clear. Each wrapping is a door:

  • Passphrase (always present): the master passphrase you chose at onboarding.
  • Recovery phrase (optional): a 12-word phrase, shown once, that opens a second door if you forget the passphrase.

The passphrase alone recovers nothing; it unlocks a small file (k.self) that must survive. “Passphrase-only” means one secret to remember and a small file to never lose. That’s why escrow comes first.

Terminal window
softfig vault status --garden <state-root>

It prints the declared recovery policy, the doors actually on disk, and any divergence between them (for example, you declared a phrase but it’s gone). It works while the garden is locked and asks for no passphrase. Add --identity to also unlock and print this device’s identity fingerprint.

To record the shape you intend, use softfig vault recovery declare <policy>, where policy is passphrase-only, passphrase+phrase, passphrase+peers, or a +-joined combination. Declaring only records intent; it adds and removes nothing.

Terminal window
softfig vault escrow export --garden <state-root> --out ~/escrow.softfig

This writes every door plus the parameters needed to use them into one file of about a kilobyte. It needs no passphrase and works on a vault you can’t currently open. The bundle is inert without your master passphrase, so copy it freely: a second disk, another machine, a password manager attachment. Use --force to replace a bundle that differs.

A copied file isn’t a backup until it’s proven to open:

Terminal window
softfig vault escrow verify ~/escrow.softfig

Stage one checks the bundle’s integrity and that it carries every declared door. Stage two asks for your passphrase and actually unwraps the key from the bundle. It never changes the live vault, and it records the result against it. Use --integrity-only to check a remote copy’s bytes without a passphrase (this proves nothing about opening), or --no-record to skip the record.

Terminal window
softfig vault recovery add phrase --garden <state-root> # mint a new 12-word phrase, shown once
softfig vault recovery drop phrase --garden <state-root> # remove it

drop is deliberately hard to do by accident. It refuses to remove the last remaining door, to proceed without a verified escrow copy of what would remain, or to remove the door you’re currently authenticated through. You don’t need the lost phrase to remove its door. You confirm by typing the door’s name, then your passphrase. Adding a door that already exists is refused; replace it with drop then add.

With a recovery phrase on hand:

Terminal window
softfig vault recover --garden <state-root>

You enter the 12 words and choose a new passphrase. This replaces k.self, so any earlier escrow proof becomes historical: export and verify again afterwards.

Terminal window
softfig vault rewrap --garden <state-root>

Re-derives k.self under heavier Argon2 parameters, calibrated to this machine (--target-ms, default 1000) or set explicitly with --m-cost, --t-cost, --p-cost. It rewrites about a hundred bytes and touches no data, so it’s quick. Add --new-passphrase to change the passphrase in the same step. It refuses to weaken parameters unless you pass --allow-downgrade. As with recover, re-export and re-verify your escrow afterwards.


Related: Seal & Reveal, Reference → Crypto, and Internals → Vault for the key hierarchy.