API 密钥泄露是开发中最常见的安全事故之一。本文讲解如何在使用 Claude Code 开发时, 安全地管理环境变量和各类密钥。
基础原则
❌ 永远不要把密钥写在代码里
❌ 永远不要把 .env 文件提交到 Git
✅ 用环境变量,不用硬编码
✅ .gitignore 里明确排除密钥文件
✅ 生产环境用专门的密钥管理服务
告诉 Claude Code 这些规范
在项目 CLAUDE.md 里写明:
markdown
## 安全规范(强制执行)
### 密钥管理
- 所有密钥和 Token **必须** 从环境变量读取
- 代码里绝对不能出现:sk-、password=、token=、secret= 等明文值
- 新增环境变量时,同步更新 .env.example(不含真实值)
### .gitignore 必须包含
- .env
- .env.local
- .env.*.local
- *.pem, *.key
- secrets/
### 代码示例(正确做法)
```python
import os
API_KEY = os.environ.get("OPENAI_API_KEY")
if not API_KEY:
raise ValueError("OPENAI_API_KEY environment variable not set")
## 项目 .env 文件规范
```bash
# .env.example(提交到 Git 的模板,无真实值)
# 复制为 .env 并填入真实值
# Anthropic
ANTHROPIC_API_KEY=sk-ant-your-key-here
# 数据库
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# 第三方服务
STRIPE_SECRET_KEY=sk_test_your-key-here
SENDGRID_API_KEY=SG.your-key-here
# 应用配置
NODE_ENV=development
PORT=3000
JWT_SECRET=change-this-in-production
bash
# .gitignore(必须包含)
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
*.pem
*.key
secrets/
.secrets在代码中安全读取
Python
python
from dotenv import load_dotenv
import os
load_dotenv() # 读取 .env 文件
ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY")
DATABASE_URL = os.environ.get("DATABASE_URL")
# 启动时验证必要变量
required_vars = ["ANTHROPIC_API_KEY", "DATABASE_URL", "JWT_SECRET"]
missing = [v for v in required_vars if not os.environ.get(v)]
if missing:
raise EnvironmentError(f"Missing required env vars: {', '.join(missing)}")Node.js / TypeScript
typescript
import dotenv from "dotenv";
dotenv.config();
// 带类型的环境变量封装
function getEnv(key: string, required = true): string {
const value = process.env[key];
if (required && !value) {
throw new Error(`Missing required environment variable: ${key}`);
}
return value || "";
}
export const config = {
anthropicKey: getEnv("ANTHROPIC_API_KEY"),
databaseUrl: getEnv("DATABASE_URL"),
jwtSecret: getEnv("JWT_SECRET"),
port: parseInt(getEnv("PORT", false) || "3000"),
};Claude Code 的 Anthropic API Key 配置
bash
# 方式 1:临时设置(当前会话)
export ANTHROPIC_API_KEY="sk-ant-你的key"
claude
# 方式 2:永久设置(推荐)
echo 'export ANTHROPIC_API_KEY="sk-ant-你的key"' >> ~/.bashrc
source ~/.bashrc
# 方式 3:.env 文件(Claude Code 项目使用)
# 在项目根目录创建 .env
echo 'ANTHROPIC_API_KEY=sk-ant-你的key' > .env
# claude 会自动加载当前目录的 .env防止 Claude Code 意外泄露密钥
在 CLAUDE.md 中明确指示:
markdown
## 禁止行为
1. 不要在任何输出中打印环境变量的值
2. 不要在日志里记录 API Key(即使是调试日志)
3. 不要把 .env 内容复制到代码注释里
4. 生成的代码示例要用占位符,不用真实值:
- 正确:`API_KEY = os.environ.get("OPENAI_API_KEY")`
- 错误:`API_KEY = "sk-abc123..."`已泄露密钥的应急处理
如果密钥意外提交到 Git:
bash
# 1. 立刻吊销泄露的密钥(去对应服务的控制台)
# 2. 从 Git 历史中删除(git-filter-repo 方法)
pip install git-filter-repo
git filter-repo --path .env --invert-paths
# 3. 强制推送(需要团队协调)
git push --force
# 4. 通知所有有仓库克隆的人重新 clone重要:删除 Git 历史不等于安全,因为如果仓库是公开的, 可能已被 GitHub 的密钥扫描系统或爬虫记录。必须先吊销密钥。
生产环境密钥管理
AWS Secrets Manager
python
import boto3, json
def get_secret(secret_name, region="us-east-1"):
client = boto3.client("secretsmanager", region_name=region)
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response["SecretString"])
# 使用
secrets = get_secret("my-app/production")
API_KEY = secrets["ANTHROPIC_API_KEY"]GitHub Actions Secrets(CI/CD)
yaml
# .github/workflows/deploy.yml
jobs:
deploy:
steps:
- name: Run with secrets
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: |
claude -p "Run production checks" --no-interactive密钥扫描(Pre-commit Hook)
bash
# 安装 detect-secrets
pip install detect-secrets
# 初始化基准
detect-secrets scan > .secrets.baseline
# 添加 pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
detect-secrets-hook --baseline .secrets.baseline
EOF
chmod +x .git/hooks/pre-commit以后每次 git commit 都会自动扫描,发现密钥会阻止提交。
来源:Claude Code Settings - Anthropic 官方文档