Security Pre-Commit Check
SkillSecurityPre-commit security scanner for git repos — blocks API keys, proxy credentials, private keys, and project-specific secrets before they reach a remote. Provides a central rule definition + per-repo customization + one-line installer that wires up `.git/hooks/pre-commit`. Use when you want to prevent accidental credential / identity / brand leaks across multiple repos. Triggers on "set up pre-commit security check", "block API keys in commits", "git secret scanner", "prevent credential leaks", "protect identity isolation in public repos".
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Security Pre-Commit Check skill
What this skill tells your AI
The instructions your AI receives, as published by noique/cross-border-ecommerce-skills in tools/security-precommit-check/SKILL.md and read by ahel’s review.
Layered defense against accidental secret / identity leaks in git commits. Combines a central scanner + universal rule set (this skill) with per-repo custom rules and one-line installer that wires up .git/hooks/pre-commit.
Architecture
tools/security-precommit-check/
├── SKILL.md ← this file
├── scripts/
│ ├── scan.sh ← scanner (called by hook OR ad-hoc)
│ └── install-hook.sh ← one-line installer per repo
├── rules/
│ └── default.txt ← universal rules (API keys / proxies / paths)
└── templates/
└── security-precommit-rules.txt.example ← copy to each repo as starting point
In each repo where you install the hook:
<repo>/
├── .git/hooks/pre-commit ← auto-generated by install-hook.sh
└── .security-precommit-rules.txt ← per-repo rules (loaded in addition to default)
The hook delegates to scripts/scan.sh --staged, which reads BOTH default.txt (universal) AND the repo's .security-precommit-rules.txt (per-project).
Install (one line per repo)
# Replace this path with where you cloned cross-border-ecommerce-skills
SKILLS=~/Documents/Code/cross-border-ecommerce-skills
cd /path/to/your/repo
$SKILLS/tools/security-precommit-check/scripts/install-hook.sh
The installer:
- Writes
.git/hooks/pre-commit(idempotent — re-run to refresh) - If
.security-precommit-rules.txtdoesn't exist in your repo, copies the template
After install, every git commit runs the scanner against staged files. BLOCK matches refuse the commit; WARN matches print a warning but allow.
Bypass (when intentional)
git commit --no-verify -m "..."
Ad-hoc scan (without commit)
# Scan all tracked files (good for initial audit on existing repos)
$SKILLS/tools/security-precommit-check/scripts/scan.sh --all
# Scan specific files
$SKILLS/tools/security-precommit-check/scripts/scan.sh --files path1 path2
# Scan staged files (default — same as the hook)
$SKILLS/tools/security-precommit-check/scripts/scan.sh
Selftest — run this after ANY rule edit
$SKILLS/tools/security-precommit-check/scripts/selftest.sh # exit 0 = every rule is alive
Every rule in rules/default.txt must fire on a known-positive sample in
rules/selftest-samples.txt (DESCRIPTION|SAMPLE, all values synthetic). The scanner
fails open, in two ways, and only the first is visible:
| Failure | Symptom | Caught by |
|---|---|---|
| Invalid regex | scan.sh prints dropping invalid rule regex | the warning — but only if you read it |
| Valid regex that matches nothing | nothing at all — the rule looks like coverage | only the selftest |
The second class is why this exists. \| inside a group is a LITERAL pipe in ERE, not
alternation, so (api[_-]?key\|secret[_-]?key) matched only the text api_key|secret_key
— dead, silently, for its whole life. Add a positive control with every new rule; a rule
without one fails the selftest.
The selftest also asserts benign lines trip no BLOCK rule (an over-broad rule teaches
people to --no-verify, which costs more than it saves) and that the generic sk- rule
does not shadow the vendor-specific Anthropic/OpenAI ones.
Rule format
SEVERITY|PATTERN|DESCRIPTION
SEVERITY=BLOCK(rejects commit) orWARN(prints warning, exit 0)PATTERN= extended-regex passed togrep -EDESCRIPTION= human-readable label (printed in scanner output; the selftest's sample key)
Lines starting with # and blank lines are ignored.
🔴 POSIX ERE only — no PCRE. No (?!…) lookahead, no (?=…), no \d/\w shorthand
you rely on. Write | for alternation unquoted — the parser takes SEV as the first
field and DESC as the last, so a pattern may contain pipes freely; escaping them as \|
silently turns them into literal characters.
What's in rules/default.txt (universal)
| Severity | Category | Examples |
|---|---|---|
| BLOCK | API keys | Anthropic / OpenAI / GitHub PAT / Slack / AWS / Stripe |
| BLOCK | Connection strings | host:port:user:pass proxy strings, postgres / mysql / mongodb URLs with embedded password |
| BLOCK | Private keys | PEM private keys, JWT tokens |
| WARN | Personal paths | /Users/{name}/... and /home/{name}/... |
| WARN | Hardcoded literals | password = "..." and api_key = "..." patterns |
What goes in your .security-precommit-rules.txt (per-repo)
| Repo type | Example rules |
|---|---|
| Public skill / template repo (e.g. cross-border-ecommerce-skills) | BLOCK / WARN: founder real name, project-specific competitor names, internal Org-only hostnames |
| Private project repo | Mostly empty — project-specific terms ARE expected here. Maybe BLOCK known-leaked credentials so re-paste fails |
| Open-source library | WARN founder email; BLOCK known internal hostnames |
| Engineering platform repo (e.g. internal services) | BLOCK production hostnames / DB URLs; WARN dev hostnames |
See templates/security-precommit-rules.txt.example for a starting point.
Layered defense — relationship to other security practices
This hook is layer 3. It does NOT replace:
- Layer 1 — Rotate secrets when leaked. A hook can't fix what's already on a remote. If you find a leaked credential, rotate it AT THE PROVIDER, not just commit a redaction.
- Layer 2 — Configure git author identity.
git config user.name/user.emailis set per-commit; this scanner doesn't touch that. Ensure your~/.gitconfiguses an anonymized noreply email if you don't want your real email in commit metadata. - Layer 3 — This hook. Prevents accidental commits of new secrets / identity strings going forward.
- Layer 4 — History hygiene. If past commits have secrets,
git filter-repo+ force-push is the only way to scrub them. Reserve for cases where rotation isn't enough (e.g. permanent credentials).
False-positive handling
If the scanner BLOCKs a legit string:
- First, double-check it's actually OK to commit. Most "false positives" are real near-misses worth fixing (env-var instead of literal, etc.).
- If genuinely OK:
git commit --no-verifyfor that one commit; don't disable the hook. - If a pattern false-positives consistently: tune the regex in
default.txt(PR back to this skill repo) or shadow it via a more specific WARN in your per-repo rules.
Caveats / known limitations
- Pattern-based scanning will miss base64-encoded secrets, secrets concatenated from multiple variables, and binary-encoded credentials. This skill catches the obvious paste-from-clipboard cases — it's not a full secret-scanning solution like TruffleHog / git-secrets / gitleaks.
- The
grep -Eengine doesn't support negative lookahead, so some "exclude localhost" rules are approximated via positive constraints (e.g. requiring user/pass length ≥ 8). - Hook only fires on
git commit.git push --forceof an already-committed bad blob won't be caught — keep secrets out at commit time.
Related
- For full repo-history scanning of past leaks, see
gitleaksortrufflehog. - For automated rotation workflows after a leak: out of scope for this skill.
Signals
- GitHub stars
- 50
- Forks
- 6
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
security-precommit-check- Source
- github.com/noique/cross-border-ecommerce-skills