I’ll admit, for a long time I assumed GitHub’s built-in security features were “nice to have” rather than essential. That changed the day GitHub emailed me about a token it had automatically detected and revoked in one of my repos before I’d even noticed it was there. That single notification is what got me to actually understand how secret scanning works — and now I make sure it’s enabled on every repository I touch.
What Is GitHub Secret Scanning?
GitHub Secret Scanning is a built-in security feature that automatically scans repository content — including commits, issues, and even wiki pages — for patterns that match known secret formats: API keys, tokens, credentials, and certificates from hundreds of service providers.
When it detects a match, it does one of two things depending on your configuration:
- Alerts you after the secret has been pushed (standard secret scanning)
- Blocks the push entirely before the secret ever reaches the repository (push protection)
flowchart LR
A[git push] --> B{Push Protection Enabled?}
B -->|Yes| C[Scan commit content]
C --> D{Secret Pattern Detected?}
D -->|Yes| E[Block push, notify developer]
D -->|No| F[Push allowed]
B -->|No| G[Push allowed]
G --> H[Scan runs after push]
H --> I{Secret Found?}
I -->|Yes| J[Alert repo admins]
How GitHub Detects Secrets
GitHub maintains partnerships with major service providers (AWS, Stripe, Twilio, Google Cloud, Slack, and hundreds of others) who supply the exact token formats their platforms issue. This means GitHub isn’t guessing based on generic patterns — it’s matching against real, known token structures, which keeps false positives relatively low.
For providers that participate in the partner program, GitHub can even notify the provider directly, allowing them to automatically revoke the leaked credential — which is exactly what happened in my case above.
Secret Scanning vs. Push Protection
These two features are related but distinct, and I think this is where most people get confused:
| Feature | When It Runs | What It Does |
|---|---|---|
| Secret Scanning | After a push | Detects and alerts on secrets already in the repo |
| Push Protection | Before a push | Blocks the push if a secret is detected |
I strongly recommend enabling both. Push protection is your prevention layer; secret scanning is your safety net for anything that slips through (like secrets already in history before you enabled the feature).
How to Enable Secret Scanning
For public repositories, secret scanning is enabled automatically and free. For private repositories, you’ll need GitHub Advanced Security (available with GitHub Enterprise, or as an add-on for certain plans).
Steps I follow to enable it at the repository level:
- Go to Settings → Code security and analysis
- Enable Secret scanning
- Enable Push protection
- Optionally, enable validity checks, which tells you whether a detected secret is still active
At the organization level, I set these as default policies so every new repository inherits them automatically, rather than relying on individual developers to turn them on.
What to Do When a Secret Is Detected
When GitHub flags a secret, I follow the same process every time:
- Assume it’s compromised — treat the exposure as real regardless of how briefly it was public.
- Revoke and rotate the credential immediately at the source (AWS console, Stripe dashboard, etc.). This is the step that actually neutralizes the risk — more detail in Secret Rotation Best Practices.
- Remove it from Git history using
git filter-repoor BFG Repo-Cleaner if it needs to be purged. - Investigate usage logs for the credential to check for unauthorized access during the exposure window.
- Document the incident so the team can learn from how it happened.
GitHub Secret Scanning vs. Third-Party Tools
GitHub’s native scanning is excellent for what it covers, but I still layer third-party tools like gitleaks or trufflehog into my CI pipeline for a few reasons:
- Broader custom pattern support for internal, non-standard secret formats
- Works across GitLab, Bitbucket, and local development too
- Can scan full history more flexibly during audits
I go into more detail on this layered approach in How to Prevent Secret Leaks in Git Repositories.
Common Mistakes I See With Secret Scanning
- Assuming secret scanning is enabled automatically on private repos — it isn’t, without Advanced Security
- Enabling scanning but not push protection, so leaks are only caught after the fact
- Not setting organization-wide defaults, leaving new repos unprotected
- Ignoring alerts because a repo is “internal only”
- Failing to rotate a credential after GitHub flags it, assuming deletion is enough
Best Practices Checklist
| Practice | Benefit |
|---|---|
| Enable push protection | Stops leaks before they happen |
| Enable secret scanning org-wide | Ensures consistent coverage |
| Pair with pre-commit hooks | Catches issues even earlier |
| Rotate immediately on alert | Neutralizes actual risk |
| Review scanning alerts regularly | Prevents alert fatigue from missing real issues |
FAQs
Is GitHub Secret Scanning free? Yes, for public repositories. For private repositories, it requires GitHub Advanced Security, which is included with GitHub Enterprise or available as an add-on.
Does secret scanning catch every type of secret? It catches known patterns from partner providers very reliably, but custom or internal secret formats may need a supplementary tool with custom regex rules, like gitleaks.
Does push protection ever produce false positives? Occasionally, especially with high-entropy strings that resemble tokens. GitHub allows you to bypass with a justification, but I recommend treating each bypass as something to review afterward.
What happens if I ignore a secret scanning alert? The credential stays exposed and exploitable. Alerts don’t automatically revoke anything (except for a subset of partner-integrated providers) — you have to act on them.
Conclusion
GitHub Secret Scanning and push protection together form one of the most effective, lowest-effort defenses against accidental credential leaks. Enabling both at the organization level, pairing them with pre-commit hooks, and having a clear rotation process for anything that’s flagged gives you coverage at nearly every point a secret could slip through. It’s one of the easiest security wins available, and there’s really no good reason not to have it turned on.
