Skip to content

πŸ“‹ Full Skill Source β€” This is the complete, unedited SKILL.md file. Nothing is hidden or summarized.

← Back to Skills Library

πŸ›‘οΈ 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-bootstrap Phase 0.5)
  • Before first git push on 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 phase
  • cm-safe-deploy β€” Gate 0 enhanced secret hygiene
  • cm-test-gate β€” Layer 5 security scan
  • cm-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 documentation

Secret Patterns to NEVER Generate ​

javascript
// ❌ 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.

Step 1: Install Gitleaks ​

bash
# macOS
brew install gitleaks

# Linux
# Download from https://github.com/gitleaks/gitleaks/releases

# Verify installation
gitleaks version

Step 2: Create .gitleaks.toml (Project Root) ​

toml
# .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 ​

bash
# 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 ​

bash
# scripts/security-scan.js β€” Repo-wide secret detection
node scripts/security-scan.js

The 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 ​

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-deploy Gate 0.

The enhanced Gate 0 check runs BEFORE deploy and:

  1. Checks tracked files for secret values (not just variable names)
  2. Verifies .gitignore includes .env and .dev.vars
  3. Checks that .env files 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 ​

PlatformToken TypeMax LifetimeRotation Trigger
Supabaseanon_key90 daysDashboard β†’ Settings β†’ API
Supabaseservice_role_key30 daysDashboard β†’ Settings β†’ API
CloudflareAPI Token90 daysDashboard β†’ My Profile β†’ API Tokens
GitHubPersonal Access Token90 daysSettings β†’ Developer Settings β†’ PAT
GitHubFine-grained Token30-90 daysUse expiring tokens when possible
OpenAI/GeminiAPI Key90 daysRotate in platform dashboard

Secret Lifecycle File ​

Track secrets in .secret-lifecycle.json (add to .gitignore!):

json
{
  "_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:

bash
# 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:staging

Cloudflare API Token:

bash
# 1. Dashboard β†’ My Profile β†’ API Tokens β†’ Roll
# 2. Update any CI/CD systems using this token
# 3. Verify with: wrangler whoami

GitHub Token:

bash
# 1. Settings β†’ Developer Settings β†’ PAT β†’ Regenerate
# 2. Update gh auth: gh auth login
# 3. Verify: gh auth status

Security Audit Checklist ​

Run this checklist for any project to assess its security posture:

markdown
## πŸ›‘οΈ 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 scrubbed

Hardened .gitignore Template ​

Every project using Secret Shield should have AT MINIMUM these patterns:

gitignore
# === 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 ​

ThoughtReality
"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 ​

SkillRelationship
cm-project-bootstrapPhase 0.5 calls Secret Shield for initial security setup
cm-safe-deployGate 0 uses Layer 4 enhanced secret audit
cm-test-gateLayer 5 security test uses Layer 3 patterns
cm-identity-guardLayer 5 token rotation extends identity lifecycle
cm-quality-gateSecret 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-guard

The 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.

Open Source AI Agent Skills Framework