Secrets Leak Gate is a GitHub Action that scans the diff of pull requests and push events for potential secrets and fails the build when it finds them. It combines regular expression matching for well‑known credential formats with Shannon entropy analysis to catch unstructured secrets. When a leak is detected in a pull request, the action can post a remediation comment on the pull request and blocks the merge by marking the step as failed.
Git history often contains thousands of lines of code, but developers rarely change more than a few files in a single commit. Scanning only the added lines dramatically reduces noise and false positives while still protecting your supply chain. This approach mirrors the secret detection strategies used by mature tools: they first identify secret candidates (often via regex or entropy) and then apply filters to reduce false positives【255846875226032†L133-L138】. GitHub’s own detect‑secrets project classifies detectors into regex‑based rules for well‑structured tokens, entropy detectors for non‑structured secrets, and keyword detectors for variable names commonly used to store credentials【357040101384713†L793-L813】. Our action uses a combination of regex rules and entropy detection to achieve good recall with acceptable precision.
The repository includes a handful of regular expressions covering common service tokens—AWS, Google Cloud, GitHub, GitLab, Slack, Stripe, Twilio, SendGrid, Mailgun, JWT tokens, API key assignments, and database connection URIs. These patterns are inspired by public resources that list secret detection regexes, such as the 100 Regex Patterns to Hunt Secrets article【830132646967155†L31-L58】. You can extend or override the list by modifying index.js to suit your own environment.
Randomly generated tokens often lack a clear prefix. To catch these, the action looks for substrings at least 20 characters long containing both letters and numbers and then computes their Shannon entropy. Strings with entropy ≥ 4.0 bits per character are flagged as high‑entropy secrets. This method is motivated by industry discussions on high entropy strings being indicative of secrets【255846875226032†L140-L148】. You can tune the threshold in index.js to adjust sensitivity.
Create a workflow file (e.g. .github/workflows/secret‑scan.yml) with the following content:
name: Secrets Scan
on:
push: {branches: [main, develop]}
pull_request:
types: [opened, synchronize, reopened]
jobs:
scan-secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Secrets Leak Gate
uses: your-username/secrets-leak-gate@v1
with:
# GITHUB_TOKEN is automatically provided; pass it so the action can comment on PRs
repo-token: ${{ secrets.GITHUB_TOKEN }}Replace your-username/secrets-leak-gate@v1 with the repository and tag you publish the action under.
When the action finds a secret, it:
- Posts a comment on the pull request summarising the file, line and secret type.
- Fails the job using
core.setFailed(), which blocks the PR from being merged.
To remediate, remove the secret from the codebase and rotate the credential. If the flagged value is benign (e.g. dummy data), you can suppress the warning by adding // pragma: allowlist secret on the same line; this pattern mirrors the allowlisting mechanism used in other secret‑scanning tools【357040101384713†L862-L872】.
Secret sprawl is evolving, and no static list of regexes will cover every case. To add or modify detection rules:
- Open
index.jsand locate theregexPatternsarray. - Add a new object with a human‑readable
nameand a JavaScriptRegExpto the array. For example, to detect Firebase secrets you could add:This pattern is derived from publicly available secret patterns【830132646967155†L42-L44】.{ name: 'Firebase Secret', regex: /AAAA[A-Za-z0-9_-]{7}:[A-Za-z0-9_-]{140}/g }
- Commit and push the changes. Remember to bump the version tag when publishing.
You can test the action locally using act or by running node index.js on a sample diff. The script falls back to comparing HEAD~1 and HEAD when no event payload is available, so you can run:
git fetch --depth=2 origin main
git checkout -b test-branch
# make some changes and commit them
node secrets-leak-gate/index.js- Create a public repository named
secrets-leak-gateon GitHub and push the contents of this directory. - Ensure your
action.ymlis in the root of the repository (as provided here). - Create a version tag following semantic versioning, e.g.
v1.0.0:git tag -a v1.0.0 -m "Initial release of Secrets Leak Gate" git push origin v1.0.0 - Navigate to the GitHub repository’s “Actions” tab and click “Add to marketplace.” Fill in the marketplace metadata and publish. Once published, users can reference the action with
uses: your-username/secrets-leak-gate@v1.
GitHub Actions executes JavaScript actions from the dist/ directory without installing dependencies. Before publishing a new release you should bundle your code using ncc. After running npm install, run:
npm run buildThis invokes ncc build index.js -o dist, which produces a single file at dist/index.js containing all dependencies. Commit the dist/ directory to your repository and tag a new version. When the action runs, GitHub will execute the compiled file without needing to download npm packages.
This project is licensed under the MIT License. See LICENSE for details.