
Production secrets management means storing API keys, database URLs, signing keys, and tokens in a dedicated secrets manager (Doppler, Infisical, 1Password Secrets Automation, AWS Secrets Manager, or HashiCorp Vault), injecting them at runtime instead of build time, scoping access per environment, and rotating on a schedule. The highest-impact first move is killing the .env file in your repo and replacing it with a managed source of truth.
If you take one thing from this post: a secret that exists in .env, .env.local, a Slack DM, a Notion doc, or a screenshot in a bug report is already compromised. Treat it as rotated.
Most production secret leaks are not from sophisticated attackers. They come from four boring places:
.env because the .gitignore was missing a line.process.env during a failed deploy.GitHub's Secret Scanning service detected over 39 million leaked secrets across public repos in 2024 alone. Of those, the most common were OpenAI keys, AWS access keys, and database connection strings. The pattern has not changed in 2026; the volume has gone up because more code is generated by AI and more AI agents write files that include sample env data.
The shift that matters: every production app team, even a two-person startup, now ships AI agents (Cursor, Claude Code, Copilot) that read and write code locally. Any secret on a developer laptop is one careless prompt away from being pasted into a chat window or committed to a side branch. Centralized secrets management is no longer a nice-to-have at series A; it is the default at week one.
.env anti-patterns you need to killA .env file is fine as a local dev convenience. It is not a production strategy. Here are the specific failure modes:
.env files. Even on a private repo, that file lives in git history forever. Anyone who clones the repo in 2030 still has the 2026 Postgres password..env.production in a Notion page. Now the secret lives in a SaaS you didn't audit, accessible to anyone with the link.NEXT_PUBLIC_* vars or a Docker image), they are not secrets anymore. Anyone who downloads the artifact has them..env for all environments. Staging and prod sharing the same Stripe key means a staging bug bills real customers..env.example. Onboarding a new engineer becomes "DM me the env file," which becomes Slack history forever..env, none of which match production, and one of them ships a feature that works on their machine and breaks on Vercel.If any of these describe your setup, the next deploy is a good moment to fix it. While you are at it, you may want to read our companion playbook on managing technical debt in a startup, because secret hygiene is the canonical example of debt you must pay down before it pays you.
There are five credible options in 2026. Pick one based on team size, cloud provider, and whether you already pay for a password manager. The honest comparison:
| Tool | Best for | Free tier | Strengths | Weaknesses |
|---|---|---|---|---|
| Doppler | Startups on Vercel/Render/Netlify | Yes, up to 5 users | Cleanest DX, native integrations with most PaaS, instant rotation API, good audit log | Pricing scales fast once you cross 10 seats |
| Infisical | Teams that want open-source + self-host option | Yes, generous | Open source, can self-host, end-to-end encryption, PR-style change reviews | Younger product, fewer turnkey integrations than Doppler |
| 1Password Secrets Automation | Teams already on 1Password | No, requires Business plan | Single vendor for human + machine secrets, excellent CLI (op), no separate audit surface | Costs extra on top of 1Password, less developer-native |
| AWS Secrets Manager | All-AWS shops, regulated industries | No, $0.40 per secret per month | Deep IAM integration, automatic rotation for RDS/Redshift, KMS-backed | AWS-only, manual rotation for non-AWS services, no nice UI |
| HashiCorp Vault | Enterprise, multi-cloud, dynamic secrets | OSS yes, Enterprise paid | Most powerful (dynamic credentials, PKI, transit encryption), audit-grade | Heavy to operate, real DevOps cost, overkill below 50 engineers |
A reasonable default for most startups in 2026: Doppler if you want SaaS, Infisical if you want open source, AWS Secrets Manager if your entire stack already lives on AWS. Vault is the right answer once you have a platform team. 1Password Secrets Automation is the right answer if your CEO already enforces 1Password for everyone.
Every modern hosting platform has an "Environment Variables" UI: Vercel, Render, Netlify, Fly.io, Railway. They all work for a single-environment side project. They all start breaking the moment you have staging + prod + preview + three developers.
The traps:
The clean pattern: use the PaaS env UI as the delivery surface, not the source of truth. Source of truth lives in Doppler / Infisical / AWS Secrets Manager. A sync integration pushes to Vercel/Render whenever the source updates. Most secret managers have first-class Vercel and Render integrations; configure once and the env vars are read-only in the PaaS UI thereafter. If you are setting up a fresh deploy, our guide on deploying Next.js on Render walks through exactly this pattern.
A surprising number of teams use the same Stripe key, same OpenAI key, and same database URL across all environments "because it's easier." It is easier until a load test on staging burns through your OpenAI quota or a seed script wipes prod.
The minimum environment separation:
dev, staging, prod. No shared values. Even the same Postgres host gets a different connection string because it is a different database.If you are wiring up Stripe webhooks correctly, this separation is what makes test replays safe and prod traffic verifiable.
The default "we'll rotate when someone leaves" plan does not work. By the time HR tells engineering that a contractor is off, the contractor has had the keys for six weeks past their last commit.
A working rotation cadence:
Vault and AWS Secrets Manager can generate dynamic secrets: a fresh database credential per request, valid for 15 minutes. If you are already on AWS or running Vault, dynamic secrets eliminate most of the rotation problem entirely.
Most teams give every engineer read access to all production secrets because "we trust each other." This is fine until you have eight engineers and one of them runs printenv | curl in a Cursor agent debugging session.
The cleaner model is deployer-only versus app-only:
This split solves the "ex-employee still has access" problem by default: revoking their SSO removes their human-only access, and they never had app-only access to begin with.
Two table-stakes practices most teams skip:
Audit logs. Every secret read, write, or rotate event needs to land in a log you can query later. Doppler, Infisical, AWS Secrets Manager, and Vault all produce these natively. Pipe them to your existing logging stack (Datadog, Axiom, BetterStack, CloudWatch) so they survive your secret manager being compromised. When you eventually have a breach, the first question your insurer asks is "show me the audit trail." If you cannot, your payout shrinks.
Git history scrubbing. If a secret has ever been committed, rotating the secret is the first step; scrubbing git history is the second. Use git filter-repo (the modern replacement for git filter-branch) or BFG Repo-Cleaner. Force-push the cleaned history, invalidate forks, and notify collaborators. Critically, scrubbing without rotating is theater; the secret is already in someone's local clone or a forked PR. Always rotate first.
GitHub's Push Protection (now default on new repos as of 2025) blocks most known-format secrets at push time. Enable it on every repo. It catches the obvious cases before they enter history at all.
If you are starting from .env files and Vercel env vars, here is the realistic four-step migration most teams can ship in one focused week:
gitleaks or trufflehog against your repo history. Anything it finds gets rotated this week, no exceptions.If your team is shipping fast and nobody owns this, a Cadence Senior engineer at $1,500/week can migrate a typical Next.js + Postgres stack to Doppler or AWS Secrets Manager in three to five days, including the audit log integration and CI rewiring. You can audit your stack with Ship or Skip first to see whether secrets management is actually your top-priority gap, or whether something like E2E test coverage deserves the week instead.
Trying to figure out who should own this? Every engineer on Cadence is AI-native by default, vetted on Cursor, Claude Code, and Copilot fluency in a live voice interview before they unlock bookings. Senior tier ($1,500/week) handles infrastructure migrations like secrets management end-to-end, with a 48-hour free trial so you only pay if the first commit lands clean.
.env files to a real secrets manager?For a typical startup with one app, three environments, and under 20 secrets, plan on two to four days of focused work. Most of that is CI rewiring and verifying nothing broke in staging; the actual import is a 30-minute step.
For most production apps with 20 to 50 secrets, you are spending $8 to $20/month. That is cheaper than the engineering time of one incident caused by a leaked .env. The cost is rarely the deciding factor; the deciding factor is whether you are already on AWS.
No. A .env.local in .gitignore plus the Vercel/Render env UI is fine for a one-person side project. Move to a real secret manager when you add your second person, or when you start handling user data subject to any compliance regime.
You can, but you lose audit logs, rotation, and easy revocation. It works for a single-VM hobby setup. It does not work the moment you have two servers, a CI pipeline, and a need to rotate a key without redeploying.
.env files for local development with multiple engineers?Use Doppler's or Infisical's CLI (doppler run / infisical run) to inject dev secrets at runtime without ever writing them to disk. New engineers get access via SSO; revoke their account and their laptop loses access on next run. No more "DM me the env file."
Use OIDC where the cloud provider supports it (AWS, GCP, Azure, Vercel all do in 2026). This eliminates long-lived CI secrets entirely. For services that still require static tokens, store them in GitHub Actions Secrets or your secret manager's CI integration, never in workflow files.