Skip to content

Credentials

Secrets live in your OS keychain and never in a file loadout controls. Your configuration records only which entries exist and which is active.

credentials:
npm_token:
active: personal
entries: [personal, work]
gh_token:
env: GHP_TOKEN
active: personal
entries: [personal, work]

No value appears anywhere in that file, and none ever will. loadout scan and sync push both refuse anything credential-shaped.

Terminal window
loadout cred list # what is declared, which is active, which have values
loadout cred set npm_token work # prompts, does not echo
loadout cred use npm_token work # make an entry active
loadout cred remove npm_token work # delete the stored value

--stdin reads the value from standard input instead of prompting, for scripted setup:

Terminal window
pass show npm/work | loadout cred set npm_token work --stdin

This is the single most common surprise, so it is worth stating plainly.

Terminal window
$ loadout cred set npm_token work
$ loadout env
export NPM_TOKEN='...'
$ echo $NPM_TOKEN
# empty

Nothing is broken. loadout env prints export lines. It cannot set them. It runs as a child process, and a child cannot change its parent’s environment — the same constraint that makes p and activate shell functions rather than subcommands.

The eval is what applies them, and only to the shell that runs it:

Terminal window
eval "$(loadout env)"

Add a second line to your shell configuration, below the source:

Terminal window
source ~/.config/loadout/init.zsh
eval "$(loadout env --quiet)"

--quiet drops the diagnostics, so a locked or unavailable keychain cannot write into every new shell you open.

This is opt-in on purpose, and the trade is real in both directions.

Writing secrets into the generated file would leave them in plain text on disk, so something has to fetch them at runtime instead. But that something reads your keychain every time a shell starts — which may mean an unlock prompt — and puts your tokens in the environment of every process you launch from that shell.

Add the line if you want that. Leave it out and run eval "$(loadout env)" in the shells that actually need tokens.

The name is derived from the credential key: upper-cased, with -, . and / normalised to underscores. So npm_token exports NPM_TOKEN.

When the consuming tool expects something the key cannot produce, say so:

credentials:
gh_token:
env: GHP_TOKEN

Two credentials resolving to the same variable is rejected when the configuration loads, since otherwise one would silently overwrite the other.

Tried in order, first available wins:

PlatformBackend
macOSsecurity (Keychain)
Linuxsecret-tool (libsecret)
Eitherpass

Values are addressed as loadout/<credential>/<entry>.

When none is present the error names what to install rather than just failing, which matters on a server where none of them exist. On a headless Linux box, pass is usually the least trouble, since libsecret wants a running daemon.

Every value is single-quoted with embedded quotes escaped, because the output is eval-ed. A token containing $(...), backticks or a newline cannot execute anything.

A host may reference a credential rather than carrying a password:

hosts:
- alias: legacy
hostname: legacy.example.com
user: deploy
password: cred:legacy_password

cred:<name> is the only accepted form. A literal password in that field is rejected by validation and by the scanner, and prefer a key over a password wherever the remote end allows it.

Credential values are never sent to the page. The interface is told only whether a value exists, which is enough to show you a filled or empty indicator and no more. Setting a value posts it once to a loopback server that writes it straight to the keychain.