Back to all posts
Photo by Filip Szalbot / Unsplash
Managing Secrets with 1Password CLI

Managing Secrets with 1Password CLI

Ian note: This post was original published on my personal blog back in 2023 . In October 2025, 1Password started adding support for environment variables directly. I'm going to keep it in here in case anyone finds it useful as a jumping off point for other interesting 1Password CLI tooling!

Most developers have some version of a dotfiles repository: shell config, editor settings, aliases, small scripts—the tools that make a machine feel like your machine. For many of us, it’s one of the first things we set up on a new computer, right after a browser, a password manager, and a terminal.

Dotfiles themselves tend not to be the problem:

API keys, tokens, webhook URLs—anything you definitely do not want committed to a public repo. The usual solution is to rely on a local, gitignored environment file.

And that works… until it doesn’t. Anyone who has ever accidentally deleted a local env file knows the pain of reconstructing credentials from scratch. It’s tedious, error-prone, and entirely avoidable.

Ideally, we want something secure, durable, and automation-friendly.

Using 1Password as a Secrets Source

Many teams already use 1Password as their system of record for credentials. Turns out, it can also act as an excellent database for local development secrets.

1Password provides a CLI tool, op, that allows secrets stored in your vault to be injected directly into environment variables or configuration files—without ever committing plaintext secrets to your repository.

That gives us a clean separation of concerns:

  • Public dotfiles repo: configuration and structure
  • Private password manager: actual secrets

The Basic Flow

First, store your secrets in 1Password as usual.

Next, create a template environment file that references those secrets using 1Password’s secret reference syntax. For example:

AWS_ACCESS_KEY_ID=op://development/aws/access_key_id
AWS_SECRET_ACCESS_KEY=op://development/aws/secret_access_key

This template file is safe to commit. It contains no secrets, only pointers.

When you need a real, secret-filled file locally, you use op inject to resolve those references:

cat ./local.env | op inject -f -o mysecrets.zsh

The -f flag skips the interactive confirmation, and -o writes the output directly to a file instead of stdout.

That generated file contains real credentials, so it stays gitignored. If it ever gets deleted, no problem—you can regenerate it in seconds. The source of truth lives in 1Password, where it belongs.

Why This Works Well

This approach scales surprisingly nicely:

  • Your dotfiles repo can be fully public if you so choose.
  • Secrets are never committed, even accidentally.
  • Rebuilding a machine is fast and deterministic.
  • You reduce the risk of credential loss or drift.

It also mirrors patterns we recommend at larger scales: keep configuration declarative, keep secrets centralized, and automate the glue between them.

Final Thoughts

We treat production systems carefully because the cost of mistakes is obvious. Local development often gets a pass, even though it’s where patterns, shortcuts, and expectations—not all of them thoughtful or secure—are formed.

Applying production-grade thinking to developer tooling doesn’t slow teams down—it removes friction they didn’t need in the first place.