Pre-Commit & Scanning Cross-cutting defense
AI agents generate diffs faster than humans can review and routinely write secrets into config files. Pre-commit hooks, secret scanners, and CI gates are the primary control plane for agent-authored code — independent of which harness you run.
pre-commit Framework Setup
The pre-commit framework (pre-commit.com) is the universal harness — runs language-agnostic hooks defined in .pre-commit-config.yaml, pinned by SHA, isolated in per-hook virtualenvs. Pin every rev: so an agent cannot silently bump a hook to a malicious version.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: detect-private-key
- id: check-added-large-files
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleakspipx install pre-commit
pre-commit install
pre-commit install --hook-type pre-push --hook-type commit-msg
pre-commit run --all-files
pre-commit autoupdate --freezeTip: mirror the same config in CI via pre-commit/action@v3.0.1 so local-skipped hooks (SKIP=gitleaks git commit) still fail the PR.
gitleaks — Fast Regex Scanner
Gitleaks scans git history and staged content against ~150 built-in regex rules plus your custom ones. Fast, deterministic first-line scanner; combine with a baseline file so legacy false positives don't drown real findings.
brew install gitleaks
gitleaks protect --staged --redact -v
gitleaks detect --baseline-path .gitleaks-baseline.json --redact# .gitleaks.toml — agent-specific custom rules
[[rules]]
id = "anthropic-api-key"
regex = '''sk-ant-[a-zA-Z0-9_-]{60,}'''
keywords = ["sk-ant-"]
[[rules]]
id = "openai-project-key"
regex = '''sk-proj-[A-Za-z0-9_-]{40,}'''Tip: generate the baseline once with gitleaks detect --report-path .gitleaks-baseline.json, commit it, require any new finding (not in baseline) to fail CI.
trufflehog — Live Credential Verification
TruffleHog goes beyond regex — its --results=verified mode actively pings the provider API to confirm a credential is live. Use verified in CI to cut noise to zero; use unverified in nightly audits to catch dormant keys.
brew install trufflehog
trufflehog git file://. --since-commit HEAD~50 --only-verified --fail
trufflehog filesystem . --results=verified,unknown --no-updateTip: run --only-verified on every PR (blocking), and a full-history --results=verified,unknown scan weekly via a scheduled GitHub Action. For repos >1 GB, prefer trufflehog filesystem on a checkout over trufflehog git.
detect-secrets (Yelp) — Auditable Baseline
detect-secrets takes a different approach — an auditable baseline of every potential secret, with entropy plus plugin heuristics. Ideal when you need a reviewable artifact showing what's been triaged.
pipx install detect-secrets
detect-secrets scan --all-files --exclude-files 'package-lock\.json' > .secrets.baseline
detect-secrets audit .secrets.baseline- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']Tip: require a human (not an agent) to be the git author of any commit touching .secrets.baseline — enforce via CODEOWNERS.
AI-Agent-Specific Scanners (Prompt Injection & Rules Files)
Agent rule files (.cursorrules, .clinerules, .opencode/agents/*.md, CLAUDE.md, AGENTS.md, .github/copilot-instructions.md) execute as system prompts — treat them as code.
<img> URLs. Gemini CLI (Jul 2025): instructions hidden in README context files (padded off-screen) triggered silent shell execution.- promptfoo —
npx promptfoo@latest redteam init/promptfoo redteam run - NVIDIA garak —
pipx install garak; LLM vulnerability scanner with 100+ probes - Mindgard CLI —
pipx install mindgard; commercial red-team runner - Lasso Security — commercial runtime/CI scanner
npx promptfoo@latest scan --paths '.cursorrules,.clinerules,.opencode/agents/**/*.md,CLAUDE.md'
garak --model_type test.Blank --probes encoding.InjectBase64,promptinject.HijackHateHumansTip: add a local pre-commit hook that greps rule files for suspicious tokens (ignore previous, system:, base64 blobs, fenced <|im_start|>) and require a security-team CODEOWNER review for any change under .cursor/, .opencode/, .clinerules, CLAUDE.md.
Repository Hygiene — .gitignore for Agent Config Dirs
Agent IDEs and CLIs scatter credentials across well-known paths. Most are project-local and will end up in git status unless ignored.
# AI agent config & credentials
.env
.env.*
!.env.example
# Cursor
.cursor/mcp.json
.cursor/rules/*.local.mdc
# Cline / Roo
.cline/
.clinerules.local
.roo/
# opencode
.opencode/auth.json
.opencode/local/
.opencode/.cache/
# Claude Code
.claude/settings.local.json
.claude/.credentials.json
.claude/projects/
# Pi / OpenHands / n8n
.pi/
.openhands/
.n8n/credentials/
# MCP server configs commonly carry tokens
**/mcp.json
**/mcp.local.json
.mcp.jsonTip: keep .env.example committed; add a pre-commit hook that hard-fails on any path matching *credentials*, *auth.json, or mcp.json regardless of .gitignore (defense against git add -f).
CI Gates — Block Secrets, Gate Agent-Authored Commits
Two gates: (a) secret scan on every PR, (b) human-review requirement on commits whose trailers identify an AI agent.
on: [pull_request]
jobs:
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: gitleaks/gitleaks-action@v2
- uses: trufflesecurity/trufflehog@main
with:
extra_args: --results=verified --fail
- uses: pre-commit/action@v3.0.1
agent-authored-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Require human reviewer on AI commits
run: |
if git log --no-merges origin/main..HEAD --format='%(trailers:key=Co-Authored-By)' \
| grep -qiE 'claude|cursor|cline|opencode|copilot|openhands'; then
echo "AI co-authored commits found — human approval required."
gh pr view ${{ github.event.pull_request.number }} --json reviews \
| jq -e '.reviews | map(select(.state=="APPROVED")) | length >= 1'
fiTip: enforce branch protection requiring secrets + agent-authored-review checks; maintain a git log --author= allowlist of trusted committers.
Hidden-Unicode / Bidi Detection
"Trojan Source" attacks (CVE-2021-42574) hide logic in U+202A–U+202E bidi controls and U+200B–U+200F zero-widths — devastating in agent-authored code because reviewers skim.
rg --pcre2 '[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2066}-\x{2069}\x{FEFF}]' \
--files-with-matches && exit 1# Custom gitleaks rule
[[rules]]
id = "bidi-control-chars"
regex = '''[\x{202A}-\x{202E}\x{2066}-\x{2069}]'''
[[rules]]
id = "zero-width-chars"
regex = '''[\x{200B}-\x{200F}\x{FEFF}]'''Additional tools: bidiscan, npm i -g anti-trojan-source, cargo install trojan-source-finder.
Tip: add the regex above as both a pre-commit local hook and a gitleaks rule — belt-and-suspenders, since agents sometimes echo invisible chars from web-fetched content.
Pre-Push & Post-Checkout — Inspect Third-Party Repos
Before pointing an agent at a freshly-cloned repo, scan it. A malicious .cursorrules or .opencode/agents/*.md can hijack the agent on first invocation.
# .git/hooks/post-checkout
#!/usr/bin/env bash
prev=$1; new=$2; flag=$3
[ "$flag" = "1" ] || exit 0
for dir in .cursor .opencode .claude .cline .pi .roo .openhands; do
[ -d "$dir" ] || continue
echo "Scanning $dir for injection markers..."
rg -n --pcre2 \
-e 'ignore (all )?previous' \
-e '<\|im_start\|>' \
-e '[\x{202A}-\x{202E}\x{200B}-\x{200F}]' \
-e 'base64,[A-Za-z0-9+/]{200,}' \
"$dir" && {
echo "Suspicious content in $dir — review before launching agent."
exit 1
}
done
gitleaks detect --no-git --source . --redactTip: for any cloned repo, run git log --diff-filter=A --name-only -- '.cursor*' '.opencode*' '.claude*' '.cline*' to see who introduced agent configs — then audit each before invoking an agent.
Supply-Chain Scanning for Agent Extensions & Plugins
Cursor/Cline/opencode/Pi marketplaces and MCP server registries have shipped weaponized packages (typosquats, dependency-confusion, post-install scripts exfiltrating ~/.aws). Treat every agent extension and MCP server like an npm dep.
nx postinstall invoked locally-installed Claude/Gemini/Q CLIs to scan filesystem for secrets, leaked 1,000+ GitHub tokens. huggingface-cli (Mar 2024): Lasso registered an LLM-hallucinated package name; 30,000+ installs in three months. n8n community-node attack (Jan 2026): eight rogue npm packages exfiltrated decrypted OAuth tokens. MaliciousCorgi VS Code extensions (Mar 2026): 1.5M installs exfiltrating source code.# Node / MCP servers
npm audit --audit-level=high
npx socket@latest npm install <pkg>
npx better-npm-audit audit
# Cross-ecosystem
osv-scanner --recursive .
snyk test --all-projects
snyk monitor
# Audit lockfiles
npx lockfile-lint --path package-lock.json --allowed-hosts npm \
--validate-https --validate-integrity- uses: google/osv-scanner-action@v1.9.1
with: { scan-args: |-
--recursive
--skip-git
./ }
- run: npx --yes socket-security-cli ciTip: pin every MCP server and agent extension by integrity hash (npm ci with committed lockfile, or uvx --from 'pkg==X.Y.Z'); run osv-scanner + socket on every PR; subscribe to Dependabot + Socket advisories.
References & further reading
- pre-commit.com — framework docs
- gitleaks — github.com/gitleaks/gitleaks
- TruffleHog — github.com/trufflesecurity/trufflehog
- detect-secrets — github.com/Yelp/detect-secrets
- promptfoo — LLM red-team / eval framework
- NVIDIA garak — LLM vulnerability scanner
- osv-scanner — vulnerability scanner for dependencies
- socket.dev — supply-chain security for npm
- Trojan Source (CVE-2021-42574) — official site
- CVE-2021-42574 — NVD entry
- Shai-Hulud 2.0 npm worm — Datadog Security Labs
- Nx npm supply-chain attack (s1ngularity) — The Register
- Slopsquatting / huggingface-cli — Aikido