Seal & Reveal Secrets
A garden is encrypted at rest, but the moment it’s unlocked the whole plaintext view is readable — by you, by your editor, by a Claude session. That’s fine for notes and config commentary; it’s wrong for an API token. Layer B is the answer: it keeps chosen secrets encrypted even inside the unlocked view, so they never appear in the mounted tree and never reach the assistant. This guide is the day-to-day mechanics of sealing and revealing them.
Two granularities
Section titled “Two granularities”You can seal at two levels, and they compose:
- Whole files, matched by glob — the entire file is Layer-B ciphertext.
- Inline regions inside an otherwise-plaintext file — wrap a single secret in
<vault id="…">…</vault>and only that span is sealed, while the rest of the file stays readable.
Inline regions are the ones to reach for most: you keep a file legible and reviewable, with just the credential blacked out. Wrap the secret in the tag, giving it an id you’ll use later to reveal it:
# an .env-style file — readable, except the one secretAPI_ENDPOINT=https://api.example.comAPI_KEY=<vault id="example-key">sk-live-abc123…</vault>What the unlocked view shows
Section titled “What the unlocked view shows”Once sealed, the FUSE mount never shows the plaintext. Instead you see placeholders:
- a sealed file reads as
[sealed:<path>]; - a sealed region reads as
<vault id="x">[encrypted]</vault>.
That’s exactly what a Claude session sees too. The MCP write verbs also refuse to edit sealed content, so an assistant can neither read a secret nor overwrite one by accident. (The boundary from the assistant’s side is described in Working with Claude.)
Seal a file
Section titled “Seal a file”softfig vault seal appends a glob to the vault’s sealed-paths list; the daemon
commits the change and auto-encrypts every tracked file that matches. It talks to
the running daemon, so the garden must be unlocked.
softfig vault seal 'secrets/**'Globs support **, *, ?, […], and {a,b}. Quote them so your shell
doesn’t expand them first. The command reports the schema change, the seal
commit, and every file newly sealed:
schema_change 3f9a…vault_seal c17b…newly sealed (2): secrets/tokens.toml secrets/deploy.envIf no tracked file matches yet, it just records the glob — anything you add later that matches gets sealed automatically.
List what’s sealed
Section titled “List what’s sealed”softfig vault list-sealedPrints the active globs and the tracked files currently matching them — your audit of what Layer B is protecting.
Reveal (for you, never for the assistant)
Section titled “Reveal (for you, never for the assistant)”Turning a secret back into plaintext is a deliberate, human-only action:
softfig reveal secrets/tokens.tomlIt does not print the secret. It writes the plaintext to a mode-0600 temp
file under $XDG_RUNTIME_DIR and prints only that path — keeping the secret
out of your shell history, terminal scrollback, and any log forwarder. You then
open, less, or pipe the file yourself:
less "$(softfig reveal secrets/tokens.toml)"To reveal a single inline region instead of a whole file, name its id — repeat
--id for several, and you get one temp file per id in the order given:
softfig reveal services/example.env --id example-keyreveal asks the daemon, which prompts for your master password (once per
invocation, even with several --ids), so the garden must be unlocked and the
daemon running. Each reveal is recorded as an audit commit. Delete the temp file
when you’re done; it lives on tmpfs under $XDG_RUNTIME_DIR.
Unseal
Section titled “Unseal”Removing a glob stops future matches from being sealed, but does not bulk-decrypt blobs that are already sealed on disk:
softfig vault unseal 'secrets/**'If you want the file back as ordinary garden content, reveal it and rewrite it
through the mount after unsealing. unseal on a pattern that isn’t present is a
no-op.
When a pointer beats a seal
Section titled “When a pointer beats a seal”Sometimes the cleanest move isn’t to seal a secret into the garden at all, but to
keep it out and point at where it really lives — an encrypted secrets.toml in
your dotfiles, a password manager, a hardware token. The garden convention is
pointer-or-seal, never plaintext: either seal it with Layer B, or store a
one-line note saying where the real thing is. Reach for a seal when the secret
genuinely belongs in the garden’s history; reach for a pointer when it belongs
somewhere else and the garden only needs to remember that.
Deploying sealed files
Section titled “Deploying sealed files”softfig deploy decrypts a sealed source to plaintext in the target and in its
deploy cache (both owner-only, outside the vault). That is a deliberate
declassification; see Deploy Dotfiles. Rendering secrets
into configs at deploy time is planned, not built.
Sealed data depends on your keys
Section titled “Sealed data depends on your keys”Sealed content is only as recoverable as your vault. Read Recovery & escrow before you seal anything you can’t lose.
Related: Deploy Dotfiles, Reference → Crypto for the primitives, and Internals → Vault for how the two layers are built.