
AI coding assistants like Claude Code, Cursor, and GitHub Copilot are becoming part of our daily workflow. They read our files, understand our codebase, and help us write code faster. But there's a problem - they can also read your .env files. A story has been recently circulating on social media, but I also experienced this firsthand:

Some AI tools such as Cursor don’t read yout .env file by default, but on the other hand, Claude code will take a peek unless you tell it not to. A good way to prevent this is tu set up your ~/.claude/settings.json file that sets the default rule for all your projects.
When an AI assistant reads your .env file, those secrets get sent to an LLM. Your API keys, database passwords, and other credentials become part of the context window. This is a security risk that sometimes gets overlooked until it's too late.
🚨 If this has happened to you:
Treat any leaked secret as compromised. Accidentally pasting your API key to Google, sending it through Slack, or just commiting it to a repository is a security risk and needs to be addressed immediately. Revoke the API key immediately and generate a new one. If you're working on a team, let them know so they can rotate the key on their end as well. It’s better to admit the mistake than to have it exploited. Happens to the best of us.
The good news is that there's a solution that can help you keep your secrets safe, while utilizing the simplicity of the .env file. In this blog I would like to show you how to set this up using 1Password CLI tool. There are other providers such as Bitwarden, Doppler, or even solutions from AWS, Google, and Azure that provide similar functionality.
The concept is simple. Instead of storing actual secret values in your .env file like this:
You store references to secrets in your 1Password vault:
The format follows this pattern: op://vault-name/item-name/field-name
When you run your application, you use the op run command to inject the actual secrets at runtime:
1Password intercepts the secret references and replaces them with real values from your vault. The secrets only exist in memory during execution - they're never written to disk.
This approach gives you several advantages:
.env file, they only see references like op://Work/Stripe/api_key, not actual secrets.env file because it only contains referencesLet me walk you through the setup process. I'm using macOS, but the steps are similar for other platforms.
If you don't have Homebrew installed, you'll need to install it first. Then run:
This step is important - it allows the CLI to authenticate through the 1Password desktop app, which means you can use Touch ID instead of typing your master password every time.
Open your 1Password desktop app and:
Test that everything is connected properly:
You should see a list of your vaults. If this works, you're all set up.
Now let's put this to work. Let’s say you have a project with a .env file that looks like this:
First, create these secrets in 1Password. I recommend creating a dedicated vault for development secrets, or organizing them in your existing Work vault.
Then update your .env file to use references:
Now run your application with:
The CLI will prompt for authentication (or use Touch ID if you have that set up), fetch the secrets from your vault, and inject them as environment variables.
You might be wondering if you have to type op run every time. You have options here.
You can update your package.json scripts:
Now npm run dev automatically uses 1Password.
Or create a shell alias in your .zshrc:
That said, I actually appreciate the small friction of op run. It reminds me that secrets are being accessed, which keeps security top of mind.
With credentials hidden this well, it can someone get confusing when trying to debug a problem. 1Password CLI will not print out your environment variables into terminal. Let’s say you have a script that looks like this:
Running this script will still print out just the reference to the secret, not the actual value.
To reveal the actual value, you can use the --no-masking flag:
For me personally, this change made me more confident that I’m not accidentally leaking my keys to A.I. assistants. It also took away the chore of finding my API keys in .env files from other projects, when I’m experimenting with multiple small projects at once
The setup takes about five minutes, and the workflow change is minimal. If you're already using 1Password for personal passwords, extending it to development secrets is a natural next step.
Hope this helps! If you found this useful, consider sharing it with your team. You can follow me on Twitter or LinkedIn for more content like this.
From time to time I send some useful tips to your inbox and let you know about upcoming events. Sign up if you want to stay in loop.