security-compliance-officer
Skill4 starsChanged 8 months agoMITView on GitHub
AI Agent 安全合规专家 - 权限分级、PII 保护、策略执行、安全审计、合规检查、denial tracking
- Reads credentials
In this repository14 other files it gives its agents.
- agent-architectSkill
- context-engineerSkill
- debug-diagnosticianSkill
- error-handling-specialistSkill
- harness-engineerSkill
- mcp-integration-specialistSkill
- performance-optimizerSkill
- prompt-engineerSkill
- skill-developerSkill
- state-management-engineerSkill
- testing-quality-assurance-engineerSkill
- tool-integratorSkill
- ui-component-architectSkill
- verification-engineerSkill
The file
Files
Security Compliance Officer
使用此技能当你需要进行安全合规系统设计、权限控制实现、PII 保护机制开发、或安全审计流程建立。
目标
产出完整的安全合规方案,包括权限分级系统、PII 保护机制、策略执行引擎、安全审计日志和合规检查清单。
核心能力
1. 权限模式系统 (src/utils/permissions/PermissionMode.ts)
Claude Code定义了 6 种权限模式:
export const PERMISSION_MODES = [
'default', // 标准审批流程
'plan', // 计划模式(只读)
'acceptEdits', // 自动接受编辑
'bypassPermissions', // 绕过权限(危险)
'dontAsk', // 不询问(全部允许)
'auto', // 自动模式(ant-only)
] as const
export const EXTERNAL_PERMISSION_MODES = [
'default',
'plan',
'acceptEdits',
'bypassPermissions',
'dontAsk',
] as const
export type PermissionMode = typeof PERMISSION_MODES[number]
export type ExternalPermissionMode = typeof EXTERNAL_PERMISSION_MODES[number]
interface PermissionModeConfig {
title: string
shortTitle: string
symbol: string
color: ModeColorKey
external: ExternalPermissionMode
}
const PERMISSION_MODE_CONFIG: Partial<Record<PermissionMode, PermissionModeConfig>> = {
default: {
title: 'Default',
shortTitle: 'Default',
symbol: '',
color: 'text',
external: 'default',
},
plan: {
title: 'Plan Mode',
shortTitle: 'Plan',
symbol: '⏸️',
color: 'planMode',
external: 'plan',
},
acceptEdits: {
title: 'Accept edits',
shortTitle: 'Accept',
symbol: '⏩',
color: 'autoAccept',
external: 'acceptEdits',
},
bypassPermissions: {
title: 'Bypass Permissions',
shortTitle: 'Bypass',
symbol: '⏩',
color: 'error',
external: 'bypassPermissions',
},
dontAsk: {
title: "Don't Ask",
shortTitle: 'DontAsk',
symbol: '⏩',
color: 'error',
external: 'dontAsk',
},
...(feature('TRANSCRIPT_CLASSIFIER')
? {
auto: {
title: 'Auto mode',
shortTitle: 'Auto',
symbol: '⏩',
color: 'warning',
external: 'default',
},
}
: {}),
}权限模式对比:
| 模式 | 文件读取 | 文件写入 | Shell 执行 | 适用场景 |
| default | ✅ | ⚠️ 询问 | ⚠️ 询问 | 日常开发 |
| plan | ✅ | ❌ | 代码审查、学习 | |
| acceptEdits | ✅ | ✅ 自动 | ⚠️ 询问 | 信任的自动化任务 |
| bypassPermissions | ✅ | ✅ | ✅ | 完全信任(危险!) |
| dontAsk | ✅ | ✅ | ✅ | 无人值守任务 |
| auto | ✅ | 🤖 AI 决定 | 🤖 AI 决定 | 高级用户(ant-only) |
2. 权限规则系统
interface PermissionRule {
id: string
pattern: string // Glob pattern for file paths
effect: 'allow' | 'deny'
tools?: string[] // Specific tools this rule applies to
reason?: string // Human-readable explanation
createdAt: number
updatedAt: number
}
/**
* Check if a tool can be used with current permissions
*/
export async function canUseTool(
toolName: string,
input: Record<string, unknown>,
permissionContext: {
mode: PermissionMode
rules: PermissionRule[]
}
): Promise<PermissionResult> {
const { mode, rules } = permissionContext
// Bypass permissions mode - allow everything
if (mode === 'bypassPermissions') {
return { status: 'approved' }
}
// Don't Ask mode - allow everything
if (mode === 'dontAsk') {
return { status: 'approved' }
}
// Plan Mode - read/search/list only
if (mode === 'plan') {
const classification = classifyMcpToolForCollapse(toolName, '', {})
if (classification === 'read' || classification === 'search' || classification === 'list') {
return { status: 'approved' }
}
return {
status: 'denied',
reason: 'Plan mode only allows read/search/list operations'
}
}
// Default/Auto mode - check rules
for (const rule of rules) {
if (ruleMatches(rule, toolName, input)) {
if (rule.effect === 'allow') {
return { status: 'approved' }
} else {
return {
status: 'denied',
reason: rule.reason || 'Blocked by permission rule'
}
}
}
}
// No matching rule - ask user
return {
status: 'ask_user',
prompt: `Allow ${toolName} with arguments: ${JSON.stringify(input)}?`
}
}
/**
* Check if a rule matches the given tool and input
*/
function ruleMatches(
rule: PermissionRule,
toolName: string,
input: Record<string, unknown>
): boolean {
// Check tool filter
if (rule.tools && !rule.tools.includes(toolName)) {
return false
}
// Check file path pattern
if (rule.pattern) {
const filePath = input.path as string | undefined
if (!filePath) return false
return picomatch.isMatch(filePath, rule.pattern)
}
return true
}3. PII 保护系统
/**
* Types of PII to detect and redact
*/
type PIICategory =
| 'email' // Email addresses
| 'phone' // Phone numbers
| 'ssn' // Social Security Numbers
| 'credit_card' // Credit card numbers
| 'api_key' // API keys and tokens
| 'password' // Passwords
| 'home_path' // User home directory paths
| 'ip_address' // IP addresses
| 'aws_credentials' // AWS access keys
| 'github_token' // GitHub personal access tokens
/**
* PII detection patterns
*/
const PII_PATTERNS: Record<PIICategory, RegExp> = {
email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
phone: /\+?[1-9]\d{1,14}(?:\s|-|\.)/g,
ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
credit_card: /\b(?:\d{4}[- ]?){3}\d{4}\b/g,
api_key: /\b(sk-[a-zA-Z0-9]{32,})\b/g,
password: /(?:"password"|"passwd"|"pwd")\s*[:=]\s*"[^"]+"/gi,
home_path: new RegExp(`\\b/Users/[^/\\]+/|\$/HOME/|/home/[^/]+/`, 'g'),
ip_address: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
aws_credentials: /\b(AKIA[0-9A-Z]{16})\b/g,
github_token: /\b(ghp_[a-zA-Z0-9]{36})\b/g,
}
/**
* Redact PII from text
*/
export function redactPII(text: string, categories?: PIICategory[]): string {
const cats = categories || Object.keys(PII_PATTERNS) as PIICategory[]
let result = text
for (const category of cats) {
const pattern = PII_PATTERNS[category]
const replacement = `[REDACTED_${category.toUpperCase()}]`
result = result.replace(pattern, replacement)
}
return result
}
/**
* Sanitize object for logging (deep PII removal)
*/
export function sanitizeObjectForLogging(obj: unknown): unknown {
if (typeof obj === 'string') {
return redactPII(obj)
}
if (Array.isArray(obj)) {
return obj.map(item => sanitizeObjectForLogging(item))
}
if (obj !== null && typeof obj === 'object') {
const sanitized: Record<string, unknown> = {}
for (const [key, value] of Object.entries(obj)) {
// Skip sensitive keys entirely
if (['password', 'secret', 'token', 'apiKey', 'credential'].includes(key.toLowerCase())) {
sanitized[key] = '[REDACTED_SENSITIVE_KEY]'
} else {
sanitized[key] = sanitizeObjectForLogging(value)
}
}
return sanitized
}
return obj
}
/**
* Log diagnostic information without PII
*/
export function logForDiagnosticsNoPII(
level: 'info' | 'warn' | 'error',
event: string,
metadata?: Record<string, unknown>
): void {
const sanitized = sanitizeObjectForLogging(metadata || {})
const timestamp = new Date().toISOString()
const logFn = level === 'error' ? console.error :
level === 'warn' ? console.warn :
console.log
logFn(`[${timestamp}] [${level.toUpperCase()}] ${event}`, sanitized)
}4. Denial Tracking System
interface DeniedAction {
id: string
timestamp: number
toolName: string
input: Record<string, unknown>
reason: string
mode: PermissionMode
userId?: string
}
class DenialTracker {
private denials: DeniedAction[] = []
private readonly MAX_HISTORY = 1000
/**
* Track a denied action
*/
track(action: Omit<DeniedAction, 'id' | 'timestamp'>): void {
const denial: DeniedAction = {
...action,
id: generateId('denial'),
timestamp: Date.now()
}
this.denials.push(denial)
// Keep only recent history
if (this.denials.length > this.MAX_HISTORY) {
this.denials.shift()
}
// Alert on suspicious patterns
this.detectSuspiciousPatterns()
}
/**
* Detect suspicious denial patterns
*/
private detectSuspiciousPatterns(): void {
const recentWindow = 5 * 60 * 1000 // 5 minutes
const now = Date.now()
const recentDenials = this.denials.filter(
d => now - d.timestamp < recentWindow
)
// Too many denials in short time
if (recentDenials.length > 20) {
logForDiagnosticsNoPII('warn', 'suspicious_denial_pattern', {
count: recentDenials.length,
window_minutes: 5,
possible_cause: 'User may be stuck in denial loop'
})
}
// Same tool denied repeatedly
const toolCounts = new Map<string, number>()
for (const denial of recentDenials) {
const count = toolCounts.get(denial.toolName) || 0
toolCounts.set(denial.toolName, count + 1)
}
for (const [tool, count] of toolCounts.entries()) {
if (count > 10) {
logForDiagnosticsNoPII('warn', 'repeated_tool_denial', {
tool,
count,
suggestion: 'Consider adjusting permission rules'
})
}
}
}
/**
* Get denial statistics
*/
getStatistics(period: number = 24 * 60 * 60 * 1000): {
total: number
byTool: Map<string, number>
byReason: Map<string, number>
trend: 'increasing' | 'stable' | 'decreasing'
} {
const cutoff = Date.now() - period
const recent = this.denials.filter(d => d.timestamp > cutoff)
const byTool = new Map<string, number>()
const byReason = new Map<string, number>()
for (const denial of recent) {
const toolCount = byTool.get(denial.toolName) || 0
byTool.set(denial.toolName, toolCount + 1)
const reasonCount = byReason.get(denial.reason) || 0
byReason.set(denial.reason, reasonCount + 1)
}
// Calculate trend (compare first half vs second half of period)
const midpoint = cutoff + period / 2
const firstHalf = recent.filter(d => d.timestamp < midpoint).length
const secondHalf = recent.filter(d => d.timestamp >= midpoint).length
const trend = secondHalf > firstHalf * 1.2 ? 'increasing' :
secondHalf < firstHalf * 0.8 ? 'decreasing' :
'stable'
return {
total: recent.length,
byTool,
byReason,
trend
}
}
/**
* Export denial report
*/
exportReport(): string {
const stats = this.getStatistics()
return `
Denial Report (Last 24h)
========================
Total Denials: ${stats.total}
Trend: ${stats.trend.toUpperCase()}
By Tool:
${Array.from(stats.byTool.entries())
.map(([tool, count]) => ` ${tool}: ${count}`)
.join('\n')}
By Reason:
${Array.from(stats.byReason.entries())
.map(([reason, count]) => ` ${reason}: ${count}`)
.join('\n')}
`
}
}
export const denialTracker = new DenialTracker()5. 安全审计日志
interface AuditLogEntry {
id: string
timestamp: number
eventType: 'tool_use' | 'permission_change' | 'config_change' | 'auth_event'
actor: {
userId: string
sessionId: string
ipAddress?: string
}
action: string
resource?: string
outcome: 'success' | 'failure' | 'denied'
details?: Record<string, unknown>
riskScore?: number // 0-100
}
class SecurityAuditor {
private logs: AuditLogEntry[] = []
private readonly RETENTION_DAYS = 90
/**
* Log a security-relevant event
*/
log(event: Omit<AuditLogEntry, 'id' | 'timestamp'>): void {
const entry: AuditLogEntry = {
...event,
id: generateId('audit'),
timestamp: Date.now()
}
this.logs.push(entry)
// Auto-cleanup old entries
this.cleanupOldEntries()
// Alert on high-risk events
if (event.riskScore && event.riskScore > 80) {
this.alertHighRiskEvent(entry)
}
}
/**
* Query audit logs
*/
query(filters: {
startTime?: number
endTime?: number
eventType?: AuditLogEntry['eventType']
actor?: string
outcome?: AuditLogEntry['outcome']
minRiskScore?: number
}): AuditLogEntry[] {
return this.logs.filter(entry => {
if (filters.startTime && entry.timestamp < filters.startTime) return false
if (filters.endTime && entry.timestamp > filters.endTime) return false
if (filters.eventType && entry.eventType !== filters.eventType) return false
if (filters.actor && entry.actor.userId !== filters.actor) return false
if (filters.outcome && entry.outcome !== filters.outcome) return false
if (filters.minRiskScore && (entry.riskScore || 0) < filters.minRiskScore) return false
return true
})
}
/**
* Generate compliance report
*/
generateComplianceReport(standard: 'SOC2' | 'GDPR' | 'HIPAA'): string {
const period = 90 * 24 * 60 * 60 * 1000 // 90 days
const recentLogs = this.query({ startTime: Date.now() - period })
const report = {
standard,
generatedAt: new Date().toISOString(),
period: 'Last 90 days',
summary: {
totalEvents: recentLogs.length,
securityEvents: recentLogs.filter(e => e.riskScore && e.riskScore > 50).length,
deniedActions: recentLogs.filter(e => e.outcome === 'denied').length,
authFailures: recentLogs.filter(e => e.eventType === 'auth_event' && e.outcome === 'failure').length
},
recommendations: this.generateRecommendations(recentLogs, standard)
}
return JSON.stringify(report, null, 2)
}
private cleanupOldEntries(): void {
const cutoff = Date.now() - (this.RETENTION_DAYS * 24 * 60 * 60 * 1000)
this.logs = this.logs.filter(entry => entry.timestamp > cutoff)
}
private alertHighRiskEvent(entry: AuditLogEntry): void {
console.error('[SECURITY ALERT] High-risk event detected:', {
eventId: entry.id,
type: entry.eventType,
action: entry.action,
riskScore: entry.riskScore,
timestamp: new Date(entry.timestamp).toISOString()
})
}
private generateRecommendations(
logs: AuditLogEntry[],
standard: string
): string[] {
const recommendations: string[] = []
// Check for common security issues
const failedAuths = logs.filter(e => e.eventType === 'auth_event' && e.outcome === 'failure').length
if (failedAuths > 10) {
recommendations.push('Multiple authentication failures detected - consider implementing account lockout')
}
const deniedActions = logs.filter(e => e.outcome === 'denied').length
if (deniedActions > logs.length * 0.3) {
recommendations.push('High denial rate - review permission policies for usability')
}
return recommendations
}
}
export const securityAuditor = new SecurityAuditor()6. 安全检查清单
## 权限控制检查
- [ ] 所有敏感操作都有权限检查
- [ ] 权限规则可配置且易于理解
- [ ] 默认拒绝未知操作
- [ ] 权限变更有审计日志
- [ ] 支持最小权限原则
## PII 保护检查
- [ ] 所有日志都经过 PII 过滤
- [ ] 敏感数据加密存储
- [ ] API 密钥不硬编码
- [ ] 用户路径不泄露
- [ ] 错误信息不包含敏感数据
## 审计合规检查
- [ ] 所有安全事件都有日志
- [ ] 日志保留期符合法规要求
- [ ] 支持日志查询和导出
- [ ] 异常行为自动告警
- [ ] 定期生成合规报告
## 认证授权检查
- [ ] OAuth token 安全存储
- [ ] Token 过期自动刷新
- [ ] 支持多因素认证
- [ ] Session 超时合理设置
- [ ] 注销后彻底清理凭证7. 安全事件响应流程
## 安全事件分级
### P0 - 严重 (Critical)
- 凭证泄露
- 未授权访问生产数据
- 大规模 PII 泄露
**响应时间**: 立即 (<15 分钟)
**升级路径**: 安全团队 → CTO → CEO
### P1 - 高 (High)
- 权限提升尝试
- 多次认证失败
- 可疑的 API 调用模式
**响应时间**: 1 小时内
**升级路径**: 安全团队 → 工程 VP
### P2 - 中 (Medium)
- 单个用户权限异常
- 配置错误导致的数据暴露
- 第三方依赖漏洞
**响应时间**: 24 小时内
**升级路径**: 安全团队 → 相关团队负责人
### P3 - 低 (Low)
- 轻微的合规偏差
- 文档不完善
- 最佳实践未遵循
**响应时间**: 1 周内
**升级路径**: 相关团队自行处理
## 事件响应步骤
1. **检测与分类** (5-15 分钟)
- 确认事件真实性
- 评估影响范围
- 确定事件级别
2. **遏制与隔离** (15-60 分钟)
- 阻止事件扩散
- 隔离受影响的系统
- 保存证据
3. **根除与恢复** (1-24 小时)
- 消除根本原因
- 恢复受影响的服务
- 验证修复效果
4. **总结与改进** (1-7 天)
- 编写事后分析报告
- 实施预防措施
- 更新应急响应流程工作流程
第一步:安全现状评估 (15 分钟)
# 1. 检查权限配置
cat ~/.claude/settings.json | jq '.permissions'
# 2. 审计日志分析
grep -i "denied\|blocked\|unauthorized" ~/.claude/logs/*.log | tail -50
# 3. PII 泄露扫描
find . -name "*.log" -exec grep -E "(sk-[a-zA-Z0-9]{32}|ghp_[a-zA-Z0-9]{36})" {} \;
# 4. 敏感文件检查
find . -name ".env*" -o -name "*credentials*" -o -name "*secrets*"第二步:风险评估 (20 分钟)
使用 STRIDE 威胁建模方法:
- Spoofing: 身份伪造风险
- Tampering: 数据篡改风险
- Repudiation: 抵赖风险
- Information Disclosure: 信息泄露风险
- Denial of Service: 服务中断风险
- Elevation of Privilege: 权限提升风险
第三步:remediation规划 (25 分钟)
基于风险评估制定修复计划,包括立即修复项、短期改进项、长期优化项。
规则
- ✅ 始终遵循最小权限原则
- ✅ 对所有外部输入进行验证和清理
- ✅ 在日志中自动过滤 PII 和敏感信息
- ✅ 为所有安全事件提供审计跟踪
- ✅ 实施深度防御策略(多层防护)
- ❌ 不要硬编码凭证或 API 密钥
- ❌ 不要在日志中输出敏感数据
- ❌ 不要绕过权限检查即使为了方便
- ❌ 不要忽略安全告警和异常
输出格式
📊 安全现状评估
**整体安全评分**: X/100
**优势领域**:
- ...
**高风险区域**:
- ...
**中等风险区域**:
- ...🔴 风险识别
**已识别的风险**: N 个
**按严重程度**:
- Critical: X
- High: Y
- Medium: Z
- Low: W
**TOP 5 风险**:
1. ... (严重程度)
2. ... (严重程度)
3. ... (严重程度)🛡️ 缓解措施
**立即修复** (24-48 小时):
1. ...
2. ...
**短期改进** (1-2 周):
1. ...
2. ...
**长期优化** (1-3 月):
1. ...
2. ...📋 合规检查
**适用标准**: SOC2/GDPR/HIPAA/...
**合规状态**:
- 符合要求:X 项
- 部分符合:Y 项
- 不符合:Z 项
**差距分析**:
...🚨 事件响应计划
**应急联系人**:
- Primary: ...
- Secondary: ...
**升级流程**:
...
**沟通模板**:
...📈 持续监控方案
**关键指标**:
- 权限拒绝率
- 认证失败次数
- PII 泄露检测
- 异常行为告警
**监控频率**: 实时/每小时/每天
**告警阈值**:
...交付物清单
最终报告应包含:
- 安全现状评估和评分
- 风险识别和严重程度评估
- 详细的缓解措施和修复计划
- 合规检查和差距分析
- 安全事件响应计划
- 持续监控方案和告警阈值
- 安全检查清单和审计报告
🤖 AI IDE 开发指南
本部分指导 AI IDE 按照 Claude Code的最佳实践开发安全合规系统。
AI IDE 开发前检查
权限模式系统验证
必须检查:
- PERMISSION_MODES 枚举定义完整
- PermissionMode类型安全
- 各模式的工具访问规则明确
- 默认模式安全(非 bypass)
警告信号:
- 硬编码的 bypass 模式
- 缺少权限检查
- 默认允许所有操作PII 保护准备
必须存在:
- PII_PATTERNS正则表达式定义
- redactPII函数实现
- sanitizeObjectForLogging深度清理
- logForDiagnosticsNoPII统一出口AI IDE 开发中指导
实时安全监控
当执行操作时,AI IDE应该:
- 权限检查验证
// ✅ 正确的权限检查 const result = await canUseTool(toolName, input, permissionContext) if (result.status === 'denied') { logger.warn(`Tool ${toolName} denied: ${result.reason}`) return } // ❌ 避免的模式 // 直接使用工具而无权限检查 await executeTool(toolName, input) // 危险! // AI IDE 应该:立即警告并要求添加 canUseTool 检查 - PII 过滤验证
// AI IDE 应该自动检测并过滤 PII const safeMetadata = sanitizeObjectForLogging(rawMetadata) // 检测模式 const piiPatterns = { email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, homePath: /\/Users\/[^/]+\//g, apiKey: /sk-[a-zA-Z0-9]{32,}/g, githubToken: /ghp_[a-zA-Z0-9]{36}/g } // 发现 PII 时警告并脱敏 if (containsPII(rawMetadata)) { logger.warn('PII detected - redacting') return redactPII(safeMetadata) } - 审计日志记录
// AI IDE 应该确保关键操作有审计日志 securityAuditor.log({ eventType: 'tool_use', actor: { userId, sessionId }, action: toolName, outcome: 'success' | 'failure' | 'denied', riskScore: calculateRiskScore(toolName, input) })
Denial Tracking 系统
AI IDE应该提供:
- denialTracker.track(): 记录拒绝的操作
- detectSuspiciousPatterns(): 检测可疑模式
- getStatistics(): 生成统计数据
- exportReport(): 导出拒绝报告
AI IDE 完成后验证
安全合规健康度评分卡
权限控制 (0-10分):
- 模式切换正确性
- 规则匹配准确性
- 最小权限原则遵循
PII 保护 (0-10分):
- 检测准确率 > 99%
- 脱敏完整性
- 零 PII 泄露到日志
审计日志 (0-10分):
- 关键操作全记录
- 日志保留期合规
- 查询功能完善
Denial Tracking (0-10分):
- 拒绝操作全记录
- 可疑模式检测
- 统计报告准确
事件响应 (0-10分):
- 事件分级明确
- 响应时间达标
- 升级路径清晰
总分评级:
- 90-100: Excellent (生产就绪)
- 75-89: Good (少量改进)
- 60-74: Fair (需要加强)
- <60: Poor (不建议上线)自动化测试清单
AI IDE应该运行:
# 1. 权限控制测试
test('bypass mode allows all', () => {...})
test('plan mode blocks writes', () => {...})
test('rules are enforced', () => {...})
# 2. PII 保护测试
test('detects emails', () => {...})
test('redacts home paths', () => {...})
test('filters API keys', () => {...})
# 3. 审计日志测试
test('logs tool usage', () => {...})
test('retains logs for 90 days', () => {...})
# 4. Denial tracking 测试
test('tracks denied actions', () => {...})
test('detects suspicious patterns', () => {...})
# 5. 事件响应测试
test('classifies events correctly', () => {...})
test('alerts on high-risk events', () => {...})AI IDE 常见陷阱检测
🔴 高危问题(必须修复)
// ❌ 权限绕过
if (user.isAdmin) {
return { status: 'approved' } // 跳过正常权限检查!
}
// AI IDE 应该:立即警告并阻止
// ❌ PII 明文日志
console.log(`User ${email} performed ${action}`) // email 未脱敏!
// AI IDE 应该:建议使用 logForDiagnosticsNoPII
// ❌ 硬编码凭证
const API_KEY = 'sk-xxx...' // 直接写在代码里!
// AI IDE 应该:建议使用环境变量或密钥管理服务
// ❌ 无审计日志
await sensitiveOperation() // 没有记录到审计日志
// AI IDE 应该:建议添加 securityAuditor.log()🟡 中等风险(建议优化)
// ⚠️ 权限规则过于宽松
const rules = [{ pattern: '*', effect: 'allow' }] // 允许所有!
// AI IDE 应该:建议更精细的规则
// ⚠️ PII 检测不完整
const patterns = { email: /.../ } // 只有 email,缺少其他类型
// AI IDE 应该:建议补充完整的 PII 类型列表🟢 低风险(可选改进)
// 💡 可以优化的模式
const isAllowed = user.role === 'admin' // 简单的 RBAC
// AI IDE 可以建议:实现基于属性的访问控制 (ABAC)AI IDE 代码审查检查清单
在 PR/MR阶段,AI IDE应该自动检查:
权限控制
- 所有敏感操作有 canUseTool 检查
- 权限模式正确处理
- 规则匹配引擎完整
- 用户询问界面友好
PII 保护
- 使用 sanitizeObjectForLogging
- 所有日志通过 logForDiagnosticsNoPII
- PII 模式检测完整
- 无硬编码凭证
审计日志
- 关键操作记录完整
- 事件类型正确分类
- 参与者信息准确
- 结果状态明确
Denial Tracking
- 拒绝操作全部记录
- 可疑模式检测启用
- 统计数据准确
- 报告导出可用
事件响应
- 事件分级明确(P0-P3)
- 响应时间定义
- 升级路径清晰
- 高风崄事件告警
AI IDE 集成实现示例
interface SecurityRule {
id: string
description: string
severity: 'error' | 'warning' | 'info'
check: (context: SecurityContext, auditLogs: AuditLogEntry[]) => Violation[]
fix?: (violation: Violation) => Fix
}
const rules: SecurityRule[] = [
{
id: 'SEC-001',
description: 'All tool calls must have permission check',
severity: 'error',
check: (context) => {
const toolCallsWithoutCheck = context.toolCalls.filter(call =>
!call.hasPermissionCheck
)
if (toolCallsWithoutCheck.length > 0) {
return [{
message: `${toolCallsWithoutCheck.length} tool calls without permission check`,
location: toolCallsWithoutCheck.map(c => c.callSite)
}]
}
return []
},
fix: () => ({ type: 'add_permission_check' })
},
{
id: 'SEC-002',
description: 'Logs must not contain PII',
severity: 'error',
check: (context) => {
const logsWithPII = context.logs.filter(log => containsPII(log.message))
if (logsWithPII.length > 0) {
return [{
message: `${logsWithPII.length} log entries contain PII`,
location: logsWithPII.map(l => l.lineNumber)
}]
}
return []
},
fix: () => ({ type: 'redact_pii' })
},
{
id: 'SEC-003',
description: 'Sensitive operations must be audited',
severity: 'error',
check: (context, auditLogs) => {
const unauditedOps = context.sensitiveOperations.filter(op =>
!auditLogs.some(log => log.action === op.name && log.timestamp >= op.timestamp)
)
if (unauditedOps.length > 0) {
return [{
message: `${unauditedOps.length} sensitive operations without audit trail`,
location: unauditedOps.map(op => op.site)
}]
}
return []
},
fix: () => ({ type: 'add_audit_log' })
},
{
id: 'SEC-004',
description: 'Credentials must not be hardcoded',
severity: 'error',
check: (context) => {
const hardcodedCredentials = findHardcodedCredentials(context.sourceCode)
if (hardcodedCredentials.length > 0) {
return [{
message: `${hardcodedCredentials.length} hardcoded credentials found`,
location: hardcodedCredentials.map(c => c.location)
}]
}
return []
},
fix: () => ({ type: 'move_to_env' })
},
{
id: 'SEC-005',
description: 'High-risk events must trigger alerts',
severity: 'warning',
check: (context, auditLogs) => {
const highRiskEvents = auditLogs.filter(log =>
log.riskScore && log.riskScore > 80 && !log.alerted
)
if (highRiskEvents.length > 0) {
return [{
message: `${highRiskEvents.length} high-risk events without alert`,
location: highRiskEvents.map(e => e.id)
}]
}
return []
},
fix: () => ({ type: 'send_alert' })
},
{
id: 'SEC-006',
description: 'Denial patterns should be analyzed',
severity: 'info',
check: (context) => {
const stats = denialTracker.getStatistics()
if (stats.trend === 'increasing' && stats.total > 20) {
return [{
message: 'Increasing denial rate detected - review permission policies',
location: 'permission_config'
}]
}
return []
}
}
// ... 更多规则
]AI IDE 学习路径
为了让 AI IDE更好地理解安全合规规范:
- 第一阶段: 学习权限模式和规则匹配
- 第二阶段: 理解 PII 检测和脱敏技术
- 第三阶段: 掌握审计日志和事件追踪
- 第四阶段: 实现 denial tracking 和模式识别
- 第五阶段: 提供智能安全风险评估和建议
通过学习路径,AI IDE可以成长为能够独立设计和审查安全合规系统的专家。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

