Keep your keys out of the code.

Where keys escape, five habits that keep them in, and a first-hour plan for the day one gets out anyway.

A bunch of keys on a ring lying on a wooden table
Photo by Filip Szalbot on Unsplashdithered by Cyborb

To keep API keys safe, keep them out of your code entirely. Store them in environment variables or a secret manager, add .env to .gitignore before your first commit, never ship a secret key to the browser, and let GitHub’s push protection block anything that slips through. If a key does leak, revoke it first and clean up second.

Coding with AI adds two new ways to leak: assistants that paste a key straight into a file, and agents that read your keys into their context. Good API key security covers both, and it takes an afternoon to set up.

The short version
  • Treat a key that reaches a public repository as stolen, even if you delete it a minute later.
  • Keep keys in environment variables or a secret manager, and ignore .env files from the first commit.
  • Anything sent to a browser is public. Secret keys belong on a server.
  • Give AI agents scoped, low-limit development keys, and never paste production keys into a chat.
  • After a leak: revoke, check usage, replace, then clean up history. In that order.

How API keys actually leak

Most leaks are not hacks. They are copies: a key ends up somewhere it was never meant to be, and someone else reads it. GitGuardian monitors public GitHub commits, and its latest yearly report shows the scale.

28.65M
new hardcoded secrets in public GitHub commits in 2025
GitGuardian, March 2026
81%
yearly rise in leaked AI service keys, to about 1.28 million
GitGuardian, March 2026
64%
of valid secrets found in 2022 were still valid in January 2026
GitGuardian, March 2026

The last number matters most. Leaked keys often stay live for years because nobody rotates them.

Here are the common paths, and the fix for each.

Leak pathHow it happensThe fix
Committed .env fileThe file was committed before anyone ignored itIgnore it before the first commit
Hardcoded in sourceYou pasted a key into a chat and the assistant wrote it into a fileGive the agent the variable name, never the value
Browser bundleThe key sits in front-end code or a public build variableCall the API from a server route
Logs and error outputDebug code prints headers, config or the whole environmentLog the key’s name, never its value
Agent contextAn agent reads .env while debugging, and the key lands in the transcriptBlock .env from the agent and use a limited dev key
Tickets, chats and screenshotsA key pasted into an issue, a team chat or a screen recordingShare a secret manager link instead

AI tooling adds its own files to the list. The same report found 24,008 unique secrets in MCP configuration files, the files that connect agents to tools. It also found that commits made with Claude Code’s help leaked secrets at a 3.2% rate, against 1.5% for all public commits. That does not prove the tool caused the leaks. It does show that AI help alone does not keep keys out.

Why a deleted key is still a leaked key

Automated scanners copy public repositories around the clock. In 2023, Palo Alto Networks’ Unit 42 watched one campaign find exposed AWS keys on GitHub and start using them within five minutes, to run crypto-mining machines on the victim’s bill.

Deleting the commit does not undo that. Copies live on in clones, forks and caches, and GitHub’s own guide warns that you cannot remove data from other people’s clones or from forks. The only fix that works everywhere at once is making the key useless.

Five habits for API key security

  1. Keep keys in the environment, not the code

    Your code reads a key by name, and the value lives outside the repository: in a local .env file for development, and in your host’s secret settings for production. Ignore the file before your first commit, and commit an example file that lists names without values.

    .gitignore
    .env
    .env.*
    !.env.example

    If .env was committed before you ignored it, git keeps tracking it anyway. Run git rm --cached .env, commit, and rotate every key the file ever held, because old commits still contain them.

  2. Never ship a secret key to the browser

    Everything a browser downloads, anyone can read. Next.js inlines any variable that starts with NEXT_PUBLIC_ into the JavaScript it sends to visitors, and Vite does the same with VITE_. Vite’s docs say plainly that these variables should not hold API keys.

    The fix is a small server route that holds the key and calls the API for the page. Put a login check or a rate limit on that route too, or anyone can spend your credits through it.

  3. Use scoped, short-lived keys

    Create one key per project and per environment, so a leak stays small. Give each key the fewest permissions that work. On GitHub, a fine-grained personal access token can be limited to specific repositories and given an expiry date, and GitHub recommends it over the classic kind. Where your AI provider offers a spending limit or budget alert, turn it on.

  4. Turn on push protection and a local scanner

    Push protection blocks a push when it detects a secret, before the secret lands. It is on by default for your personal account when you push to public repositories. For private repositories, it needs GitHub Secret Protection, a paid add-on. A free local scanner is a good second net:

    Terminal
    # Scan every commit in this repository for secrets
    gitleaks git -v .

    Gitleaks can also run as a pre-commit hook, so a commit containing a key never gets made. If push protection blocks you, do not bypass it out of habit: bypassing on a public repository publishes the key.

  5. Keep keys out of your agent’s context

    Anything a cloud-based agent reads goes to the model provider, and usually into a saved session transcript as well. What happens to it next depends on the provider. So tell the agent the variable name, not the value, and block it from reading .env files. In Claude Code that is a deny rule in its settings file. Cursor ignores .env files by default.

    .claude/settings.json
    {
      "permissions": {
        "deny": ["Read(./.env)", "Read(./.env.*)"]
      }
    }

    These rules are guardrails, not vaults. Claude Code’s docs say a script that opens files itself is not covered, and Cursor’s docs say the agent’s terminal and MCP tools can still reach ignored files. On a machine where an agent runs, keep only development keys with low limits. The same applies in CI, where an agent running in your pipeline needs its secrets scoped just as tightly.

