Preventing Secrets from Leaking in Git Repos (Pre‑commit Hook)

• Security

Why

AI‑assisted coding accelerates delivery—and increases the odds of accidentally staging API keys or passwords. Offensive security teams already use tools like Nosey Parker to find leaked credentials in repos. As developers, we can shift left and use the same engine before commit: a tiny pre‑commit hook scans staged files and blocks risky changes automatically.

Setup

  1. Install Nosey Parker: github.com/praetorian-inc/noseyparker
  2. Create a hooks folder and add the hook:
    mkdir -p .githooks
    cat > .githooks/pre-commit << 'HOOK'
    #!/usr/bin/env bash
    set -euo pipefail
    if ! command -v noseyparker >/dev/null 2>&1; then
    echo "[noseyparker] Not installed. Install: https://github.com/praetorian-inc/noseyparker"
    echo "[noseyparker] Proceeding without scan."
    exit 0
    fi
    mapfile -t FILES < <(git diff --cached --name-only --diff-filter=ACMR)
    [[ ${#FILES[@]} -eq 0 ]] && exit 0
    TMPDIR=$(mktemp -d 2>/dev/null || mktemp -d -t np)
    trap 'rm -rf "$TMPDIR"' EXIT INT TERM
    for f in "${FILES[@]}"; do
    if git cat-file -e ":$f" 2>/dev/null; then
    mkdir -p "$TMPDIR/$(dirname "$f")"
    git show ":$f" > "$TMPDIR/$f" || true
    fi
    done
    DATASTORE="$TMPDIR/datastore"
    noseyparker scan --datastore "$DATASTORE" "$TMPDIR" >/dev/null 2>&1 || { echo "[noseyparker] scan failed"; exit 1; }
    REPORT=$(noseyparker report --datastore "$DATASTORE" 2>/dev/null || true)
    if [[ -n "$(echo "$REPORT" | sed 's/[[:space:]]//g')" ]]; then
    echo "[noseyparker] Potential secrets detected in staged changes."; echo "---"; echo "$REPORT" | sed -n '1,200p'; echo "---"; exit 1; fi
    exit 0
    HOOK
    chmod +x .githooks/pre-commit
    
  3. Tell Git to use the hooks folder for this repo:
    git config core.hooksPath .githooks
    

The hook scans only staged changes and blocks the commit if it finds likely secrets.

Quick Test

Create a throwaway file that looks like a secret and try to commit it. The hook should block and print a short report.

printf "AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE\nAWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n" > tmp-secret.env
git add tmp-secret.env
GIT_TRACE=1 GIT_TRACE_SETUP=1 git commit -m "test: should be blocked by noseyparker"

Example output (truncated):

[noseyparker] Potential secrets detected in staged changes.
---
Finding 1: AWS Access Key ID
File: tmp-secret.env:1
Match: AKIAIOSFODNN7EXAMPLE
Finding 2: AWS Secret Access Key
File: tmp-secret.env:2
Match: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
---
Aborting commit.

Clean up and confirm a clean commit:

git reset HEAD tmp-secret.env
rm tmp-secret.env
git commit -m "clean commit"

What the Hook Does

  • Materializes staged files into a temp directory
  • Runs noseyparker scan on that temp directory
  • Prints a brief noseyparker report and blocks on findings

Hook path in this repo: .githooks/pre-commit.

Credit

Nosey Parker is an open‑source project by Praetorian. A shout‑out to my former coworker Brad Larsen, a machine learning expert, whose work and advocacy for practical guardrails inspired adding this minimal hook to keep AI‑era coding safer.

Notes

  • This is a minimal example to keep friction low; improve as needed for your workflow.
  • Rotate any credential that was ever committed—even briefly.
  • For CI coverage, run Nosey Parker in your PR pipeline as well.