The New .env: Measuring Credential Leakage in AI Agent Instruction Files


Developers have quietly opened a new place to hard-code their own live secrets: the Markdown files they write to steer their AI coding agents. We measured how often, which files, and why.

Summary

  • AI coding agents read an instructions file in each software project to learn that project's rules. Searching public projects on GitHub, the world's largest home for open-source code, we found hundreds where the author had accidentally left a live password or access key sitting in plain text inside one of these files.
  • These are valuable secrets, not throwaway ones: working keys to popular AI services such as Google Gemini and OpenAI, cloud databases holding real data, and other paid accounts. In the wrong hands they can run up bills or expose users' information.
  • In one common file type, about 0.7% of files we checked contained a real credential.
  • This is not something the AI did. In more than 8 out of 10 cases the key was typed in by a person: a developer pasting their own working key to get the tool running, then forgetting to take it out.
  • It is a brand-new kind of exposure. These files barely existed a year ago, the security scanners most teams rely on do not yet watch them, and, unlike an ordinary settings file, their whole reason for existing is to be fed straight into the AI agent, so any secret inside travels directly into the agent's context.

A familiar mistake in an unfamiliar place

Hard-coding a secret and pushing it to a public repository is one of the oldest own-goals in software. What is new is where it is now happening. AI coding agents read a project's instruction file at the start of every session: CLAUDE.md for Claude Code, GEMINI.md for Gemini CLI, AGENTS.md / AGENT.md for the Codex-style ecosystem, .github/copilot-instructions.md for Copilot, .cursor/rules for Cursor, and so on. These files are supposed to hold conventions and context. Increasingly, they also hold live keys.

Here is the shape of it, a real text we saw repeatedly, redacted:

# Fixing the "API key invalid" error

# Problem:
GEMINI_API_KEY=your_gemini_api_key_here   # ✗ Placeholder

# Solution:
GEMINI_API_KEY=AIzaSy█████████████████████   # ✓ Real key

A troubleshooting note, written for the agent, that helpfully contrasts the placeholder with the author's working key. The comment literally labels the live credential.