Paste rules like these into your agent’s project instructions, so it follows them in every session:

PromptSecret-handling rules for your agent
Follow these rules for secrets in this project:
1. Never write an API key, token or password into a source file, test, log line or commit.
2. Read secrets from environment variables. If one is missing, stop and tell me its name.
3. Never open, print or copy .env files. Use .env.example to learn the variable names.
4. Never send a secret to the browser. Calls that need a secret key go through a server route.
5. If you see a secret in code or in command output, stop and tell me where it is.

For the wider question of what an agent can reach on your machine, see whether it is safe to let AI control your computer.

What to do in the first hour after a leak

Speed matters more than tidiness. Work through these in order, and do not start with git.

  1. Revoke or rotate the key

    Go to the provider’s dashboard and revoke the key, or rotate it if other systems depend on it. GitHub’s guide puts this first, because a dead key is harmless wherever it was copied.

  2. Check what it was used for

    Open the provider’s usage, billing and audit logs for the time the key was exposed. Look for requests, spend or new resources you do not recognize, such as unexpected cloud machines.

  3. Put the new key where it belongs

    Store the replacement in your host’s secret settings or your secret manager, redeploy, and confirm the app still works.

  4. Clean up the code and, if needed, the history

    Remove the key from the code. Rewriting history is optional once the key is dead, and it has costs: every later commit hash changes, and copies in forks and clones stay out of reach. If you do it, GitHub recommends git filter-repo, and GitHub Support can clear cached views.

  5. Close the gap and tell people

    Find the path the key took and fix it with the habits above. If the key could reach a client’s or user’s data, tell them what happened.

A checklist for every project

API key hygiene0 of 7

AI-written code has other weak spots besides keys. Our checklist for securing AI-generated code covers the rest.

FAQ

Is it safe to keep API keys in a .env file?

For development, yes, as long as the file is in .gitignore. It is plain text on your disk, so it prevents accidental commits, not theft by anything that can read your files. Production keys belong in your host’s secret settings or a secret manager.

Can I hide an API key in front-end code?

No. Minifying, encoding or splitting the key does not help, because the browser needs the real value to use it. Put the call behind a server route. Some keys are designed to be public, such as Stripe’s publishable key, and the provider’s docs say which ones.

Does GitHub scan private repositories for secrets?

Only with GitHub Secret Protection, a paid add-on for GitHub Team and Enterprise Cloud. Public repositories are scanned for free, automatically. Organizations can also run a free report that scans their code for leaked secrets.

Should I give my AI coding agent my API keys?

Give it only what it needs to run the project locally: a development key with low limits, read from an environment variable. Never paste a production key into a chat, where it becomes part of the conversation history.

Key takeaways
  • Keys belong in environment variables or a secret manager, never in code or in the browser.
  • Scoped keys with limits turn a leak from a disaster into a chore.
  • Push protection and a local scanner catch what habits miss.
  • Give agents variable names and development keys, and block them from .env files.
  • After a leak, revoke first. Cleaning up history comes last, if at all.

Read next: how to secure the code your agent writes, and how prompt injection can turn an agent against you.

Sources
  1. The State of Secrets Sprawl 2026, GitGuardian, March 2026
  2. CloudKeys in the air: tracking malicious operations of exposed IAM keys, Palo Alto Networks Unit 42, October 2023
  3. Push protection, GitHub Docs
  4. Secret scanning, GitHub Docs
  5. Removing sensitive data from a repository, GitHub Docs
  6. Managing your personal access tokens, GitHub Docs
  7. How to use environment variables in Next.js, Next.js, August 2026
  8. Env variables and modes, Vite
  9. Configure permissions, Claude Code Docs
  10. Ignore file, Cursor Docs
  11. Gitleaks, Gitleaks on GitHub
cyborb.ai

Stop reading about it. Build it.

Describe what you want in plain words. Cyborb plans the work, writes and runs the code, makes the assets, and puts the result online.

Download Cyborb

Free to start. No card required.