Best practice: commit .env.example, gitignore .env. The Opus 4.7 corpus mostly follows it — but not always.
The numbers
Across 12,095 Opus 4.7 repos:
| File | Repos | What it means |
|---|---|---|
| .env.example | 1,877 (15%) | The correct pattern — template |
| .nvmrc | 173 | Node version pinning |
| .env (committed) | 52 | ⚠️ Real environment file in git |
| .env.production | 51 | ⚠️ Production config in git |
| .node-version | 42 | Alt Node version pinning |
| .envrc | 40 | direnv — usually safe, loads local .env |
| .env.development | 38 | ⚠️ Dev environment in git |
| .env.test | 19 | Test environment in git (lower risk) |
| .env.local | 7 | ⚠️ Next.js local env in git |
The risk
52 + 51 + 38 + 7 = 148 repos have some .env flavor committed. Roughly 1.2% of the corpus.
Best case: those .env files contain placeholder values like DATABASE_URL=postgres://user:pass@localhost/db. Medium case: they contain real but revocable keys (Supabase anon keys, for instance, are public-safe).
Worst case: they contain real production secrets — API keys to OpenAI/Anthropic, Stripe keys, database credentials, AWS access keys.
Our credential scanner runs against every file in the corpus and flags specific secret patterns. Early findings suggest:
- Most
.envcommits are placeholder values, safe - A minority contain Supabase anon keys (public-safe by design)
- A handful contain real API keys — these are the actual leaks
The absolute number is small (under 50 repos with real-secret leaks, by rough estimate). But GitHub search indexes these, and the economic value of a leaked API key is high enough that bots find them within hours.
What’s going wrong
Three failure modes:
1. .gitignore never written
Some repos don’t have a .gitignore at all. When the developer runs git add ., everything including .env gets staged.
2. .gitignore written but .env not listed
More common. .gitignore exists (4,997 repos have it) but the specific .env entry is missing. This tends to happen when the template wasn’t Next.js or Vite (both of which ship .gitignore with .env.* already listed).
3. Renamed files skip the ignore
.env.production might be gitignored but .env.production.local isn’t. Developers rename for environment-specific reasons and accidentally bypass the rule.
The Opus 4.7 dynamic
Is this Opus 4.7’s fault? Partly.
- Opus 4.7 scaffolds
.env.examplecorrectly in 15% of repos ✓ - Opus 4.7 scaffolds
.gitignorein 41% of repos ✓ - Opus 4.7 does not reliably prompt “don’t commit your .env” as a post-scaffold step ✗
A simple CLAUDE.md or post-scaffold check would catch this. Something like:
if [ -f .env ] && ! grep -q '^\.env$' .gitignore; then
echo "WARNING: .env exists but isn't gitignored"
fi
This is a six-line shell script. Running it post-generate would eliminate the 148 affected repos.
The Supabase caveat
Many committed .env files we see contain NEXT_PUBLIC_SUPABASE_ANON_KEY. Supabase anon keys are public by design — they’re safe to commit because row-level security (RLS) enforces access control.
That said:
- Supabase service role keys are not safe to commit
- Environment files often contain both
- 52 committed .env files include at least some with service role keys, judging from pattern samples
Recommended fix
Three checks that would close 95% of the gap:
- Pre-scaffold: always include
.env*in.gitignoreexcept.env.example - Pre-commit hook: reject commits that contain
.envwithSERVICE_ROLEorSECRET_KEYpatterns - GitHub Secret Scanning: Enable secret scanning on the repo (GitHub does this for public repos automatically — but private repos aren’t scanned without the paid tier)
How bad is it in context?
52 leaked .env files out of 12,095 repos is 0.4%. For comparison:
- The general GitHub baseline for .env leaks has been measured around 1-2% historically
- Claude’s .env leak rate is less than half the baseline
So Opus 4.7 is actually doing better than the population average on this metric. But “better than baseline” isn’t “good enough” when the stakes are production API keys.
Separate: .env.example is in 15% of repos (1,877) — the correct pattern is well-adopted.