Secret Scanning & Push Protection

Accidentally committing secrets to GitHub is one of the most common and dangerous security mistakes. Secret scanning detects exposed credentials in your repository, and push protection blocks them before they ever reach GitHub—keeping your tokens, keys, and passwords safe from attackers.

Secret Scanning Push Protection Token Leak Prevention
What is Secret Scanning?

Secret scanning is a GitHub security feature that automatically scans your repositories for accidentally committed secrets. It looks for patterns that match known credential formats—AWS access keys, GitHub tokens, Slack webhooks, API keys, database passwords, and hundreds of other secret types. When a secret is detected, GitHub creates an alert and notifies the repository administrators and the affected service provider, who can revoke the compromised credential.

This feature is critical because once a secret is committed to Git, it remains in the repository history forever unless explicitly removed. Attackers routinely scrape GitHub for exposed secrets, and compromised credentials can lead to data breaches, unauthorized cloud resource usage, and serious security incidents. Secret scanning acts as a safety net, catching mistakes before they become disasters.

According to GitHub, secret scanning helps thousands of organizations detect and remediate exposed credentials every day. Many of these would otherwise go unnoticed until after they were exploited.
Supported Secret Types

GitHub's secret scanning detects over 200 different secret patterns from dozens of service providers. Here are some of the most commonly detected types:

Cloud Providers: AWS access keys and secret keys, Azure credentials, Google Cloud service account keys, DigitalOcean tokens, and more.

Code Platforms: GitHub personal access tokens, GitHub App tokens, GitLab tokens, Bitbucket credentials.

Communication Tools: Slack webhooks and tokens, Discord webhooks, Microsoft Teams webhooks, Twilio credentials.

Database & Services: PostgreSQL, MySQL, MongoDB connection strings, Redis credentials, Stripe API keys, PayPal credentials, SendGrid API keys.

Tokens & Keys: JSON Web Tokens (JWT), SSH private keys, RSA private keys, PGP private keys, TLS certificates.

For private repositories, secret scanning also includes high-confidence patterns for generic secrets and custom patterns you can define yourself.

If a secret pattern isn't covered by GitHub's built-in detectors, you can create custom patterns to scan for your organization's specific credential formats.
How Secret Scanning Works

Secret scanning runs continuously across your repositories. When you push code, when new secrets are added to the advisory database, and on a scheduled basis, GitHub scans both the current content and the entire commit history for secret patterns.

When a match is found, several things happen. First, an alert is created in the repository's Security tab, showing the secret type, location (file and line number), and the time it was detected. Second, GitHub notifies the repository administrators and users who have access to the security alerts. Third, for many partner services, GitHub automatically notifies the service provider, who can revoke the exposed credential to prevent abuse.

For public repositories, secret scanning is completely free and enabled by default. For private repositories, it's included in GitHub Advanced Security, which is available with GitHub Enterprise plans. Once a secret is detected, you can view the alert, follow remediation steps, and mark it as resolved after the secret is revoked and removed from history.

# Example secret scanning alert details
Secret type: AWS Access Key
Location: src/config.js line 15
Detected: 2 hours ago
Status: Open

Remediation steps:
1. Revoke the exposed credential in your cloud provider
2. Remove the secret from your repository history
3. Use GitHub Secrets or environment variables instead
Push Protection: Block Secrets Before They Reach GitHub

While secret scanning catches secrets after they're committed, push protection stops them from being pushed in the first place. When push protection is enabled, any attempt to push code containing a detected secret is blocked at the command line. The developer sees a clear error message explaining which secret was detected and in which file.

This is a game-changer for security. Instead of discovering secrets days or weeks later, developers get immediate feedback and can remove the secret before it ever reaches the remote repository. Push protection supports the same secret patterns as secret scanning and can be enabled for specific repositories or at the organization level.

When a push is blocked, the developer has several options. They can remove the secret from the files being pushed, rewrite history to remove it from earlier commits, or—if they're certain it's a false positive—use a bypass token to override the protection. Bypasses are logged for audit purposes.

# Push protection error message
$ git push origin main
remote: error: GH013: Push contains a secret detected by push protection.
remote: Scanning for known secrets (14.7 MB scanned)
remote:
remote: secret: AWS_ACCESS_KEY_ID (AKIAXXXXXXXXXXXXXXXX)
remote: locations:
remote: - src/aws_config.js:3
remote:
remote: To push, remove the secret from the commit history,
remote: or use a bypass token with `git push --push-option=...`
error: failed to push some refs to 'https://github.com/user/repo.git'
Push protection is the most effective way to prevent secret leaks. It catches mistakes at the moment they happen, before they can cause damage.
How to Enable Secret Scanning and Push Protection

