proxykey API KEY VAULT

Why storing OPENAI_API_KEY=sk-… in code and .env is a bad idea

.env looks safe: the file sits in .gitignore, it never reaches the repo, "nobody will see it." In practice the key usually leaks not through the file itself, but through a dozen places environment variables pass right through, without asking you.

2026-07-11 · proxykey

.env feels safe — and that's the mistake

.gitignore closes exactly one leak channel: an accidental commit of the whole file. But an environment variable, once loaded into a process, lives in that process's memory and is reachable by anything with permission to interact with that process — from monitoring systems to neighboring processes on the same machine. You can hide the file; you can't hide what the process does with it afterward.

Where an environment variable leaks even if .env was never committed

ChannelHow it happens
Error logs / monitoringSentry, Datadog and similar services attach the process's full environment to a crash report by default — keys included.
CIprintenv/env in a debug pipeline step, a variable dump on a failed build — all of it lands in CI logs, which are often reachable by more people than the repo itself.
Dockerdocker inspect shows a container's ENV variables in plain text; if the key was passed via ENV in the Dockerfile, it's baked into an image layer and ships with it to the registry.
/proc/<pid>/environOn a multi-user server, any process with the same UID can read your process's environment directly from /proc.
Client bundlesThe bundler (Next.js, Vite) inlines variables prefixed NEXT_PUBLIC_/VITE_ straight into the JS shipped to every visitor's browser — a prefix typo turns a secret public.
The "quick script"test_gpt.py with the key right in a command-line argument lands in bash history and in ps aux output.

Check yourself: has this already happened?

What to do instead

The problem isn't the filename — it's that the environment variable holds a real, unrestricted key. The fix is to put a revocable credential-proxy token into OPENAI_API_KEY instead of the key itself:

# before
OPENAI_API_KEY=sk-proj-...the-real-thing...

# after — same code, same variable, different value
OPENAI_API_KEY=vlt_openai_...
OPENAI_BASE_URL=https://api.proxykey.org/p/openai

The variable name and the application code don't change — what's inside it does. If this .env leaks anyway (and per the channels above, sooner or later it will), what gets out is a revocable token, not the key. For how the substitution itself works, see the article on API key injection.

FAQ

Isn't it simpler to just hide .env better?

.gitignore closes exactly one channel — an accidental commit. It doesn't protect against monitoring logs, a CI dump, docker inspect, or another process on the same machine reading /proc/pid/environ — which is how environment variables most often leak in practice.

What if the key has already leaked?

Revoke it with the provider first — that stops the damage immediately. Then follow a checklist: assess what was accessible, find the source, clean up history. The full walkthrough is in the article on an OpenAI key leak.

Does this apply to keys other than OpenAI's?

Yes — every leak channel applies equally to any key: Stripe, Anthropic, a GitHub token, a Telegram bot token. The sk-… format is specific to OpenAI; the underlying problem isn't.

Replace the value, not the code

Add a key to proxykey, get a vlt_… pass, and put it in the same environment variable. Free, no card required.

Get started →