Skip to content
Muhammad Moeed

How to Protect API Keys When Using AI Coding Agents

Protect API keys when using AI coding agents. Learn what .gitignore cannot do, how to limit access, and what to do if a secret leaks.

To protect API keys when using AI coding agents, keep real credentials out of the agent’s workspace whenever possible. Give it fake values for coding, limited test credentials when needed, and no production access by default.

An API key is a secret that lets software use a service. For example, your app might use one to send emails. Someone who gets that key may be able to use the service under your account, within the key’s permissions.

An AI coding agent can do more than suggest code. Depending on its permissions, it may read files, run terminal commands, and call other tools. That is why protecting a key means checking what the agent can access, not just what you type in chat.

GitHub’s article on secret protection in agent workflows highlights this growing problem. Here is a practical way to handle it in your own project.

Start with a simple example

Imagine you ask an agent to fix your app’s email feature. Your project contains this file:

# .env.example: a template with no real credentials
EMAIL_API_KEY=replace_with_a_test_key
EMAIL_FROM=hello@example.com

The agent needs to know the variable’s name and how your code uses it. It usually does not need your real email-service key to edit that code.

Start with a fake email client in tests: it records the message instead of sending it. Only use a real test credential when you need to check the connection to the provider.

This keeps an ordinary coding task from becoming a task with access to your live email account.

Does .gitignore protect .env from an AI agent?

No. .gitignore controls which untracked files Git normally ignores. It does not control who can read a file. A terminal command or another tool may still open that file.

For example, this .gitignore keeps common local environment files out of normal Git staging:

.env
.env.*
!.env.example

The last line allows a safe template to be committed. Keep that template free of real secrets.

Check your rules without printing file contents:

git check-ignore -v .env
git ls-files -- .env

The first command shows the matching ignore rule. If the second prints .env, Git already tracks it. Adding an ignore rule does not remove a tracked file or erase an earlier commit. See the Git ignore documentation.

How to protect API keys while the agent works

1. Use a separate development environment

Give the agent a project copy with sample data. Keep production credentials outside that environment. Avoid mounting your entire home folder into an agent’s container.

When an integration needs a real credential, create one for that test environment. Limit its permissions and lifetime where the service supports it. A key that can only send test emails is preferable to one that can also manage your whole account.

These choices follow OWASP’s secrets management guidance: restrict access, manage a secret’s lifetime, and avoid unnecessary copies.

2. Check file permissions and terminal access separately

In Claude Code, file permission rules can block the Read tool from opening sensitive files. For example, merge this into your project’s .claude/settings.json:

{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(.env.*)"
    ]
  }
}

These patterns also block .env.example. If the agent needs variable names, put a secret-free description in your README.

This is one protection layer. Do not assume a Read rule alone isolates everything a shell process can access. Review the Claude Code permission rules for your installed version.

A sandbox limits what a running process can access. Check its actual read and network restrictions: enabling a sandbox does not necessarily hide credential files. Also check whether commands can run outside it. Claude documents these details in its sandbox configuration guide.

3. Keep secrets out of command output

An environment variable is a way to pass configuration to a program. It is not a guarantee that the program, or an agent running it, cannot read the value.

Avoid debugging by printing every environment variable. Log whether a required setting exists instead:

// Run in Node.js. This prints a boolean, not the key.
console.log({ emailKeyConfigured: Boolean(process.env.EMAIL_API_KEY) });

Also check test output, screenshots, error reports, and HTTP logs before sharing them. A key can escape through a log even when it never appears in a commit.

4. Review tool access before enabling it

Treat a new plugin or MCP server as another piece of software with access to your work. Check what it can read, change, and send elsewhere.

For example, a tool that searches documentation should not need permission to change your production database. Start with the smallest set of tools needed for the task. For remote tools, the MCP authentication guide explains how access tokens and permissions work.

Add secret scanning before and after a push

Secret scanning looks for exposed credentials. GitHub can scan repository history and report supported secret types. Feature availability depends on repository type and plan. Check the GitHub secret scanning documentation.

Push protection can stop supported secrets from entering a repository during a push. Enable it where available, and investigate an alert before bypassing it. See GitHub push protection.

These checks are useful backups. They cannot prove that every secret is absent, and they do not undo a key already sent to a chat or external tool.

ProtectionWhat it helps withWhat it does not guarantee
.gitignoreKeeping untracked local files out of normal stagingPreventing file reads
Agent permissionsRestricting particular tool actionsIsolating every subprocess
A configured sandboxRestricting process accessSafety for commands allowed outside it
Limited test credentialsReducing the damage from misusePreventing the credential from leaking
Secret scanningDetecting supported leaked credentialsFinding every possible secret

What should you do if an API key leaks?

Treat an exposed key as compromised. Deleting the message or removing the line from Git does not make the key safe again.

  1. Identify the key and its owner. Record where it appeared without copying the secret into another ticket.
  2. Revoke it through the provider. For an active, public, or production key, act urgently. Coordinate a rapid replacement if immediate revocation would interrupt an essential service.
  3. Update affected applications. Store the replacement in the approved secret store and confirm the applications work.
  4. Review usage and access logs. Look for unexpected activity and charges.
  5. Clean up exposed copies and fix the cause. Check code, logs, and shared messages. Follow your team’s process for Git history cleanup.

This order follows GitHub’s leaked-secret remediation guidance. Removing a copy and revoking its access are different tasks.

Common questions

Can I put an API key in a prompt for a quick test?

Use a placeholder instead. If a test really needs access, arrange a limited test credential through the runtime. Ask the agent to explain the setup without printing the value.

Is a private repository enough?

It limits who can see the repository, but anyone or any tool with access may still encounter a committed key. Keep credentials out of source code in private repositories too.

How can I check my setup safely?

Create a dummy file with a clearly fake value. Test whether the agent’s file tools and terminal can read it under your chosen rules. Do this with fake data, not a production key. Repeat after changing permissions.

For more on connected tools, read the MCP server security guide or browse the AI agents articles.