503 权限与安全管理
API Key 分级管理、敏感数据保护和合规审计
学习目标
完成本课程后,你将能够:
一、API Key 分级管理
三级权限体系
| 级别 | 权限范围 | 使用场景 | Key 管理 |
|---|---|---|---|
| Admin | 全部项目、全部命令 | 团队负责人、架构师 | 严格管控 |
| Developer | 指定项目、常用命令 | 日常开发 | 按项目分配 |
| Viewer | 只读、审查 | Code Review、审计 | 可较宽松 |
环境变量管理
API Key 管理原则:
1. 永远不提交到代码仓库
2. 开发环境每人独立 Key
3. CI/CD 使用专用 Service Key
4. 定期轮换(每 90 天)
5. 离职立即吊销.gitignore 配置
# 敏感文件
.env
.env.local
.env.*.local
*.pem
*.key
credentials.json
service-account.json
# 但保留示例文件
!.env.example.env.example 模板
# .env.example — 环境变量说明
# === Codex ===
# 获取地址:https://platform.openai.com/api-keys
CODEX_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
# === 数据库 ===
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# === Redis ===
REDIS_URL=redis://localhost:6379
# === JWT ===
# 生成命令:openssl rand -base64 64
JWT_SECRET=your-256-bit-secret-here
# === 第三方服务 ===
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
S3_BUCKET=your-bucket-name
# === 日志级别 ===
# 可选:trace | debug | info | warn | error | fatal
LOG_LEVEL=info二、敏感数据保护
数据分级
| 级别 | 示例 | 存储 | 传输 | 日志 |
|---|---|---|---|---|
| L1 公开 | 产品名称、新闻 | 明文 | HTTP | 可记录 |
| L2 内部 | 项目代码、架构图 | 明文 | HTTPS | 脱敏后 |
| L3 机密 | 用户手机号、邮箱 | 加密 | HTTPS | 禁止 |
| L4 绝密 | 密码、Token、Key | 哈希/加密 | HTTPS | 禁止 |
数据脱敏实现
// backend/src/utils/mask.ts
/** 手机号脱敏:138****1234 */
export function maskPhone(phone: string): string {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
/** 邮箱脱敏:t***@example.com */
export function maskEmail(email: string): string {
const [name, domain] = email.split('@');
return `${name[0]}***@${domain}`;
}
/** 身份证脱敏:320***********1234 */
export function maskIdCard(id: string): string {
return id.replace(/(\d{4})\d{10}(\d{4})/, '$1**********$2');
}
/** JSON 递归脱敏 */
export function maskSensitiveData(obj: any, sensitiveFields: string[]): any {
if (typeof obj !== 'object' || obj === null) return obj;
const masked = Array.isArray(obj) ? [...obj] : { ...obj };
for (const key in masked) {
if (sensitiveFields.includes(key)) {
masked[key] = '***REDACTED***';
} else if (typeof masked[key] === 'object') {
masked[key] = maskSensitiveData(masked[key], sensitiveFields);
}
}
return masked;
}日志脱敏集成
// 在 logger 中集成脱敏
export const logger = pino({
serializers: {
req: (req) => ({
method: req.method,
url: req.url,
userId: req.user?.id,
// 自动脱敏敏感请求体
body: maskSensitiveData(req.body, [
'password', 'token', 'secret',
'phone', 'email', 'idCard'
]),
}),
},
});三、审计日志
审计日志设计
// backend/src/services/audit.service.ts
interface AuditLog {
id: string;
userId: string;
action: string; // 例如:task.create, user.login
resource: string; // 例如:task:clx123, user:clx456
details: Record<string, unknown>;
ip: string;
userAgent: string;
timestamp: Date;
result: 'success' | 'failure';
}
async function logAction(log: Omit<AuditLog, 'id' | 'timestamp'>) {
await prisma.auditLog.create({
data: {
...log,
details: maskSensitiveData(log.details, ['password']),
},
});
}必须审计的操作
必须记录的操作类型:
- 用户认证:登录、注册、密码修改、Token 刷新
- 敏感数据:查看/修改用户个人信息
- 权限变更:角色修改、权限赋予/撤销
- 数据删除:任何 DELETE 操作
- 配置变更:系统设置修改
- 导出操作:数据批量导出
审计日志保留期:
- 在线查询:90 天
- 归档存储:3 年(合规要求)审计中间件
// backend/src/middleware/audit.ts
export function audit(action: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const startTime = Date.now();
// 捕获响应
const originalJson = res.json.bind(res);
res.json = function (body: any) {
res.locals.responseBody = body;
return originalJson(body);
};
res.on('finish', () => {
AuditService.log({
userId: req.user?.id || 'anonymous',
action,
resource: `${req.baseUrl}${req.path}`,
details: {
method: req.method,
statusCode: res.statusCode,
duration: Date.now() - startTime,
},
ip: req.ip,
userAgent: req.get('user-agent') || '',
result: res.statusCode < 400 ? 'success' : 'failure',
}).catch(console.error);
});
next();
};
}
// 使用
router.delete('/tasks/:id', audit('task.delete'), TaskController.delete);四、合规检查清单
安全合规检查表
## 企业安全合规检查清单
### 访问控制
- [ ] 所有 API 需要认证(公开接口除外)
- [ ] 使用 JWT + 刷新 Token 双 Token 机制
- [ ] 敏感操作需要二次验证(2FA)
- [ ] 会话超时时间为 30 分钟
- [ ] 密码复杂度:至少 8 位,包含大小写+数字+特殊字符
### 数据传输
- [ ] 生产环境强制 HTTPS
- [ ] API 响应包含安全头(Helmet)
- [ ] CORS 白名单配置
- [ ] WebSocket 使用 WSS
### 数据存储
- [ ] 密码使用 bcrypt 哈希(cost >= 12)
- [ ] 个人敏感数据加密存储(AES-256-GCM)
- [ ] 数据库连接使用 TLS
- [ ] 备份文件加密存储
### 依赖安全
- [ ] 启用 Dependabot 自动更新
- [ ] 每周运行 npm audit
- [ ] 使用 package-lock.json 锁定版本
- [ ] 私有包使用 npm private registry
### 其他
- [ ] 错误信息不泄露内部实现
- [ ] 文件上传类型和大小限制
- [ ] 速率限制(Rate Limiting)
- [ ] 定期渗透测试五、实战练习
练习 1:配置环境变量管理
为团队项目配置:
- .env.example 模板文件
- 开发/预发布/生产三套环境变量
- CI/CD Secret 管理
- 密钥轮换脚本练习 2:实现审计日志
请为你的项目实现审计日志功能:
- 敏感操作自动记录
- 日志查询和导出
- 数据脱敏
- 异常行为告警练习 3:安全自查
/review 请对当前项目进行安全审查,对照合规检查清单逐项输出结果六、本课总结
**核心要点:**
- API Key 按角色分级,Admin/Developer/Viewer 权限递减
- 敏感数据四层分级:公开/内部/机密/绝密,不同级别不同保护
- 审计日志记录「谁在什么时间对什么资源做了什么操作」
- 日志中敏感字段必须脱敏,避免二次泄露
- 合规检查清单要纳入 CI/CD,每次部署前自动验证
**下一步:** 模块 504 — 绩效评估体系