From security-engineering
Playbook for detecting secrets committed to Git — pre-commit hooks, CI scanning, historical repo scanning — and the full remediation procedure when a secret is found: rotation, history rewrite, and the post-incident checklist.
How this skill is triggered — by the user, by Claude, or both
Slash command
/security-engineering:secrets-detection-and-remediationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use when adding secrets scanning to a CI/CD pipeline, investigating a potential leaked credential, responding to a GitHub push-protection alert, or auditing a legacy repository for historical leaks.
Use when adding secrets scanning to a CI/CD pipeline, investigating a potential leaked credential, responding to a GitHub push-protection alert, or auditing a legacy repository for historical leaks.
Block secrets before they ever hit the remote:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
hooks:
- id: gitleaks
name: Detect hardcoded secrets
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
Install on the repo and for every contributor:
pip install pre-commit
pre-commit install
pre-commit run --all-files # baseline scan
detect-secrets uses the baseline file to suppress known false positives — update it when you intentionally add a token-shaped test fixture.
Pre-commit is advisory (devs can skip with --no-verify). The CI gate is the enforced backstop:
# .github/workflows/security.yml
name: Secret Scanning
on: [push, pull_request]
jobs:
gitleaks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 } # full history for diff scanning
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # required for org scans
fetch-depth: 0 is required — shallow clones miss secrets introduced in older commits of a PR.
GitHub native push protection: enable under Organization → Settings → Code Security → Secret scanning → Push protection. This blocks the push at the server before it lands, for known high-entropy patterns (AWS keys, GCP SA keys, Stripe keys, etc.).
For legacy repositories or post-incident audits:
# Full history scan (all branches, all commits)
trufflehog git file://. \
--only-verified \
--json \
| tee trufflehog-results.json
# Or with gitleaks on full history
gitleaks detect \
--source . \
--log-opts="--all" \
--report-path gitleaks-report.json \
--report-format json
--only-verified (TruffleHog): tests each found credential against its API — reduces false positives significantly. Active credentials are the priority.
For each finding:
| Field | Record |
|---|---|
| Secret type | AWS access key, GitHub PAT, DB password, etc. |
| First introduced | Commit SHA + date |
| Last seen | Most recent commit containing it |
| Current status | Active (verified) / Expired / Unknown |
| Blast radius | What can this credential access? |
Prioritize by: verified/active first → then by blast radius (prod credentials > dev > test) → then by exposure window (public repo > private).
Rotation stops active exploitation. History rewrite comes second.
AWS: IAM → Security credentials → Deactivate → Create new key → Update consumers → Delete old
GCP: IAM → Service Accounts → Keys → Add key → Update consumers → Delete old key
GitHub PAT: Settings → Developer settings → Personal access tokens → Regenerate
DB passwords: ALTER USER ... PASSWORD '...' + update all connection strings
Use git-filter-repo (not the deprecated filter-branch):
pip install git-filter-repo
# Remove a specific file that contained the secret
git filter-repo --path path/to/secret-file.env --invert-paths
# Or replace the exact secret string across all history
git filter-repo --replace-text <(echo "AKIAIOSFODNN7EXAMPLE==>REDACTED_AWS_KEY")
Before rewriting:
git push --force --all).git fetch --all && git reset --hard origin/main.[ ] Secret rotated and old credential deleted/deactivated
[ ] Git history rewritten; no trace in any branch or PR diff
[ ] All consumers (apps, CI, scripts) updated to use new credential
[ ] Audit log reviewed: was the secret used between first-commit and rotation?
[ ] Platform logs checked (AWS CloudTrail / GCP Audit Logs / GitHub audit log)
[ ] Incident note written: type, exposure window, scope, remediation
[ ] Pre-commit hook and CI gate added/verified to prevent recurrence
[ ] Team notified of the rewritten history + required re-clone
git log; the history rewrite is mandatory.main that doesn't cover develop, release/*, and every open PR branch leaves copies of the secret in the remote.--only-verified masking unverified but real secrets — TruffleHog verified mode skips expired/rate-limited creds; run an unverified scan too on critical repos and manually triage..gitleaksignore or secrets baseline — without a suppression file, scan noise from test fixtures blocks the CI gate with false positives; establish a baseline on day one.npx claudepluginhub mcorbett51090/ravenclaude --plugin security-engineeringGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.