把 API 密钥直接写进代码
API key pasted into the code
智能体把凭据(来自示例、测试,或你在聊天里贴的内容)直接写进源码,然后被提交了。
适用于: Claude Code · Cursor · Codex · Copilot agent
症状
源文件里出现 `const key = "sk-..."`、提交进 git 的配置里有 token,或 `.env` 被加进了仓库。
为什么会这样
在智能体眼里,密钥只是一个能让示例跑起来的字符串。agent-review 把 AR018“硬编码凭据”列为最高严重级;developertoolkit.ai 的安全类别把控制点放在 CI(密钥扫描)。
示例
摘自 agent-review 分类(AR018)。
tsconst key = "sk-proj-abc123def456...";
复制即用的修复
按你用的智能体挑选文件。规则片段用英文写,放进任何仓库都能用。
规则
Claude Code:加入 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 编码智能体等:加入 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 规则
Cursor:项目规则
.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 权限:硬性禁止敏感路径,安装依赖前先询问
CLAUDE.md 里的规则只是上下文;权限规则由工具强制执行。按你的仓库调整路径。
.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 / 脚本
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 }}