# SECURITY INCIDENT - HUMAN ACTIONS REQUIRED **Date**: 2025-10-21 **Incident**: Anthropic API Key Exposure + Additional Credentials Found **Severity**: CRITICAL **Status**: IMMEDIATE ACTION REQUIRED --- ## EXECUTIVE SUMMARY **What Happened**: 1. Anthropic API key exposed in public GitHub repository (tractatus-framework) 2. Key automatically revoked by Anthropic (good - their secret scanning worked) 3. Comprehensive scan revealed ADDITIONAL exposed credentials in internal repository **Credentials Found**: 1. ✅ Anthropic API key (REVOKED by Anthropic) 2. ❌ SAME Anthropic key STILL in `.env` file (internal repo) 3. ❌ SAME Anthropic key STILL in `docs/STRIPE_LIVE_MODE_DEPLOYMENT.md` (internal repo) 4. ❌ Stripe TEST keys in `.env` (low risk, but still credentials) 5. ❌ JWT secret in `.env` (production secret) **Your Action**: Follow checklist below IMMEDIATELY --- ## CRITICAL - IMMEDIATE ACTIONS (Next 30 Minutes) ### 1. Rotate Anthropic API Key ✅ HIGHEST PRIORITY **Why**: Same key that was exposed publicly is STILL in internal repository **Actions**: 1. Login to Anthropic Console: https://platform.claude.com/settings/keys 2. Verify key `[REDACTED - key rotated 2025-10-21]` is revoked - Key ID: 5043627 - Key Name: family-history-ocr - Status should show: **REVOKED** 3. Create NEW API key: - Name: `tractatus-production-2025-10-21` (or similar) - Description: "Replaces compromised key family-history-ocr" - Copy new key (starts with `sk-ant-api03-`) 4. Update `.env` file: ```bash # Open .env file nano /home/theflow/projects/tractatus/.env # Replace OLD key with NEW key: # OLD: CLAUDE_API_KEY=[REDACTED - key rotated 2025-10-21] # NEW: CLAUDE_API_KEY=sk-ant-api03-YOUR_NEW_KEY_HERE # Save and exit (Ctrl+X, Y, Enter) ``` 5. Test new key: ```bash curl https://api.anthropic.com/v1/messages \ --header "x-api-key: sk-ant-api03-YOUR_NEW_KEY_HERE" \ --header "anthropic-version: 2023-06-01" \ --header "content-type: application/json" \ --data '{"model": "claude-sonnet-4-5-20250929", "max_tokens": 10, "messages": [{"role": "user", "content": "test"}]}' # Should return valid response (not 401 error) ``` **Verification**: New key works, old key definitely revoked --- ### 2. Remove Exposed Key from Documentation ✅ CRITICAL **Why**: `docs/STRIPE_LIVE_MODE_DEPLOYMENT.md` contains the SAME exposed key **Actions**: ```bash # Edit the file nano /home/theflow/projects/tractatus/docs/STRIPE_LIVE_MODE_DEPLOYMENT.md # Find line with: CLAUDE_API_KEY=sk-ant-api03-_xmqWkax8jx... # Replace with: CLAUDE_API_KEY=sk-ant-api03-EXAMPLE-REDACTED-NEVER-USE # Save and exit ``` **Alternative** (automated): ```bash sed -i 's/CLAUDE_API_KEY=sk-ant-api03-[a-zA-Z0-9_-]*/CLAUDE_API_KEY=sk-ant-api03-EXAMPLE-REDACTED-NEVER-USE/g' docs/STRIPE_LIVE_MODE_DEPLOYMENT.md ``` **Verification**: No real API keys in documentation --- ### 3. Rotate JWT Secret ✅ HIGH PRIORITY **Why**: JWT secret in `.env` is production credential used for authentication **Current Secret** (EXPOSED): ``` [REDACTED] ``` **Actions**: 1. Generate new JWT secret: ```bash # Generate secure random secret (64 bytes hex) openssl rand -hex 64 # Copy the output ``` 2. Update `.env`: ```bash nano .env # Replace: # OLD: JWT_SECRET=d4d9b5ac258123db... # NEW: JWT_SECRET= # Save and exit ``` 3. **IMPORTANT**: This will invalidate ALL existing JWT tokens - All users will need to re-login - Any admin sessions will be terminated - This is CORRECT behavior (invalidates potentially compromised sessions) **Verification**: Server starts successfully with new JWT secret --- ### 4. Rotate Stripe Keys (OPTIONAL - Low Risk) ⚠️ MEDIUM PRIORITY **Why**: Stripe TEST keys found in `.env` (not live keys, low financial risk) **Current Keys** (TEST mode): - Secret: `sk_test_[REDACTED]` - Publishable: `pk_test_[REDACTED]` **Risk Assessment**: - These are TEST keys (sk_test_, pk_test_) - No real money can be charged - Still best practice to rotate **Actions** (if you want to rotate): 1. Login to Stripe Dashboard: https://dashboard.stripe.com/test/apikeys 2. Roll secret key (this creates new key and invalidates old) 3. Copy new keys 4. Update `.env`: ```bash STRIPE_SECRET_KEY=sk_test_YOUR_NEW_SECRET_KEY STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_NEW_PUBLISHABLE_KEY ``` **Decision**: Your call - test keys have low risk, but rotation is prudent --- ## SECONDARY ACTIONS (Next 1-2 Hours) ### 5. Install Gitleaks (Secret Detection Tool) **Why**: Prevents future credential exposure with automated pre-commit scanning **Installation** (Linux): ```bash # Download gitleaks wget https://github.com/gitleaks/gitleaks/releases/download/v8.18.1/gitleaks_8.18.1_linux_x64.tar.gz # Extract tar -xzf gitleaks_8.18.1_linux_x64.tar.gz # Move to /usr/local/bin sudo mv gitleaks /usr/local/bin/ # Verify installation gitleaks version ``` **Installation** (Mac - if applicable): ```bash brew install gitleaks ``` **Test**: ```bash # Scan repository cd /home/theflow/projects/tractatus gitleaks detect --source . --verbose # Should detect credentials in .env, docs/STRIPE_LIVE_MODE_DEPLOYMENT.md ``` --- ### 6. Create Git Pre-Commit Hook **Why**: Blocks commits containing secrets BEFORE they reach git history **Actions**: ```bash # Navigate to repository cd /home/theflow/projects/tractatus # Create pre-commit hook cat > .git/hooks/pre-commit << 'EOF' #!/bin/bash echo "🔍 Running secret detection scan..." gitleaks detect --source . --verbose --no-git if [ $? -ne 0 ]; then echo "" echo "❌ SECRETS DETECTED - Commit blocked" echo "" echo "If this is a false positive:" echo " 1. Verify it's NOT a real secret" echo " 2. Add to .gitleaksignore with explanation" echo " 3. Get user approval" echo " 4. Try committing again" echo "" exit 1 fi echo "✅ No secrets detected - proceeding with commit" exit 0 EOF # Make executable chmod +x .git/hooks/pre-commit # Test echo "test-secret=sk-ant-api03-test" > test-file.txt git add test-file.txt git commit -m "test" # Should BLOCK with secret detection error rm test-file.txt git reset HEAD test-file.txt ``` **Verification**: Committing a file with API key pattern is BLOCKED --- ### 7. Add .env to .gitignore (If Not Already) **Why**: Ensures .env never accidentally committed **Actions**: ```bash # Check if .env in .gitignore grep "^\.env$" .gitignore # If not found, add it: echo ".env" >> .gitignore # Verify cat .gitignore | grep "\.env" ``` **Verification**: .env appears in .gitignore --- ### 8. Remove docs/STRIPE_LIVE_MODE_DEPLOYMENT.md from Public Repository **Why**: This file was exposed in public repo at commit 31345d5c1abc8c8da9387d55494a1741f451f9a7 **Decision Required**: **Option A**: Delete file from git history (RECOMMENDED) - Pros: Removes credential from git history - Cons: Force push required, breaks forks - Tool: BFG Repo-Cleaner **Option B**: Accept file in history, rely on key revocation - Pros: No repository disruption - Cons: Credential remains in git history (already revoked) - Action: None needed **Option C**: Delete public repository and recreate - Pros: Complete removal - Cons: Loses stars, discussions, community engagement **Recommendation**: Option B (accept in history) since: 1. Key already revoked by Anthropic 2. Public repo is tractatus-framework (implementation only) 3. No active community yet (early stage) 4. Low risk of exploitation (key revoked) **If you choose Option A** (remove from history): ```bash # Install BFG Repo-Cleaner wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar java -jar bfg-1.14.0.jar --delete-files STRIPE_LIVE_MODE_DEPLOYMENT.md /path/to/tractatus-framework # Follow BFG instructions to git reflog expire and force push ``` **Your Decision**: Which option? --- ### 9. Review All .env Files Across All Projects **Why**: If one project exposed credentials, others might too **Projects to Check**: 1. `/home/theflow/projects/tractatus` (DONE - issues found) 2. `/home/theflow/projects/family-history` (CHECK THIS) 3. `/home/theflow/projects/sydigital` (CHECK THIS) 4. Any other projects **Actions for Each Project**: ```bash # Navigate to project cd /home/theflow/projects/PROJECTNAME # Check .env exists ls -la .env # Scan for credentials gitleaks detect --source . --verbose # Check if .env in git history (BAD if true) git log --all --full-history -- .env ``` **Verification**: No .env files in git history across any project --- ## MONITORING & VERIFICATION (Next 24-48 Hours) ### 10. Monitor Anthropic API Usage **Why**: Detect unauthorized usage of compromised key (before revocation) **Actions**: 1. Login to Anthropic Console: https://platform.claude.com/settings/usage 2. Review API usage for past 24 hours 3. Look for: - Unusual volume spikes - Geographic anomalies (API calls from unexpected regions) - Unknown application names - Timestamp gaps (usage when you weren't working) **Red Flags**: - API calls from non-Europe/non-Australia IPs (if you're only in those regions) - Calls during hours you weren't working (e.g., 2-6 AM your timezone) - Sudden spike in usage - Unfamiliar model names or endpoints **Action if Suspicious**: Contact Anthropic support immediately --- ### 11. Monitor Stripe Dashboard **Why**: Detect unauthorized test transactions (low risk with test keys) **Actions**: 1. Login to Stripe Dashboard: https://dashboard.stripe.com/test/payments 2. Review test transactions for past 7 days 3. Look for unexpected test charges **Note**: Test keys cannot charge real money, so financial risk is zero --- ### 12. Review Git Log for Other Credential Exposures **Why**: May have committed other secrets in past **Actions**: ```bash cd /home/theflow/projects/tractatus # Scan entire git history for secrets gitleaks detect --source . --log-opts="--all" --verbose --report-path=/tmp/gitleaks-report.json # Review report cat /tmp/gitleaks-report.json | jq '.' # Or use grep for common patterns git log -p --all | grep -E "sk-|pk-|api.?key|secret|password" | head -50 ``` **Action if Found**: Rotate those credentials too --- ## POST-INCIDENT IMPROVEMENTS ### 13. Update SECURITY.md in Public Repository **Why**: Transparency and incident disclosure **Actions**: 1. Add incident to Security Audit History table 2. Document response (key revocation, rotation procedures) 3. Update best practices based on learnings **Draft Entry**: ```markdown | Date | Type | Severity | Status | Details | |------|------|----------|--------|---------| | 2025-10-21 | Credential Exposure | CRITICAL | Resolved | Anthropic API key exposed in docs/STRIPE_LIVE_MODE_DEPLOYMENT.md at commit 31345d5c1a. Key automatically revoked by Anthropic via GitHub secret scanning. All credentials rotated. Pre-commit secret detection implemented. | ``` --- ### 14. Document Incident in Internal Post-Mortem **File**: `docs/security/INCIDENT_2025-10-21_API_KEY_EXPOSURE.md` **Sections**: 1. Timeline 2. Root cause 3. Impact assessment 4. Response actions 5. Preventive measures 6. Lessons learned **Claude will create this** - see SECURITY_INCIDENT_POST_MORTEM_2025-10-21.md --- ### 15. Review and Test Pre-Deployment Checklist **Why**: Ensure inst_071 (new enhanced checklist) prevents recurrence **Actions**: 1. Review inst_071 checklist 2. Practice running each step 3. Identify any gaps 4. Update checklist if needed **Checklist** (from inst_071): ``` □ 1. CSP Compliance Check [AUTOMATED via hook] □ 2. Secret Detection Scan (gitleaks detect --source .) □ 3. Credential Audit (grep -r "sk-" "pk-" "secret" "password") □ 4. Local Server Test (curl http://localhost:9000/health → 200 OK) □ 5. Comprehensive Testing (npm test → all pass) □ 6. Permission Verification (ls -la → correct 644/755) □ 7. Git Status Clean (no uncommitted changes) □ 8. Public Repository Content Review (no internal docs) ``` --- ## SUMMARY CHECKLIST Use this to track completion: **CRITICAL (Do Now)**: - [ ] Rotate Anthropic API key (create new, update .env) - [ ] Remove exposed key from docs/STRIPE_LIVE_MODE_DEPLOYMENT.md - [ ] Rotate JWT secret (generate new, update .env) - [ ] Test application with new credentials **HIGH PRIORITY (Next 2 Hours)**: - [ ] Install gitleaks - [ ] Create pre-commit hook - [ ] Verify .env in .gitignore - [ ] Decide on public repo history (Option A/B/C) **MEDIUM PRIORITY (Next 24 Hours)**: - [ ] Rotate Stripe test keys (optional) - [ ] Review other projects (.env files) - [ ] Monitor Anthropic API usage - [ ] Monitor Stripe dashboard - [ ] Scan git history for other secrets **LOW PRIORITY (Next Week)**: - [ ] Update SECURITY.md - [ ] Review post-mortem - [ ] Test pre-deployment checklist - [ ] Schedule quarterly security audits --- ## QUESTIONS & CLARIFICATIONS ### Q: Why did this happen? **A**: Multiple failures in credential handling: 1. Real API key in documentation (should have been redacted example) 2. No secret detection before commit (no pre-commit hook) 3. No credential audit in cleanup checklist (inst_054 didn't include secret scan) 4. Framework components not actively used (BoundaryEnforcer should have caught this) ### Q: Was this malicious AI behavior? **A**: NO. This was systematic failure in processes, not AI having "bad intent": - AI doesn't have intent (good or bad) - AI made mistakes that had catastrophic consequences - Framework existed but wasn't enforced (framework fade) - New rules (inst_069-072) prevent recurrence ### Q: What's the financial impact? **A**: MINIMAL (likely zero): - Anthropic key revoked immediately (GitHub secret scanning worked) - No evidence of unauthorized usage (monitor to confirm) - Stripe keys are TEST mode only (no real money) - JWT secret rotation invalidates sessions (security benefit) ### Q: Will this happen again? **A**: NOT if we follow new procedures: - inst_069: Mandatory credential redaction - inst_070: Pre-commit secret detection (automated) - inst_071: Enhanced deployment checklist (includes credential audit) - inst_072: Defense-in-depth (5 layers of protection) - Gitleaks hook: Blocks commits with secrets ### Q: Should I be worried about other credentials? **A**: YES - Audit recommended: - Review all projects for .env files - Scan git history with gitleaks - Rotate credentials found in scans - Implement secret detection across all projects --- ## CONTACT & SUPPORT **Anthropic Support**: https://support.anthropic.com **Stripe Support**: https://support.stripe.com **GitHub Security**: https://docs.github.com/en/code-security/secret-scanning **Internal**: Review SECURITY_INCIDENT_POST_MORTEM_2025-10-21.md for full analysis --- **CREATED**: 2025-10-21 by Claude Code (Automated Security Response) **URGENCY**: IMMEDIATE ACTION REQUIRED **NEXT REVIEW**: After completing CRITICAL section (next 30 minutes)