| #!/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 |