Read secret environment variables once per command, then unset them (closes #60)
check / check (push) Failing after 2s
check / check (push) Failing after 2s
init and vault create put the mnemonic into the process environment for vault.CreateVault to read back, so every program they ran, gpg included, inherited it, and SB_SECRET_MNEMONIC and SB_UNLOCK_PASSPHRASE were read at 13 places and never unset. Each command that may need them now reads both once, in its RunE, into locked buffers on the CLI Instance, and unsets them at once. The buffers are passed down: vault.CreateVault takes the mnemonic, a Vault carries Mnemonic and UnlockPassphrase, and the PGP, keychain and Secure Enclave unlocker constructors take both. Nothing below the command reads the environment. README warns against both variables. Model: opus-5-5
This commit is contained in:
@@ -315,6 +315,16 @@ Each vault maintains its own set of unlockers and one long-term key. The long-te
|
||||
- `SB_UNLOCK_PASSPHRASE`: Pre-set unlock passphrase (avoids interactive prompt)
|
||||
- `SB_GPG_KEY_ID`: GPG key ID for PGP unlockers
|
||||
|
||||
**Warning:** `SB_SECRET_MNEMONIC` and `SB_UNLOCK_PASSPHRASE` expose the secret
|
||||
they hold. Other processes running as the same user can read a process's
|
||||
environment (on Linux, from `/proc/<pid>/environ`). Every child process of the
|
||||
shell or script that sets them inherits them, `gpg` included. Set on a command
|
||||
line or in a CI job, they end up in shell history and CI logs. `secret` unsets
|
||||
each one as soon as it has read it, so that the programs it runs itself, such
|
||||
as `gpg`, do not inherit it, but that erases nothing: the environment the
|
||||
process started with, and its memory, still hold the value. The interactive
|
||||
prompt, used when the variable is not set, is the safer default.
|
||||
|
||||
## Security Features
|
||||
|
||||
### Encryption
|
||||
|
||||
Reference in New Issue
Block a user