The instinct is understandable. The file feels like a private note to your assistant, so pasting the real value seems harmless: "just so the agent can run it." Setup and troubleshooting docs then accumulate working keys, and some agents persist them into memory files (## Gemini Added Memories: the API key is …). The result is a credential sitting in plaintext, in a file designed to be ingested by a model, committed to a public repository.

How we measured it

We ran a sample scan. Here is the pipeline we used:

  1. Enumerate agent-instruction files across public GitHub via the Code Search API, covering nine file types (GEMINI.md, AGENT.md, QWEN.md, Copilot instruction/prompt directories, Roo/Windsurf rule directories, JetBrains Junie, and more). In all we enumerated ~100K agent-instruction files across ~45K distinct public repositories.
  2. Fetch & scan. Each file is fetched at its pinned commit from the raw CDN and matched against a deliberately broad secret regex (high recall, no placeholder filtering) so the detector casts a wide net and accepts false positives by design. The scan produced 24,441 survivors with at least one candidate regex hit.
  1. Verify with an LLM. Each survivor's hits (with surrounding context) are adjudicated one file at a time by Claude Haiku into confirmed (a real, usable external secret), weak (real but low-value: a localhost/dev/test password, PII-as-login), or false positive (placeholder, environment-variable reference, or public-by-design key).

To trust those labels, we hand-audited a stratified sample of 210 verdicts against the underlying evidence. Confirmed-class precision was ~88% (95% CI 78–94%); of 120 sampled false-positive verdicts, there were no real secrets the verifier had wrongly dismissed (95% CI upper bound ~3%). In other words, the LLM stage makes only rare mistakes when identifying secrets and effectively never discards a real one. Given that, we then manually reviewed every finding the model labeled confirmed or weak, discarded the residual false positives, and kept only genuine external credentials.

What we found

~100

confirmed live external secrets

~300

additional weak (dev/test) creds

381

distinct repositories

354

distinct owners / orgs

Because the confirmed files map almost one-to-one onto distinct repositories and owners, these are independent leaks from independent developers, not one template copied around.

Format validity is a lower bar than usability, so we went one step further. For the distinct credentials we extracted, we ran a read-only, zero-cost liveness check against each key's issuing provider wherever a free, non-destructive endpoint existed: a metadata or token-verification call that reads nothing and changes nothing (list-models, whoami, token-verify, a database SELECT 1). Of the keys we could definitively test this way, 60% were still live, including production PostgreSQL databases, MongoDB clusters, a working Telegram bot, dozens of Google API keys, and paid-tier keys for providers such as Deepgram, ElevenLabs, NVIDIA, and Cerebras. This means that these are not mostly stale strings that merely match a pattern: a majority of the testable keys still grant access today.

All numbers here are lower bounds. Code Search is not a complete index of GitHub; the per-type sample was capped; and the regex, though broad, has recall gaps. The real population is larger.

Leakage by file type

GEMINI.md leaks the most in absolute terms, on both high-value confirmed secrets and the weaker dev/test credentials. But once we normalize by files scanned and count any real credential (confirmed or weak), the per-file rates converge: AGENT.md and QWEN.md edge ahead on this combined rate, while GEMINI.md still carries the highest rate of high-value confirmed keys.

File type Scanned Confirmed Confirmed+weak (Confirmed+weak) / scanned
GEMINI.md 29,609 62 142 0.48%
AGENT.md 14,289 24 99 0.69%
Copilot instructions 15,000 8 79 0.53%
Copilot prompts 15,000 6 23 0.15%
Windsurf rules 9,788 5 11 0.11%
QWEN.md 5,000 3 33 0.66%

The table shows the six most-affected file types; the remaining three scanned types were JetBrains Junie, Roo rules, and .roomodes.

What kind of secrets

Google/Gemini AIza… API keys dominate, unsurprising given the file that leaks most is the one you write for Gemini. But the tail is broad and high-value: OpenAI and Cerebras sk-/csk- keys, Supabase service_role JWTs, production PostgreSQL / MongoDB / MySQL connection strings with inline passwords, Stripe and SendGrid keys, Telegram bot tokens, NVIDIA nvapi- tokens, Cloudflare tunnel tokens, ngrok auth tokens, and Azure OpenAI keys. These are not toy credentials; many grant direct, billable, or data-bearing access.

The agent file is its own hotspot

In two-thirds of the repositories that leaked a credential through an agent file, the key appeared in none of the project's other documentation: no README, changelog, or setup guide repeated it. So the agent file usually isn't a symptom of a project that hard-codes secrets everywhere; it's a specific place developers paste a live key to make the agent work, even when the surrounding docs are clean. Its very purpose, being read verbatim by an AI tool, is what draws the real value in: a placeholder won't function, so the working key goes in and stays. That makes it a distinct, newly significant exposure surface in its own right, not just collateral of careless documentation.

Scope: "other documentation" here means the project's other Markdown/text files, which we scanned for the same credential; it does not include application source or .env files.

It's the humans, not the AI

An obvious hypothesis is that AI coding agents generate these files and paste keys in themselves. The data says otherwise. We blamed each leaked line down to the exact commit that introduced it and checked that commit's metadata for AI-authorship signatures: bot committers, Co-Authored-By trailers naming an agent, "Generated with …" markers. Only ~10% (strong signals) to ~16% (any mention) of the secret-introducing commits carried one.

So these leaks are predominantly hand-typed by people, pasting their own working keys into a file they think of as personal scratch space. (For contrast, a recent study of an AI-skills marketplace found ~72% of its hard-coded-credential cases had AI-authorship signatures, but that is a corpus of machine-generated skills, a different population from ordinary developers editing a repo.)

Why agent instructions files became a leak magnet

Three properties combine:

  • They're new and under-instrumented. GEMINI.md, *.agent.md, and .github/instructions/* barely existed a year ago. Secret-scanning rulesets, .gitignore templates, and code-review habits were tuned for source files and .env, not for these.
  • They're authored as notes, not as code. Teams write and review instruction files with far less rigor than a pull request, precisely because they read like documentation. A key pasted into prose doesn't feel like a key committed to code.
  • They have a direct path into the model. Unlike a .env that an app reads, an agent file exists to be ingested into an agent's context verbatim. The leak and the ingestion are the same act.

Where this sits in the literature

Credential leakage on GitHub is well studied. Meli et al.'s How Bad Can It Git? (NDSS 2019) established the prevalence and the two-pronged Code-Search-plus-BigQuery method we build on. GitGuardian's annual State of Secrets Sprawl operationalizes it at full scale: a real-time census of the entire public commit stream (1.94 billion commits and 28.65 million new secrets in 2025), including a dedicated finding of ~24,000 secrets in MCP configuration files. An academic study of an agent-skills marketplace has likewise quantified credential leakage in bundled skill packages.

Our contribution is orthogonal to all three. In this blog we isolate and rank the agent-instruction-file container itself: which of these brand-new file types developers actually paste live keys into, at what rate, and with what growth. MCP config files are a different container (JSON, not instruction prose); skill marketplaces are a different population. The measurement above fills that gap.

The part source scanning can't see

Everything so far is a story about secrets at rest in a public repository, and the first-line defense is exactly what you'd expect: scan the source, fix the file. But agent-instruction files have a property that pushes the problem past source scanning. Their reason for existing is to be read into a running agent.

That means a key in one of these files does not stay put. Every session, it becomes live context: loaded into the model's prompt, potentially forwarded to a hosted LLM provider, echoed into tool calls, written to logs, and, for agents with memory, persisted into long-term state. Source-side controls, however good, have blind spots along that path:

  • private and internal repositories that public scanners never see;
  • agent files that live only on a developer's machine and are never committed;
  • secrets pasted straight into a live session or accumulated in agent memory;
  • the credential propagating through the running agent's tools and outputs after it has been read.

Catching sensitive information in motion through the agent is a different control from scanning files at rest, and a necessary complement to it.

What developers should do

Practical hygiene for agent files

  • Never put a real value in an agent file: not in config, not in a troubleshooting note, not "as an example." If the agent needs a credential, it should read it from the environment or a secret manager, and the file should say exactly that.
  • Treat agent files as code. Put them through review and the same pre-commit secret scanning as everything else. Add their globs explicitly; many rulesets don't match *.md agent files by default.
  • Watch agent memory. Files that persist an agent's "learned" state can capture a key you handed it mid-session. Review and scrub them.
  • Assume exposure is permanent. A secret pushed to a public repo is compromised the moment it lands; git history and mirrors keep it. Rotate immediately; don't just delete the line.

What security teams should do

Organizational measures

  • Extend secret-scanning coverage to the new file types. Confirm your scanners actually match GEMINI.md, *.agent.md, .github/instructions/*, and editor rule directories, not just source and .env. Coverage tuned a year ago probably doesn't.
  • Inventory where agents ingest self-authored context, and bring those files into DLP and code-scanning scope as a first-class asset class.
  • Acknowledge the at-rest blind spots. Source scanning cannot see private repos, local-only files, live-session pastes, or a credential propagating through a running agent. Plan for a runtime layer that monitors sensitive information as agents actually operate.
  • Rotate and revoke on detection, and measure time-to-rotation; exposed keys stay valid for a long time if no one acts.

Closing the runtime gap

The measurement in this post is about secrets at rest, and the developer and organizational practices above are the right first response. But because agent-instruction files exist to be pulled into a live model, part of this problem lives at runtime, where file scanning cannot reach: the credential is already in the agent's context, memory, and tool traffic.

That runtime layer is where Radware's Agentic AI Protection operates. Using dedicated guardrails it can identify sensitive information as it moves through an agent, on developer host endpoints and in production alike, complementing source-side secret scanning rather than replacing it. The complete defensive posture is to watch both where those credentials sit and where they flow.

References

  • Meli, McNiece, Reaves. How Bad Can It Git? Characterizing Secret Leakage in Public GitHub Repositories. NDSS 2019.
  • GitGuardian. The State of Secrets Sprawl 2026.
  • How Your Credentials Are Leaked by LLM Agent Skills: An Empirical Study. arXiv:2604.03070, 2026.
  • Codacy. We Scanned 34,266 Repos: 1 in 4 Orgs Showed Gaps in AI Agent Config Files. 2026.

As part of responsible disclosure, all findings were reported to the affected repository owners where a contact channel was available.

Zvika Babo & Gabi Nakibly

Contact Radware Sales

Our experts will answer your questions, assess your needs, and help you understand which products are best for your business.

Already a Customer?

We’re ready to help, whether you need support, additional services, or answers to your questions about our products and solutions.

Locations
Get Answers Now from KnowledgeBase
Get Free Online Product Training
Engage with Radware Technical Support
Join the Radware Customer Program

Get Social

Connect with experts and join the conversation about Radware technologies.

Blog
Security Research Center
CyberPedia