INCIDENT SUMMARY:
- Date: 2025-10-21
- Severity: CRITICAL → MEDIUM (credential revoked before exploitation)
- Exposed: Anthropic API key (ID 5043627, name: family-history-ocr)
- Location: docs/STRIPE_LIVE_MODE_DEPLOYMENT.md (commit 31345d5c)
- Detection: GitHub secret scanning (automatic)
- Revocation: Anthropic (automatic, within hours)
- Financial Impact: $0 (no unauthorized usage)
ROOT CAUSE - 5 FAILURE POINTS:
1. No credential redaction in documentation (PREVENTION)
2. Framework fade - BoundaryEnforcer not used (ENFORCEMENT)
3. No pre-commit secret detection (DETECTION)
4. No credential audit in pre-deployment checklist (MITIGATION)
5. Single-layer security model, not defense-in-depth (ARCHITECTURAL)
NEW GOVERNANCE RULES:
- inst_069: Credential Handling in Documentation (SYSTEM, HIGH, PERMANENT)
- Requires ALL credentials redacted with example-only values
- Patterns: sk-ant-api03-EXAMPLE-REDACTED, sk_live_EXAMPLE_REDACTED
- Mandatory secret detection scan before commits
- inst_070: Pre-Commit Secret Detection (SYSTEM, HIGH, PERMANENT)
- Requires gitleaks or detect-secrets as pre-commit hook
- BLOCKS commits containing secrets
- False positives require user approval + documentation
- inst_071: Enhanced Pre-Deployment Checklist (OPERATIONAL, HIGH, PERMANENT)
- Replaces inst_054 with 8 steps including secret detection
- Step 2: gitleaks detect --source .
- Step 3: Credential audit (grep for sk-, pk-, secret, password)
- Step 8: Public repository content review
- inst_072: Assume Breach - Defense in Depth (STRATEGIC, HIGH, PERMANENT)
- Layer 1 - Prevention: Never commit credentials
- Layer 2 - Mitigation: Redact credentials in docs
- Layer 3 - Detection: Pre-commit secret scanning (automated)
- Layer 4 - Backstop: GitHub secret scanning
- Layer 5 - Recovery: Credential rotation procedures
DOCUMENTATION:
- SECURITY_INCIDENT_POST_MORTEM_2025-10-21.md (comprehensive analysis)
- SECURITY_INCIDENT_HUMAN_ACTIONS_REQUIRED.md (15-step action plan)
- scripts/install-gitleaks-hook.sh (automated installation)
- scripts/add-security-rules-2025-10-21.js (rules migration)
ADDITIONAL FINDINGS:
Comprehensive credential scan revealed additional exposed credentials in
internal repository (not public):
- Same Anthropic key in .env file
- Same key in internal docs/STRIPE_LIVE_MODE_DEPLOYMENT.md
- Stripe test keys in .env
- JWT production secret in .env
HUMAN ACTIONS REQUIRED:
1. Rotate Anthropic API key (CRITICAL)
2. Rotate JWT secret (CRITICAL)
3. Remove credentials from internal repository files
4. Install gitleaks pre-commit hook
5. Decide on git history cleanup (Option A/B/C)
VERSION UPDATE:
- instruction-history.json: 3.6 → 3.7
- Total rules: 68 → 72
- Active rules: 56 → 59
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
176 lines
9.6 KiB
JavaScript
Executable file
176 lines
9.6 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Add Security Rules - Post-Breach Response
|
||
*
|
||
* Adds inst_069, inst_070, inst_071, inst_072 in response to
|
||
* Anthropic API key exposure incident on 2025-10-21
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const INSTRUCTION_FILE = path.join(__dirname, '../.claude/instruction-history.json');
|
||
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log(' ADD SECURITY RULES - POST-BREACH RESPONSE');
|
||
console.log('═══════════════════════════════════════════════════════════\n');
|
||
|
||
// Read current data
|
||
console.log('📖 Reading current instruction-history.json...');
|
||
const data = JSON.parse(fs.readFileSync(INSTRUCTION_FILE, 'utf8'));
|
||
|
||
console.log(` Version: ${data.version}`);
|
||
console.log(` Instructions: ${data.instructions.length}`);
|
||
console.log(` Active: ${data.stats.active_instructions}\n`);
|
||
|
||
// Create backup
|
||
const backupFile = INSTRUCTION_FILE + '.backup-pre-security-rules-' + Date.now();
|
||
fs.copyFileSync(INSTRUCTION_FILE, backupFile);
|
||
console.log(`💾 Backup created: ${path.basename(backupFile)}\n`);
|
||
|
||
// Define new security rules
|
||
const newRules = [
|
||
{
|
||
id: 'inst_069',
|
||
text: 'ALL credentials, API keys, secrets, tokens, passwords in documentation MUST be redacted or use example-only values. NEVER include real production or development credentials in files committed to git. Required patterns: API keys: "sk-ant-api03-EXAMPLE-REDACTED-NEVER-USE", Stripe keys: "sk_live_EXAMPLE_REDACTED", "pk_live_EXAMPLE_REDACTED", Passwords: "REDACTED" or "your-password-here", Tokens: "your-token-here". BEFORE committing any file containing credential-like patterns: (1) Replace ALL real values with examples/redacted versions, (2) Run secret detection scan (gitleaks or detect-secrets), (3) Verify no actual credentials remain. If actual credentials needed for deployment, use: Environment variables (.env file, NOT committed), Secure secret management (HashiCorp Vault, AWS Secrets Manager), Deployment-specific configuration (NOT in git).',
|
||
quadrant: 'SYSTEM',
|
||
persistence: 'HIGH',
|
||
temporal_scope: 'PERMANENT',
|
||
session_id: '2025-10-07-001',
|
||
notes: 'CRITICAL SECURITY REQUIREMENT - Created in response to Anthropic API key exposure incident on 2025-10-21. API key (sk-ant-api03-_xm...TwAA, ID 5043627, name: family-history-ocr) was committed to public repository in docs/STRIPE_LIVE_MODE_DEPLOYMENT.md at commit 31345d5c1abc8c8da9387d55494a1741f451f9a7. GitHub secret scanning detected and Anthropic revoked key automatically. This rule prevents recurrence by requiring ALL credentials to be redacted in documentation and enforcing secret detection scans before commits.',
|
||
active: true,
|
||
created_date: '2025-10-21',
|
||
parameters: {
|
||
verification_required: 'MANDATORY',
|
||
blocking: true,
|
||
security_critical: true,
|
||
incident_response: 'anthropic_api_key_exposure_2025_10_21'
|
||
}
|
||
},
|
||
{
|
||
id: 'inst_070',
|
||
text: 'ALL git commits MUST pass secret detection scan before being allowed. Use gitleaks or detect-secrets as pre-commit hook. Hook location: .git/hooks/pre-commit. Command: gitleaks detect --source . --verbose. Action: BLOCK commit if secrets detected. If legitimate secret-like pattern detected (false positive): (1) Verify it is NOT a real secret, (2) Add to .gitleaksignore with comment explaining why, (3) Get user approval before committing, (4) Document in commit message. NEVER bypass secret detection hook without explicit user approval.',
|
||
quadrant: 'SYSTEM',
|
||
persistence: 'HIGH',
|
||
temporal_scope: 'PERMANENT',
|
||
session_id: '2025-10-07-001',
|
||
notes: 'CRITICAL SECURITY REQUIREMENT - Created in response to Anthropic API key exposure incident. Automated pre-commit hook prevents credentials from being committed to git in the first place. This is Layer 3 of defense-in-depth strategy (Prevention → Mitigation → Detection → Backstop → Recovery).',
|
||
active: true,
|
||
created_date: '2025-10-21',
|
||
parameters: {
|
||
verification_required: 'MANDATORY',
|
||
blocking: true,
|
||
automation_required: true,
|
||
security_critical: true
|
||
}
|
||
},
|
||
{
|
||
id: 'inst_071',
|
||
text: 'PRE-DEPLOYMENT CHECKLIST (run in order):\n□ 1. CSP Compliance Check [AUTOMATED via hook]\n□ 2. Secret Detection Scan (gitleaks detect --source .)\n□ 3. Credential Audit (grep -r "sk-" "pk-" "secret" "password")\n□ 4. Local Server Test (curl http://localhost:9000/health → 200 OK)\n□ 5. Comprehensive Testing (npm test → all pass)\n□ 6. Permission Verification (ls -la → correct 644/755)\n□ 7. Git Status Clean (no uncommitted changes)\n□ 8. Public Repository Content Review (no internal docs)\nMark each checkbox before proceeding to next. BLOCK deployment if any step fails.',
|
||
quadrant: 'OPERATIONAL',
|
||
persistence: 'HIGH',
|
||
temporal_scope: 'PERMANENT',
|
||
session_id: '2025-10-07-001',
|
||
notes: 'ENHANCED from inst_054 - Added steps 2, 3, 8 in response to security incident. Step 2 (Secret Detection) and Step 3 (Credential Audit) provide redundant verification that no credentials are being deployed. Step 8 (Public Repository Content Review) ensures no internal documentation accidentally published. This is defense-in-depth approach.',
|
||
active: true,
|
||
created_date: '2025-10-21',
|
||
parameters: {
|
||
verification_required: 'MANDATORY',
|
||
blocking: true,
|
||
replaces: 'inst_054'
|
||
}
|
||
},
|
||
{
|
||
id: 'inst_072',
|
||
text: 'Implement defense-in-depth for credential protection: Layer 1 - Prevention: Never commit credentials to git. Layer 2 - Mitigation: Redact credentials in documentation. Layer 3 - Detection: Pre-commit secret scanning (automated). Layer 4 - Backstop: GitHub secret scanning (automatic on public repos). Layer 5 - Recovery: Credential rotation procedures documented. ALL security-sensitive operations must have multiple layers. If one layer fails, others should prevent catastrophic outcome. When creating deployment documentation: (1) Use environment variable names, not values, (2) Include credential rotation procedures, (3) Document secret management system (Vault, AWS Secrets Manager), (4) Never assume "just do not commit secrets" is sufficient protection.',
|
||
quadrant: 'STRATEGIC',
|
||
persistence: 'HIGH',
|
||
temporal_scope: 'PERMANENT',
|
||
session_id: '2025-10-07-001',
|
||
notes: 'STRATEGIC SECURITY PRINCIPLE - Created in response to incident analysis. The breach occurred because only Layer 1 (prevention) and Layer 4 (GitHub scanning) existed. Layers 2, 3, and 5 were missing. This rule requires ALL five layers for security-critical operations. Based on "assume breach" security model where no single control is trusted.',
|
||
active: true,
|
||
created_date: '2025-10-21',
|
||
parameters: {
|
||
verification_required: 'ADVISORY',
|
||
architectural_principle: true,
|
||
security_critical: true
|
||
}
|
||
}
|
||
];
|
||
|
||
console.log('➕ Adding new security rules...\n');
|
||
|
||
newRules.forEach(rule => {
|
||
data.instructions.push(rule);
|
||
console.log(` ✓ Added ${rule.id}`);
|
||
console.log(` ${rule.text.substring(0, 80)}...`);
|
||
console.log('');
|
||
});
|
||
|
||
// Update inst_054 to mark as superseded
|
||
const inst_054 = data.instructions.find(i => i.id === 'inst_054');
|
||
if (inst_054) {
|
||
if (!inst_054.notes.includes('Superseded')) {
|
||
inst_054.notes += '\n\nSuperseded by inst_071 on 2025-10-21 which adds secret detection and credential audit steps.';
|
||
}
|
||
inst_054.active = false;
|
||
console.log(' ⊝ Deprecated inst_054 (superseded by inst_071)\n');
|
||
}
|
||
|
||
// Update version and stats
|
||
data.version = '3.7';
|
||
data.last_updated = new Date().toISOString();
|
||
|
||
const activeInstructions = data.instructions.filter(i => i.active !== false);
|
||
|
||
const quadrantCounts = {
|
||
SYSTEM: 0,
|
||
STRATEGIC: 0,
|
||
OPERATIONAL: 0,
|
||
TACTICAL: 0
|
||
};
|
||
|
||
const persistenceCounts = {
|
||
HIGH: 0,
|
||
MEDIUM: 0,
|
||
LOW: 0
|
||
};
|
||
|
||
activeInstructions.forEach(inst => {
|
||
if (inst.quadrant) quadrantCounts[inst.quadrant]++;
|
||
if (inst.persistence) persistenceCounts[inst.persistence]++;
|
||
});
|
||
|
||
data.stats = {
|
||
total_instructions: data.instructions.length,
|
||
active_instructions: activeInstructions.length,
|
||
by_quadrant: quadrantCounts,
|
||
by_persistence: persistenceCounts
|
||
};
|
||
|
||
console.log('📊 Updating version and stats...');
|
||
console.log(` Version: 3.6 → 3.7`);
|
||
console.log(` Total: ${data.instructions.length}`);
|
||
console.log(` Active: ${data.stats.active_instructions}\n`);
|
||
|
||
// Write updated file
|
||
fs.writeFileSync(INSTRUCTION_FILE, JSON.stringify(data, null, 2));
|
||
console.log(`💾 Written to ${path.basename(INSTRUCTION_FILE)}\n`);
|
||
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log(' ✅ SECURITY RULES ADDED SUCCESSFULLY');
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log('');
|
||
console.log('New rules:');
|
||
console.log(' inst_069: Credential Handling in Documentation');
|
||
console.log(' inst_070: Pre-Commit Secret Detection');
|
||
console.log(' inst_071: Enhanced Pre-Deployment Checklist');
|
||
console.log(' inst_072: Assume Breach - Defense in Depth');
|
||
console.log('');
|
||
console.log('Next steps:');
|
||
console.log(' 1. Sync to MongoDB: node scripts/sync-instructions-to-db.js');
|
||
console.log(' 2. Run credential scan: rg -i "sk-" --hidden');
|
||
console.log(' 3. Install gitleaks: brew install gitleaks (or apt/yum)');
|
||
console.log(' 4. Create pre-commit hook: scripts/install-gitleaks-hook.sh');
|
||
console.log('');
|