Secrets management
Keeping API keys and passwords out of your code, stored somewhere encrypted and handed to the app at runtime instead.
See it
What it is
The rule underneath it: a secret has exactly one home, and everything else holds a reference to it rather than a copy. The home is a manager (1Password, Doppler, Infisical, AWS Secrets Manager, HashiCorp Vault) or your host's encrypted environment store, and the app reads it at boot. Your repo carries a .env.example with every key name and no values, never a real .env.
Any key that costs money, sends email, or touches customer data belongs there from the first commit, because retrofitting means rotating everything you already leaked. The parts that matter in practice: one set of values per environment (dev keys must not reach prod), a rotation you have actually rehearsed once, and some record of who read what.
Two traps. Environment variables are not encrypted, only less visible: they leak into crash reports, 'docker inspect', CI logs, and any error handler that dumps process.env. And the browser has no secrets at all, so anything bundled into client JS, including every NEXT_PUBLIC_ or VITE_ variable, ships to every visitor. If a third-party API needs a real key, proxy the call through your own server.
Ask AI for it
Set up proper secrets management in this project. Move every hardcoded key, token, password, and connection string out of the source into environment variables. Create a .env.example listing every key name with empty values, add .env and .env.* to .gitignore, and add a typed config module that reads and validates all of them with zod at startup, so a missing secret fails fast on boot instead of at 3am. Keep dev, staging, and prod values separate, keep every real secret server-side (nothing behind a NEXT_PUBLIC_ or VITE_ prefix), and finish with a list of which keys I must now rotate because they were previously committed.