π Full Skill Source β This is the complete, unedited SKILL.md file. Nothing is hidden or summarized.
π‘οΈ Secret Shield β Defense-in-Depth Security β
Secrets leak at FIVE stages. Guard ALL five. Write β Commit β Push β Deploy β Runtime One missed stage = one leaked key = one compromised system.
The Iron Laws β
NEVER commit secrets. EVER.
NEVER output secrets in logs, chat, or AI responses.
NEVER trust .gitignore alone β it doesn't protect git history.
PRE-COMMIT HOOKS are your FIRST line of defense.
ROTATION is not optional after a leak.When to Use β
ALWAYS when:
- Setting up a new project (called by
cm-project-bootstrapPhase 0.5) - Before first
git pushon any project - After discovering a potential secret leak
- Setting up CI/CD pipelines
- Reviewing security posture of existing projects
- User says: "check secrets", "security audit", "leaked key", "rotate token"
Integrates with:
cm-project-bootstrapβ Security Foundation phasecm-safe-deployβ Gate 0 enhanced secret hygienecm-test-gateβ Layer 5 security scancm-identity-guardβ Token lifecycle management
The 5 Defense Layers β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 1: WRITE GUARD β AI agent behavior rules β
β Layer 2: PRE-COMMIT GUARD β Block secrets at commit β
β Layer 3: REPO SCAN β Full repo pattern check β
β Layer 4: DEPLOY GATE β Pre-deploy secret audit β
β Layer 5: RUNTIME GUARD β Env var hygiene & rotationβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββLayer 1: Write Guard β AI Agent Safety Rules β
Goal: Prevent the AI agent itself from introducing secrets into code.
Rules for AI Agents β
β
DO:
- Use environment variables: process.env.SECRET_KEY
- Use .dev.vars for local development
- Use platform-specific secret stores: wrangler secret put, Supabase vault
- Mask secrets in logs: console.log('Key:', key.slice(0,4) + '***')
- Reference secret NAMES, not VALUES
β NEVER:
- Hardcode API keys, tokens, or passwords in source code
- Put secrets in wrangler.jsonc, package.json, or any tracked file
- Output full secret values in chat, logs, or error messages
- Use placeholder secrets that look real (e.g., sk-1234567890abcdef)
- Store secrets in i18n files, README, or documentationSecret Patterns to NEVER Generate β
// β NEVER write code like this:
const API_KEY = "sk-proj-abc123def456ghi789";
const SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
const DB_PASSWORD = "MyP@ssw0rd123!";
fetch('https://api.example.com', { headers: { Authorization: 'Bearer sk-...' } });
// β
ALWAYS write code like this:
const API_KEY = process.env.API_KEY;
const SUPABASE_KEY = process.env.SUPABASE_ANON_KEY;
// For Cloudflare Workers:
export default { async fetch(req, env) { const key = env.API_KEY; } };Layer 2: Pre-Commit Guard β Block Secrets at Commit β
Goal: Automatically scan staged files BEFORE they enter git history.
Option A: Gitleaks (Recommended β Industry Standard) β
Step 1: Install Gitleaks β
# macOS
brew install gitleaks
# Linux
# Download from https://github.com/gitleaks/gitleaks/releases
# Verify installation
gitleaks versionStep 2: Create .gitleaks.toml (Project Root) β
# .gitleaks.toml β Cody Master Secret Shield Configuration
title = "CM Secret Shield β Gitleaks Config"
# Extend default rules (catches 100+ known patterns)
[extend]
useDefault = true
# Custom rules for Cody Master projects
[[rules]]
id = "supabase-service-key"
description = "Supabase Service Role Key"
regex = '''eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+'''
tags = ["supabase", "jwt"]
[[rules]]
id = "cloudflare-api-token"
description = "Cloudflare API Token"
regex = '''[A-Za-z0-9_-]{40}'''
entropy = 4.5
secretGroup = 0
tags = ["cloudflare"]
[[rules]]
id = "generic-high-entropy"
description = "High entropy string that may be a secret"
regex = '''(?i)(api[_-]?key|secret[_-]?key|access[_-]?token|private[_-]?key|auth[_-]?token)\s*[=:]\s*['"][a-zA-Z0-9/+=]{20,}['"]'''
tags = ["generic"]
# Allow patterns (reduce false positives)
[allowlist]
paths = [
'''\.gitleaks\.toml$''',
'''\.dev\.vars\.example$''',
'''node_modules/''',
'''dist/''',
'''\.git/'''
]Step 3: Setup Git Pre-Commit Hook β
# Create the hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# CM Secret Shield β Pre-Commit Guard
# Scans staged files for secrets before allowing commit
echo "π‘οΈ Secret Shield: scanning staged files..."
# Check if gitleaks is installed
if command -v gitleaks >/dev/null 2>&1; then
gitleaks git --pre-commit --staged --verbose
if [ $? -ne 0 ]; then
echo ""
echo "β SECRET DETECTED! Commit blocked."
echo ""
echo "To fix:"
echo " 1. Remove the secret from your code"
echo " 2. Use environment variables instead"
echo " 3. If false positive: add to .gitleaks.toml allowlist"
echo ""
echo "To bypass (DANGEROUS): git commit --no-verify"
exit 1
fi
echo "β
Secret Shield: no secrets detected"
else
# Fallback: basic pattern check without gitleaks
echo "β οΈ Gitleaks not installed. Running basic checks..."
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
PATTERNS="SERVICE_KEY|ANON_KEY|PRIVATE_KEY|DB_PASSWORD|SECRET_KEY|API_SECRET|sk-[a-zA-Z0-9]{20,}|-----BEGIN.*KEY-----"
for file in $STAGED; do
if echo "$file" | grep -qE '\.(js|ts|jsx|tsx|json|toml|yaml|yml|env|cfg|conf|ini)$'; then
if git diff --cached "$file" | grep -qE "$PATTERNS"; then
echo "β Potential secret found in: $file"
echo " Run: git diff --cached $file | grep -E '$PATTERNS'"
exit 1
fi
fi
done
echo "β
Basic check passed (install gitleaks for deeper scanning)"
fi
EOF
chmod +x .git/hooks/pre-commit
echo "β
Pre-commit hook installed"Option B: Native Git Hook Only (No Dependencies) β
For projects that can't install Gitleaks, the basic pattern check in the hook above works as a fallback.
Layer 3: Repo Scan β Full Repository Audit β
Goal: Scan the entire repository for secrets that may have been committed before the pre-commit hook was set up.
Quick Scan Script β
# scripts/security-scan.js β Repo-wide secret detection
node scripts/security-scan.jsThe scan script checks for Service Key variables, Anon Key variables, Private Key blocks, JWT tokens, generic API keys, AWS keys, Slack tokens, GitHub tokens, Stripe keys, and DB passwords. It skips node_modules, .git, dist, .wrangler, .next, and coverage directories.
Add to package.json β
{
"scripts": {
"security:scan": "node scripts/security-scan.js",
"security:precommit": "gitleaks git --pre-commit --staged || echo 'Install gitleaks for deep scan'"
}
}Layer 4: Deploy Gate β Pre-Deploy Secret Audit β
Goal: Final check before code leaves the machine. Integrated with
cm-safe-deployGate 0.
The enhanced Gate 0 check runs BEFORE deploy and:
- Checks tracked files for secret values (not just variable names)
- Verifies
.gitignoreincludes.envand.dev.vars - Checks that
.envfiles are not tracked by git
If any check fails, the deploy is blocked with Secret Shield: Deploy blocked. Fix issues above.
Layer 5: Runtime Guard β Token Lifecycle Management β
Goal: Manage secrets throughout their lifecycle β creation, usage, rotation, revocation.
Token Rotation Schedule β
| Platform | Token Type | Max Lifetime | Rotation Trigger |
|---|---|---|---|
| Supabase | anon_key | 90 days | Dashboard β Settings β API |
| Supabase | service_role_key | 30 days | Dashboard β Settings β API |
| Cloudflare | API Token | 90 days | Dashboard β My Profile β API Tokens |
| GitHub | Personal Access Token | 90 days | Settings β Developer Settings β PAT |
| GitHub | Fine-grained Token | 30-90 days | Use expiring tokens when possible |
| OpenAI/Gemini | API Key | 90 days | Rotate in platform dashboard |
Secret Lifecycle File β
Track secrets in .secret-lifecycle.json (add to .gitignore!):
{
"_WARNING": "This file tracks secret metadata ONLY. NEVER put actual values here.",
"secrets": [
{
"name": "SUPABASE_ANON_KEY",
"platform": "supabase",
"store": "cloudflare-secrets",
"createdAt": "2026-03-01",
"rotateBy": "2026-06-01",
"lastRotated": "2026-03-01",
"status": "active"
},
{
"name": "SUPABASE_SERVICE_KEY",
"platform": "supabase",
"store": "cloudflare-secrets",
"createdAt": "2026-03-01",
"rotateBy": "2026-04-01",
"lastRotated": "2026-03-01",
"status": "active"
}
]
}Emergency Rotation Playbook β
When a secret is leaked, follow this sequence immediately:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. REVOKE β Disable the old key in platform dashboardβ
β 2. ROTATE β Generate a new key β
β 3. UPDATE β Push new key to secret store β
β 4. DEPLOY β Redeploy affected services β
β 5. SCAN β Check git history for the old key β
β 6. SCRUB β Remove from git history if needed β
β 7. AUDIT β Review access logs for unauthorized use β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββPer-Platform Rotation Commands β
Supabase:
# 1. Go to Supabase Dashboard β Project Settings β API
# 2. Click "Regenerate" on the compromised key
# 3. Update Cloudflare Secrets:
wrangler secret put SUPABASE_ANON_KEY # Paste new value
wrangler secret put SUPABASE_SERVICE_KEY # Paste new value
# 4. Update local .dev.vars with new values
# 5. Redeploy
npm run deploy:stagingCloudflare API Token:
# 1. Dashboard β My Profile β API Tokens β Roll
# 2. Update any CI/CD systems using this token
# 3. Verify with: wrangler whoamiGitHub Token:
# 1. Settings β Developer Settings β PAT β Regenerate
# 2. Update gh auth: gh auth login
# 3. Verify: gh auth statusSecurity Audit Checklist β
Run this checklist for any project to assess its security posture:
## π‘οΈ Secret Shield Audit
### Layer 1: Write Guard
- [ ] No hardcoded secrets in source files
- [ ] Environment variables used for all secrets
- [ ] .dev.vars exists with local secrets (not committed)
- [ ] .dev.vars.example exists with placeholder names (committed)
### Layer 2: Pre-Commit Guard
- [ ] .git/hooks/pre-commit exists and is executable
- [ ] Gitleaks installed OR native fallback hook active
- [ ] .gitleaks.toml configured for project
### Layer 3: Repo Scan
- [ ] `npm run security:scan` passes clean
- [ ] No JWT tokens in tracked files
- [ ] No API keys in configuration files
- [ ] No private keys in repository
### Layer 4: Deploy Gate
- [ ] Gate 0 checks ALL source files (not just wrangler.jsonc)
- [ ] .gitignore includes: .env, .dev.vars, .env.local, .env.production
- [ ] No .env files tracked by git
- [ ] Cloudflare Secrets used for production values
### Layer 5: Runtime Guard
- [ ] .secret-lifecycle.json tracks all secrets (metadata only)
- [ ] No secrets past rotation deadline
- [ ] Emergency rotation playbook known by team
- [ ] Post-incident: keys rotated, history scrubbedHardened .gitignore Template β
Every project using Secret Shield should have AT MINIMUM these patterns:
# === Secret Shield: Mandatory Ignores ===
# Environment & secret files
.env
.env.*
!.env.example
!.env.test
.dev.vars
!.dev.vars.example
# Secret lifecycle tracking (contains metadata, not values)
.secret-lifecycle.json
# Platform-specific
.wrangler/
*.pem
*.key
*.p12
*.pfx
# OS artifacts
.DS_Store
Thumbs.db
# Dependencies
node_modules/
# Build output
dist/
build/
.next/
.nuxt/
# IDE
.vscode/settings.json
.idea/Red Flags β STOP β
| Thought | Reality |
|---|---|
| "It's just a dev key" | Dev keys have the same permissions as prod keys |
| ".gitignore will protect me" | It can't remove what's already in git history |
| "I'll rotate it later" | Later = never. Rotate NOW. |
| "It was only exposed briefly" | Bots scan GitHub in real-time for leaked keys |
| "This is a private repo" | Private doesn't mean secured. Colleagues, CI, forks all have access |
| "The pre-commit hook is annoying" | 3-second scan vs. hours of incident response |
| "I'll add --no-verify just this once" | That "once" is when the leak happens |
Integration β
| Skill | Relationship |
|---|---|
cm-project-bootstrap | Phase 0.5 calls Secret Shield for initial security setup |
cm-safe-deploy | Gate 0 uses Layer 4 enhanced secret audit |
cm-test-gate | Layer 5 security test uses Layer 3 patterns |
cm-identity-guard | Layer 5 token rotation extends identity lifecycle |
cm-quality-gate | Secret shield is a prerequisite gate |
Lifecycle Position β
cm-project-bootstrap β cm-secret-shield (setup) β development cycle
β
cm-secret-shield (pre-commit) β git commit
cm-secret-shield (gate 0) β cm-safe-deploy
cm-secret-shield (scan) β cm-test-gate
cm-secret-shield (rotation) β cm-identity-guardThe Bottom Line β
5 layers. Every stage. No exceptions.
Write Guard β Pre-Commit β Repo Scan β Deploy Gate β Runtime Guard.
A 3-second scan prevents a 3-day incident. This is non-negotiable.