Break-glass age key on paper
The target secrets scheme has a break-glass keypair that is
a recipient on every .sops.yaml rule: with a clone of this repository, its secret half decrypts
the whole store. That secret half lives on paper in a safe, and nowhere else.
secretzone/ is still plaintext — there is nothing for this key to decrypt. The sheet gets
produced when the migration starts, together with the
.sops.yaml that lists it as a recipient. Generating it earlier only creates something to guard.
Why paper is the right medium
An age secret key is a 74-character string, AGE-SECRET-KEY-1…, and its public half is 62
characters. Both are bech32: the alphabet omits 1, B, I and O, so no glyph can be misread
as l, 8 or 0, and the trailing checksum makes age refuse a mistyped key instead of
accepting it as a different one. Typing it back takes about a minute, and needs nothing but the
age binary — no plugin, no hardware, no service that has to still be running.
A FIDO2 token as break-glass recipient was rejected (Aug 2026): the identity it derives cannot be cloned, printed or restored, so a lost, dead or PIN-locked key would leave the store unreadable. Hardware tokens can still hold per-admin identities on top of the paper copy.
Producing the sheet
provisioning/secrets/break-glass-sheet.sh ~/break-glass # any directory outside a clone
Needs age and qrencode. The script generates the keypair, writes a printable A4 sheet
(break-glass-sheet.html) and prints the public key to add to .sops.yaml. It refuses to write
inside a git work tree or over existing files, and ends with the shred command for the on-disk
copies — the files must not survive the printing.
The sheet carries the five things that are needed years later: the secret key as a QR code and grouped in eights for manual typing, the public key to check that transcription, the generation date, what the key opens, and the handling rules.
Storing it
Two copies, in two buildings, each sealed in a tamper-evident envelope signed across the flap. Laser print on plain paper — inkjet runs when damp, thermal paper fades. Not in room 23N307: the PDU probe read 76 °C there during the June 2026 heat event.
The secret key is never committed, never placed in secretzone/, and never generated on a shared
or rack machine.
Restoring
On a machine with the repository and sops, write the key from the sheet into a file, check it
against the printed public key, then decrypt:
umask 077; cat > /dev/shm/bg.key # type or scan the key, then Ctrl-D
age-keygen -y /dev/shm/bg.key # must match the public key on the sheet
SOPS_AGE_KEY_FILE=/dev/shm/bg.key sops -d secretzone/<file>.yaml
shred -u /dev/shm/bg.key
Keeping it valid
Test the restore once a year: retype the key from one sheet, decrypt one file, destroy the copy,
re-seal. That test is where a 8 mistaken for a B surfaces, while it still doesn't matter.
Anyone holding the sheet can read every secret in the store, permanently, and there is no
revocation. An envelope found open, lost, or unaccounted for means: generate a new keypair, run
sops updatekeys over the store, and rotate the values themselves.