skip to content
Jakob Osterberger

Secrets-free .env with 1Password CLI and DDEV

/ 2 min read

Link post → studiomitte.com
Read original → studiomitte.com

I wrote up a guide for using 1Password CLI with DDEV for my companies blog. Here you can read the english version.

Your .env file sits one git add . away from leaking your database password. 1Password CLI fixes this without extra infrastructure. Replace credential values with references, and let op run inject the real secrets at container start. Nothing sensitive ever even touches your filesystem.

Prerequisites

  • A 1Password account (individual or teams)
  • 1Password CLI installed
  • A DDEV project with credentials in a .env file

Connect 1Password CLI

Add your account and sign in:

op account add
eval $(op signin)

eval $(op signin) sets session tokens in your current shell. You’ll re-run this each session, or configure biometric unlock for automatic authentication.

Find your secret references

1Password references use the format op://vault-name/item-name/field-name. To find the exact field names for an item, fetch it as JSON:

op item get "My Database" --format json

Look for the reference key inside each field object - it gives you the exact string to paste. You can also right-click any field in the 1Password desktop app and copy its secret reference directly.

Replace values in .env

Swap out credential values for their op:// references:

DB_PASSWORD=supersecret123
STRIPE_SECRET=sk-live-abcdef123456
SMTP_PASSWORD=mailpassword

The .env is now safe to commit or sync - it holds paths, not secrets.

Tell DDEV to accept injected variables

DDEV doesn’t automatically forward host environment variables into the web container. Add each variable name to web_environment in .ddev/config.yaml:

web_environment:
  - DB_PASSWORD
  - STRIPE_SECRET
  - SMTP_PASSWORD

Without this, op run resolves the secrets into the host process but they never reach the container.

Start DDEV with secrets resolved

op run --env-file=".env" -- ddev start

op run reads the .env file, resolves each op:// reference against 1Password, injects the real values into the process environment, then hands off to ddev start. The secrets exist in memory for that process only - never written to disk.

💡 If your .env file isn’t in the project root, adjust the path: op run --env-file="config/.env" -- ddev start

The main trade-off: everyone running the project needs 1Password CLI and vault access. For solo work that’s nothing. For teams, make sure the relevant items are in a shared vault before rolling this out.


Related Posts


Jakob's Newsletter

Stay updated about my latest ideas, thoughts, journeys and projects. I'll send you the best of what I discover on the internet, what I've learned, and what I'm working on.

No spam, ever. Unsubscribe at any time.

Powered by Buttondown.

Enjoying the content?

Buy Me a Coffee at ko-fi.com