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).
tsconst 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.
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.
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: 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.
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:*)"
]
}
}
Secret scanning in CI (gitleaks)
.github/workflows/gitleaks.ymlname: 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 }}