For public repositories, secret scanning is enabled by default. You can verify this by going to your repository's Settings → Security & analysis. For private repositories, you'll need GitHub Advanced Security enabled on your organization.

To enable push protection, navigate to Settings → Code security and analysis → Push protection. Click "Enable" to turn it on. You can enable it for all repositories in an organization, or for specific repositories. Once enabled, any push containing a detected secret will be blocked.

You can also configure custom patterns if your organization uses proprietary credential formats. Go to Settings → Code security and analysis → Secret scanning → Custom patterns. Define a regular expression pattern, provide a description, and test it against sample code. Custom patterns apply to both secret scanning and push protection.

# Custom pattern for internal API keys
Pattern: (internal-api-key-[A-Za-z0-9]{32})
Description: Internal API keys used by our services

# Sample matches:
internal-api-key-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
How to Respond to Secret Alerts

When you receive a secret scanning alert, take immediate action. The first step is to revoke the exposed credential at the service provider. For AWS keys, go to the AWS console and delete or deactivate the key. For GitHub tokens, regenerate them. This prevents attackers from using the exposed secret, even if it's still in your repository history.

Next, remove the secret from your repository. If it was just added in the most recent commit, you can use git commit --amend to remove it. If it's deeper in history, you'll need to use git filter-repo or BFG Repo-Cleaner to rewrite history and remove the secret from all commits. After cleaning, force-push to update the remote repository.

Finally, back in GitHub, mark the alert as resolved. This removes it from the active alerts list. Document the incident and consider reviewing your development practices to prevent similar leaks in the future—like using environment variables or GitHub Secrets instead of hardcoding credentials.

# Remove a secret from the most recent commit
git commit --amend
# Remove the secret from the file, then save and close
git push --force-with-lease origin main

# Remove a secret from entire history using BFG
bfg --replace-text passwords.txt my-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push --force-with-lease
Removing secrets from Git history rewrites commits. Coordinate with your team before doing this, as everyone will need to re-clone the repository.
Best Practices for Secret Management

Never hardcode secrets. This is the most important rule. Secrets should never appear in source code. Use environment variables, configuration files outside version control, or secret management tools.

Use GitHub Secrets for Actions. When using GitHub Actions, always store credentials in repository secrets. They're encrypted and never appear in logs.

Enable push protection on all repositories. This creates a safety net that catches mistakes immediately, preventing secrets from ever reaching GitHub.

Rotate secrets regularly. Even without exposure, regular rotation limits the window of opportunity if a secret is compromised without your knowledge.

Use OIDC when possible. OpenID Connect allows GitHub Actions to authenticate to cloud providers without storing any long-lived secrets at all.

Audit your repository history. Even with protections, periodically scan your repository for any missed secrets. Tools like truffleHog or gitleaks can help.

Train your team. Developers are the first line of defense. Make sure everyone understands why secrets should never be committed and how to use environment variables and secret stores.

A well-implemented secret management strategy combines prevention (push protection), detection (secret scanning), and rapid response (alert remediation). Each layer adds critical protection.
Frequently Asked Questions
Is secret scanning free for public repositories?
Yes! Secret scanning is completely free for all public repositories. For private repositories, it's included in GitHub Advanced Security, which requires a GitHub Enterprise license.
What happens when a secret is detected?
GitHub creates an alert in the Security tab, notifies repository administrators, and for many partner services, automatically notifies the service provider so they can revoke the exposed credential.
Can I bypass push protection if I need to push a legitimate secret?
Yes. You can use a bypass token provided in the error message. However, this is logged and should be used sparingly. For legitimate secrets, consider using environment variables or GitHub Secrets instead.
What if secret scanning reports a false positive?
You can mark the alert as "false positive" in the GitHub UI. GitHub uses this feedback to improve its detection algorithms. You can also create custom patterns to exclude certain formats.
How do I remove a secret that was committed in the past?
Use git filter-repo or BFG Repo-Cleaner to rewrite history and remove the secret from all commits. After cleaning, force-push to update the remote. All collaborators must re-clone after this operation.
Can I create custom secret patterns for my organization?
Yes, with GitHub Advanced Security. You can define regular expression patterns for your organization's proprietary credential formats, and they'll be scanned along with GitHub's built-in patterns.
Does secret scanning check commit history or just the latest code?
Both. Secret scanning scans the entire repository history, including all commits, branches, and tags. This ensures that even if a secret was committed and later removed, it's still detected and alerted.
How quickly are secrets detected after a push?
Secret scanning runs continuously. Most secrets are detected within minutes of being pushed. Push protection blocks them instantly, preventing them from reaching the remote repository at all.
Previous: Dependabot Alerts Next: Code Scanning

Secrets are the keys to your infrastructure. Protect them with secret scanning and push protection, and build a culture of security in your development workflow.