Bug

API key pasted into the code

把 API 密钥直接写进代码

The agent inlines a credential (from an example, a test, or something you pasted in chat) into source code, and it gets committed.

Applies to: Claude Code · Cursor · Codex · Copilot agent

Symptom

`const key = "sk-..."` in a source file, a token in a config committed to git, or a `.env` file added to the repo.

Why it happens

To an agent, a key is just a string that makes the example work. agent-review lists AR018 "Hardcoded credential" as Critical; developertoolkit.ai's security class puts the control in CI (secret scanning).

Example

From the agent-review taxonomy (AR018).

ts
const key = "sk-proj-abc123def456...";

Copy-paste fixes

Pick the files for the agents you use. Snippets are in English so they work in any repo.

Rules

Claude Code: add to CLAUDE.md

CLAUDE.md
## Secrets never go in code
- Read credentials from environment variables or the project's secret manager. Never write a real
  key, token or password into source, tests, docs or config, even temporarily.
- If the user pastes a secret into chat, do not copy it into any file. Reference an env var name
  instead and tell them where to set it.
- Never `git add` `.env*` files. Check `git diff --cached` for secrets before committing.
Rules

Codex, Copilot coding agent and others: add to AGENTS.md

AGENTS.md
## Secrets never go in code
- Read credentials from environment variables or the project's secret manager. Never write a real
  key, token or password into source, tests, docs or config, even temporarily.
- If the user pastes a secret into chat, do not copy it into any file. Reference an env var name
  instead and tell them where to set it.
- Never `git add` `.env*` files. Check `git diff --cached` for secrets before committing.
Cursor rule

Cursor: project rule

.cursor/rules/hardcoded-secret.mdc
---
description: "AgentFails: API key pasted into the code"
alwaysApply: true
---

## Secrets never go in code
- Read credentials from environment variables or the project's secret manager. Never write a real
  key, token or password into source, tests, docs or config, even temporarily.
- If the user pastes a secret into chat, do not copy it into any file. Reference an env var name
  instead and tell them where to set it.
- Never `git add` `.env*` files. Check `git diff --cached` for secrets before committing.
Settings

Claude Code permissions: hard-deny sensitive paths, ask before installs

Rules in CLAUDE.md are context; permission rules are enforced by the tool. Adjust the paths to your repo.

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Edit(./migrations/**)",
      "Edit(./.env*)",
      "Edit(./package-lock.json)",
      "Edit(./pnpm-lock.yaml)",
      "Edit(./src/generated/**)"
    ],
    "ask": [
      "Bash(npm install:*)",
      "Bash(pnpm add:*)",
      "Bash(yarn add:*)",
      "Bash(pip install:*)",
      "Bash(git push:*)"
    ]
  }
}
CI / script

Secret scanning in CI (gitleaks)

.github/workflows/gitleaks.yml
name: gitleaks
on: [pull_request, push]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Sources and credit

Related patterns

翻车 of the week

One real agent failure and its fix, every week. Free, short, no spam.