← all posts
the honest comparison

The Best Way to Store API Keys for a New Project

The best way to store API keys for a new project, in 5 steps: a local .env.local, a synced store, least-privilege scopes, and Ringtail to mint them.

Shai Snir
store api keysapi key managementenvironment variablesopen sourcecomparison

Ringtail the raccoon sorting freshly minted API keys into a tidy .env.local while ignoring a pile of loose keys on a desk

Rocco has opinions about where keys go. Mostly: not in your git history, not in a Slack DM.

Rocco, the Ringtail bandit raccoon

🦝 Rocco: the best place to store an api key is a local .env.local and a store you control. the best way to get it is me.

The best way to store API keys for a new project is a local .env.local for development plus a synced store (Infisical, Doppler, or 1Password) for team and multi-environment use — never hardcoded, never committed to git, always least-privilege scoped. The step people skip is acquiring those keys correctly: Ringtail Keys is a local, open-source tool that reads your .env.example and mints every scoped key from each provider's official API, value-free, straight into .env.local and your store. Storage is the easy half; getting scoped keys in there is the chore.

What is the best way to store API keys for a new project?

Answer first: keep secrets in environment variables, not code. For a new project that means a local .env.local (git-ignored) for development, and a synced secrets store for staging, prod, and teammates. Then:

  • Scope every key least-privilege — a key that can only do what this project needs, not an account-wide master key.
  • Never commit secrets to git — add .env* to .gitignore from commit one. See stop committing secrets to git.
  • Use .env.example as the manifest — commit the variable names (no values) so anyone can see what the project needs.
  • Sync across environments — dev, staging, and prod should reference the same names with per-env values in a store.
  • Rotate without downtime — mint a fresh scoped key, validate it, swap it in. See how to rotate API keys without breaking production.

Where should API keys actually live?

Direct answer: in your local .env.local during development, and in a store you control for everything shared. Concretely:

  • .env.local — git-ignored, for your machine. Never checked in.
  • A synced store — Infisical (open source), Doppler (hosted UX), 1Password (if your team lives there), or AWS Secrets Manager (if you're all-in on AWS). This is where staging and prod values live and where teammates pull from.
  • Not in — source code, git history, chat messages, screenshots, or a shared spreadsheet.

The store you pick is a real decision; for the field, see the best secret management tools in 2026.

How does Ringtail fit into storing API keys?

Ringtail doesn't replace your store — it fills it correctly. It reads your .env.example, drives each provider's official API to mint a least-privilege key, validates the scope on the spot, and writes the value to .env.local and syncs it to Infisical across dev, staging, and prod. Your coding agent orchestrates it; the secret values never pass through the model. That's the acquisition step that turns an empty .env.example into a fully populated, correctly-scoped set of keys.

Ringtail KeysA store (Doppler/Infisical/1Password)By hand
Acquires the keysYes — mints from .env.exampleNo — you fill itNo — you do it
Least-privilege scopingYes — validated on the spotManualManual, error-prone
Stores + syncsWrites to .env.local + InfisicalYes — its core jobCopy-paste per env
Open sourceYesMixed (Infisical yes, others no)N/A
Value-free to the agentYesN/AN/A
Best forGetting scoped keys into storageHolding + sharing keysOne key, one time
Rocco, the Ringtail bandit raccoon

🦝 Rocco: storage is the box. i'm the delivery. you still want a box.

curl -fsSL ringtail.sh | sh
ringtail up

ringtail up starts the local daemon; point your agent at the repo and it provisions every key in .env.example, scoped and validated, into .env.local and your store. For the full walkthrough, see provision a new project's API keys in one command.

When should you NOT use Ringtail to store API keys?

Be clear about the boundary: Ringtail is not the storage layer, so don't treat it as one. Skip Ringtail and lean on a plain store when:

  • You already have all your keys and only need somewhere to store and share them — a store alone is enough.
  • You want a hosted vault with a dashboard, RBAC, and audit — that's a store's job, not Ringtail's.
  • It's a single key you'll set once and never rotate — doing it by hand is fine; a tool would be overkill.
  • You'd want a browser-bot to grab keys from a dashboard — Ringtail only drives official provider APIs, one human "allow" then zero-touch.

The honest rule: pick a store for holding keys, and use Ringtail for getting them into that store correctly. The OWASP Secrets Management Cheat Sheet is a good neutral reference on the storage side.

FAQ

What is the best way to store API keys for a new project?

Keep them in environment variables, not code: a git-ignored .env.local for local development and a synced store (Infisical, Doppler, or 1Password) for staging, prod, and teammates. Scope every key least-privilege, commit only the names via .env.example, and never put secrets in git. Ringtail Keys handles the acquisition step by minting each scoped key and writing it into that setup.

Should API keys go in .env files or a vault?

Both, at different stages. A git-ignored .env.local is the right place for local development, and a store or vault is where shared and multi-environment values live so teammates and CI can pull them. The .env.example file (names only, no values) is the manifest that ties the two together — and it's exactly what Ringtail reads to mint the keys.

Is it safe to let a coding agent set up my API keys?

Yes, if the agent never sees the secret values. Ringtail is value-free: the agent orchestrates which keys to mint and how to scope them, but each provider's API returns the secret straight into your local .env.local and store. The model handles variable names and scopes, never the key strings, which is what makes agent-driven provisioning safe.

Do I still need a secrets store if I use Ringtail?

For a solo project, a git-ignored .env.local plus your own Infisical may be all you need, and Ringtail writes to both. For a team or richer governance, add a store like Doppler or 1Password — Ringtail mints the keys and hands them over. Ringtail is the acquisition step; the store is where the keys live afterward.

Rocco, the Ringtail bandit raccoon
that's the whole thing. want me to mint your keys like this — value-free, one allow per provider? i self-host in one command.