blob: 8ef4ade1a94b67e7efb5f42be1d7bdf741566381 [file]
#!/bin/bash
# Install this hook via
# cp .githooks/pre-commit .git/hooks && chmod +x .git/hooks/pre-commit
# Regex patterns for sensitive tokens
# Matches GitHub PATs (classic & fine-grained), OAuth, User-to-Server, Server-to-Server, and Refresh tokens
GITHUB_TOKEN_REGEX="(gh[pousr]_[A-Za-z0-9_]{36}|github_pat_[A-Za-z0-9_]{22}_[A-Za-z0-9_]{59})"
# Matches Buildkite User Access Tokens
BUILDKITE_TOKEN_REGEX="bkua_[A-Za-z0-9_]{32,}"
# Combine into a single regex for searching
COMBINED_REGEX="($GITHUB_TOKEN_REGEX|$BUILDKITE_TOKEN_REGEX)"
SECRETS_FOUND=0
# Get a list of all files that are staged for commit (Added, Copied, or Modified)
# We ignore deleted files because you can't add a token by deleting a file.
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
# Inspect each staged file
for file in $STAGED_FILES; do
# 1. git diff --cached: Outputs the diff of the staged changes
# 2. grep '^+': Only look at newly added lines
# 3. grep -v '^+++': Ignore the diff file headers
# 4. grep -q -E: Check quietly against the regex
if git diff --cached "$file" | grep '^+' | grep -v '^+++' | grep -E -q "$COMBINED_REGEX"; then
echo " ❌ $file" >&2
SECRETS_FOUND=1
fi
done
if [ $SECRETS_FOUND -eq 1 ]; then
echo "" >&2
echo "========================================================================" >&2
echo "🚨 ERROR: Commit rejected! Sensitive token(s) detected in the files above." >&2
echo "" >&2
echo "A GitHub or Buildkite token was found in your staged changes." >&2
echo "Please remove the token from your code, stage the changes (git add), and commit again." >&2
echo "" >&2
echo "If this is a false positive, you can bypass this hook using:" >&2
echo " git commit --no-verify" >&2
echo "========================================================================" >&2
exit 1
fi
exit 0