Another trick I've used is to use named FIFOs for commands that expect there to be files rather than stdin/stdout. The command that spits the sensitive credential outputs to the FIFO and blocks.
The command that needs the sensitive credential to be input is pointed to the FIFO and reads it, and nothing is left over on disk or in the shell's history or memory.
I'm sure other languages have equivalents but I rarely see this.. for example I was about to say serde doesn't do it, but it looks like it's possible with a wrapper type? https://docs.rs/redactrs/latest/redactrs/
Anyway, this kind of tagging is good, I want more!
This article does not mention that environment variables are also visible by process in /proc/*/environ (which has restrictive permissions, but is completely visible to root).
PuTTY has added a -pwfile option for use in ssh. If not exported, this interface is likely the best for non-key batch use. It seems much superior to sshpass.
The old .netrc format can be adapted for storage (which appears popular for curl), but I prefer sqlite databases, with permissions removed for all but the owner.
I'm surprised to see that very little is known about the Linux kernel keyring. With keyctl[0] you can put secrets scoped to process and ensure that they stay there only for a limited period of time. The tool isn't intuitive, but it's the way I put my 2FA and secrets in shell without bothering about leaking anything.
I think single-secret files and filesystem permissions are superior between the presented options.
You don't need root to do what rootless podman does and create and work in directories that processes spawned from your normal user can't normally read using subuids. tmpfs to keep it off actual disks.
i usually use subshells and a project specific shell script to not have variables linger around in long-lived shell processes: ` ( . ./credentials && PW="$CRED_PW" ./the_thing ) ` so credentials can be retrieved via pass or whatever mechanism provides them.
> But I definitely feel a lot more comfortable when secrets are never written to persistent unencrypted files, and being aware of these leakage vectors is helpful to avoid that!
It is very common for people to set environment variables for a server process from a config file that is readable by the application which is a bigger problem. At least put them a file that is only root readable (and have the process started by root).
Lately I've been using my desktop keyring/wallet to store the secrets encrypted at rest. Then on login they get injected to my shell directly from the secure storage (unlocked at login).
I feel this is probably better than plain text, but if my machine gets popped while logged on you likely have Access to active browser sessions between MFA flows and could do more damage that way.
Not directly related to this, but you can use systemd-creds to store secrets at rest. It can even work with a tpm2 chip or a key file to encrypt the secrets.
And then use these tips for when you want to interactively reference those stored secrets.
On macOS you can store secrets in Keychain and then retrieve them with a command (using biometrics by default, or without biometrics if you so wish). The most obvious example is to hook `sudo` up to biometrics using `sudo -A` and askpass to tetris the secret (password).
16 comments
[ 2.5 ms ] story [ 42.3 ms ] threadThe command that needs the sensitive credential to be input is pointed to the FIFO and reads it, and nothing is left over on disk or in the shell's history or memory.
facet (rust) allows tagging fields as sensitive so they won't show up in logs: https://facet.rs/guide/attributes/#sensitive
I'm sure other languages have equivalents but I rarely see this.. for example I was about to say serde doesn't do it, but it looks like it's possible with a wrapper type? https://docs.rs/redactrs/latest/redactrs/
Anyway, this kind of tagging is good, I want more!
PuTTY has added a -pwfile option for use in ssh. If not exported, this interface is likely the best for non-key batch use. It seems much superior to sshpass.
The old .netrc format can be adapted for storage (which appears popular for curl), but I prefer sqlite databases, with permissions removed for all but the owner.
[0]: https://www.man7.org/linux/man-pages/man1/keyctl.1.html
You don't need root to do what rootless podman does and create and work in directories that processes spawned from your normal user can't normally read using subuids. tmpfs to keep it off actual disks.
var=value some_command
This will still show up in /proc, but a lot of internal tools often rely on environment variables, so it’s kind of inevitable.
>op read "op://foo/bar/password"
related: https://news.ycombinator.com/item?id=43721228
If you prepend your command with a space, it will not be added to your shell history.
It helps with pasting special chars, newlines, and remote sessions without access to the local clipboard.
https://manpages.debian.org/jessie/moreutils/vipe.1It is very common for people to set environment variables for a server process from a config file that is readable by the application which is a bigger problem. At least put them a file that is only root readable (and have the process started by root).
(looking at you `gcloud`)
best practice I've heard is to create a user fs mount that prompts every time it's accessed?
I feel this is probably better than plain text, but if my machine gets popped while logged on you likely have Access to active browser sessions between MFA flows and could do more damage that way.
And then use these tips for when you want to interactively reference those stored secrets.