Quickstart: open a vault, run one command.
Nine commands from an empty directory to a program running with a secret in its environment that never touched your shell history.
Before you start#
You need a Rust toolchain at 1.96.0 or later, because the workspace is on edition 2024. macOS and Linux are the supported hosts. There is nothing to download: you are building the two binaries yourself from a source tree you have been given access to.
Use a throwaway API key for this. The whole point of the walkthrough is that you should not trust a pre-release vault with a credential that matters.
Build the two binaries#
cargo build -p locker-cli --bin locker
cargo build -p locker-server --bin locker-daemond
locker is the command-line client. locker-daemond is the local broker that holds the unlocked vault.Put both on your PATH, or call them by path. The rest of this page assumes they are on your PATH.
Create the vault#
locker init --stdin
Emergency Kit written to /…/slifer/emergency-kit.txt
init reads your passphrase from standard input, generates a Vault Secret Key, and writes an Emergency Kit file with mode 0600.Unlocking needs both factors: something you remember and something that was generated for you. The Vault Secret Key is not stored inside the vault file, so a copy of that file alone cannot be attacked by guessing your passphrase.
Do not open the Emergency Kit in an editor an agent can see, and do not paste it into a chat. It contains the Vault Secret Key. The command prints the path rather than the contents on purpose. If you lose it and you have not memorized the machine-form line, the vault is not recoverable. That is the design, not a bug.
Start the daemon and unlock#
locker-daemond &
locker unlock --stdin
unlock wants two lines on standard input: the passphrase first, then the "Machine form (hex)" line from your Emergency Kit. The vault re-locks itself after fifteen minutes of inactivity.
Override where the daemon keeps its state with SLIFER_RUNTIME_DIR, and where the vault file lives with SLIFER_VAULT_PATH. The runtime directory is always clamped to mode 0700.
If the daemon was killed rather than stopped cleanly, its port and session files are left behind and the next start fails to bind with an already-exists error. Point SLIFER_RUNTIME_DIR at a fresh directory, or remove the stale files.
Check it worked#
locker status --json
Store a provider key#
locker secrets add OPENAI_API_KEY --provider openai --stdin
locker secrets list
secrets list and secrets show return aliases, providers, versions, and timestamps. Neither returns a value, and there is no flag that makes them.
Run something with the secret#
locker run --secret OPENAI_API_KEY -- python app.py
Standard input, output, and error are inherited, so this is transparent inside a pipeline, and the child's exit code passes through unchanged. Rename on the way in with --secret VAULT_ALIAS=ENV_NAME when the program expects a different variable name.
Every one of these injections is written to the activity log under the actor locker-run, so routine use cannot quietly hide inside the same record as a real break-glass reveal.
locker events list --limit 20
What this does not do yet#
locker run is the compatibility path, and it is honestly weaker than the brokered one. Once the child holds the variable, the value is in ordinary process memory: readable through a debugger, a core dump, or the process table on some systems. Slifer cannot zeroize memory it does not own.
The stronger path is to never give the program the key at all and let it call through the broker instead. That is Proxy and policy.