JIT Secrets With 1Password
Ensuring scoped environment access
The norm is to keep your environment or .env
files populated with secrets, but what if I could
show you how to store only safe secret references and have those secrets injected at runtime?
Almost as JIT1 secrets, you could even keep all application configuration within 1Password2 and have it available only to the application you’re running.
First Steps
I’m not going to teach you how to install 1Password, follow their documentation to do so, if you’re reading this you likely already have this covered.
Once you have that figured out, you’re going to want to grab a secret reference from your 1Password application to test that everything is setup correctly, you can right click on a single value in your 1Password application and in the dropdown you should be able to see the option.
This will copy a secret reference string to your clipboard, it will look like this:
op://Private/502a50c985f858297eaf3d6/tokens/token
If we’ve configured everything correctly, we should be able to run this command and see our secret printed in our shell (masked by default).
$ TOKEN="op://Private/502a50c985f858297eaf3d6/tokens/token" op run -- printenv TOKEN
<concealed by 1Password>
You can disable concealment with the --no-masking
flag, op run --no-masking
will show you the actual secret, this also fixes some interactive commands that misbehave when using this,for example docker compose pull
doesn’t show colors and doesn’t clean the terminal as it should creating a mess, but passing the flag before executing our docker compose
commands fixes it.
Basic Usage
What you just read above is the gist of it, op run [--no-masking] -- <your-command>
but that of
course does not do anything without secrets being referenced, so what I like to do is within my
~/.zshrc
file, I export several system-wide secret references, for example $GITHUB_TOKEN
.
export KAGI_API_KEY="op://Private/Kagi/API Token"
export GITHUB_TOKEN="op://Private/GitHub/tokens/token"
I also like to create some aliases to make tool usage comfortable since I don’t want to type op run --
before all my commands, for example.
alias gh="op run -- gh"
.env File
If you need to declare a specific set of variables, and you’ve got many you can also pass an entire
.env
file.
$ op run --env-file .env --no-masking -- docker compose up --detach --remove-orphans
APP_NAME=My Application
APP_ENV=production
APP_KEY=...
GITHUB_TOKEN="op://Private/GitHub/tokens/token"
...
This also opens up the ability to share a secret entry with your team over 1Password and having all secrets automatically injected into their environments, and when you need to rotate one of them you can do it from within the 1Password interface and everyone will get the latest version of it.
Footnotes:
-
Just In Time: https://en.wikipedia.org/wiki/Just-in-time_compilation ↩︎
-
I used to like 1Password, I still do, but I used to, too. ↩︎