A leaked API key can turn a normal code change into a security incident.

The problem is usually not that developers intentionally commit credentials. Secrets often enter a repository through configuration files, test data, copied examples, generated files, or a temporary debugging change. Once a secret reaches Git history, removing the line does not make the credential safe.

GitHub Secret Protection provides several controls for this problem. Secret scanning detects exposed credentials, while push protection can stop supported secrets before they reach the repository.

For development teams, the most useful approach is to treat secret protection as a prevention layer, not just an alerting system.

Secret Scanning vs Push Protection

These two capabilities solve different parts of the problem.

Capability

Purpose

When it acts

Secret scanning

Finds exposed secrets

After secrets exist in repository content

Push protection

Blocks supported secrets

Before the push reaches the repository

Custom patterns

Detects organization-specific secrets

During scanning and, when enabled, push protection

Validity checks

Helps determine whether supported secrets are active

During investigation

Merge protection

Prevents unresolved secret alerts from reaching protected branches

During pull request merge

Push protection is particularly important because it moves detection closer to the point where the mistake happens.

A developer can receive feedback during git push instead of discovering the problem after a pull request has already been opened.

How Push Protection Works

Suppose a developer accidentally adds a credential:

var apiKey = "example-secret-value";

The developer commits the change:

git add .
git commit -m "Add API integration"
git push origin feature/api-integration

If push protection recognizes the value as a supported secret, GitHub blocks the push.

The developer can then remove the secret and push the corrected commit.

The important part is that the secret did not become part of the remote repository through that push.

Push protection can cover secrets pushed from the command line and also applies to supported repository changes made through the GitHub user interface.

Why Blocking the Push Is Better Than Finding the Secret Later

Consider two workflows.

Without push protection

Developer writes secret
        |
        v
Commit created
        |
        v
Push succeeds
        |
        v
Pull request created
        |
        v
Secret detected
        |
        v
Credential must be rotated
        |
        v
Repository history must be cleaned

With push protection

Developer writes secret
        |
        v
Commit created
        |
        v
Push blocked
        |
        v
Secret removed
        |
        v
Push succeeds

The second workflow does not eliminate every possible leak, but it removes an important failure path.

It also gives the developer feedback while the change is still local and easy to fix.

What GitHub Secret Protection Can Detect

GitHub secret scanning supports several categories of patterns.

Provider patterns identify credentials associated with services such as cloud platforms and other third-party providers.

Generic patterns can identify secrets such as:

GitHub also supports AI-detected generic secrets for certain types of unstructured credentials.

The exact detection and push protection behavior depends on the secret pattern. Not every detected secret is automatically blocked by push protection.

That distinction matters when designing an organization's security policy.

Enable Push Protection at the Repository Level

For a repository using GitHub Secret Protection, the basic setup is straightforward.

Open the repository settings and go to the Advanced Security settings.

Enable Secret Protection if it is not already enabled.

Then enable:

Secret Protection
    |
    `-- Push protection

After that, pushes containing supported secrets can be blocked before they reach the repository.

The exact controls available depend on the repository type and GitHub plan.

For organizations, it is better to establish the policy centrally instead of asking every development team to configure repositories independently.

Custom Patterns for Internal Secrets

Standard secret patterns cannot cover every organization's credential format.

Suppose your company generates internal tokens with a format such as:

CORP_TOKEN_<environment>_<random-value>

A custom secret scanning pattern can be created using a regular expression.

A simplified example might look like:

CORP_TOKEN_[A-Z]+_[A-Za-z0-9]{32}

This is only an example. A real pattern should match the actual credential format and avoid matching ordinary application data.

Custom patterns can be created at the repository, organization, or enterprise level.

This is useful for internal credentials that are unknown to GitHub's standard provider patterns.

Test Custom Patterns Before Blocking Developers

A bad custom pattern can create a large number of false positives.

For example, suppose an organization creates a pattern that matches every string beginning with:

TOKEN_

A codebase may contain perfectly harmless values such as:

const string TOKEN_TYPE = "Bearer";

A broad pattern could start blocking legitimate development work.

Use the dry-run capability to evaluate a custom pattern before enabling push protection for it.

A sensible process is:

  1. Define the pattern.

  2. Test it with representative secret values.

  3. Run a dry run against the repository.

  4. Review detected matches.

  5. Fix false positives.

  6. Publish the pattern.

  7. Enable push protection when the detection quality is acceptable.

This is especially important at the organization or enterprise level because a noisy pattern can affect many repositories.

What Happens When a Push Is Blocked?

A blocked push is not automatically a security incident.

The developer should first determine whether the detected value is actually a secret.

For example:

Secret detected
      |
      +-- False positive
      |      |
      |      `-- Remove or appropriately bypass
      |
      `-- Real secret
             |
             +-- Remove from code
             +-- Rotate or revoke credential
             `-- Check whether it reached another system

Do not simply bypass the protection because the push is blocking the developer.

If the value is a real credential, it should be treated as compromised if it has already reached an environment where an unauthorized person could access it.

Bypass Is Not a Fix

GitHub provides bypass mechanisms because there are legitimate cases where a detected value is not actually a secret or where a specific workflow requires an exception.

That does not mean bypass should become the normal workflow.

A common mistake is:

Push blocked
   |
   v
Developer clicks bypass
   |
   v
Push succeeds

If developers repeatedly bypass the same pattern, the organization should investigate why.

Possible causes include:

The correct response is to improve the detection rule or development workflow, not simply increase the number of bypasses.

Keeping Secrets Out of Source Code

Push protection is only one part of a secure application.

Application code should not contain production credentials such as:

var connectionString =
    "Server=db01;User Id=app;Password=real-password;";

Instead, use the application's supported configuration and secret-management mechanisms.

For example:

var connectionString =
    configuration.GetConnectionString("ApplicationDatabase");

The application receives the value through its runtime configuration rather than storing the credential in source control.

For local development, use an appropriate developer-specific secret mechanism. For CI/CD, use the secret storage capabilities of the CI platform or an external secret manager.

The goal is simple: source code should contain references to configuration, not production credentials.

Protecting Pull Request Merges

Preventing secrets from entering a repository is the first layer.

You can also protect important branches by requiring secret scanning alerts to be resolved before merging.

This creates another control:

Developer
   |
   v
Push protection
   |
   v
Pull request
   |
   v
Secret scanning
   |
   v
Merge protection
   |
   v
Protected branch

This is useful because push protection does not catch every possible secret, and some alerts can be created through workflows other than a normal developer push.

A merge rule provides another checkpoint before code reaches a protected branch.

What Push Protection Does Not Solve

Push protection is not a complete secret-management system.

It does not mean that every credential will be detected.

Detection depends on supported patterns, configuration, and the form in which the secret appears.

For example, an application may construct a credential dynamically:

var token = prefix + valueFromConfig;

A scanner may have less information to work with than it would for a recognizable token format.

There can also be secrets stored in encrypted files, generated artifacts, unusual formats, or third-party systems that are not covered by the configured detection patterns.

This is why developers still need good secret-handling practices.

Common Mistakes

Treating Secret Scanning as a Replacement for Secret Management

Secret scanning detects problems. It does not provide a secure place to store application credentials.

Use an appropriate secret-management mechanism for runtime credentials.

Putting Fake Secrets Directly in Tests

Even fake credentials can look like real credentials to automated scanners.

Prefer clearly synthetic values that cannot be confused with production credentials.

For example:

const string TestApiKey = "test-only-value";

Do not copy a real production token into a test just because the test environment is supposed to be isolated.

Ignoring a Blocked Push

A blocked push is useful feedback.

Developers should inspect the detected value rather than immediately bypassing the protection.

Creating Broad Custom Patterns

A pattern that matches too much creates false positives and encourages developers to bypass security controls.

Test custom patterns before enabling enforcement.

Assuming Removing a Secret From the Latest Commit Is Enough

If a real secret was pushed, simply deleting the line in a later commit does not make the credential safe.

The credential itself should be rotated or revoked, and the repository history should be reviewed according to the organization's incident-response process.

Recommended Team Workflow

A practical workflow looks like this:

  1. Enable Secret Protection for repositories that handle sensitive application code.

  2. Enable push protection to block supported secrets before they reach the repository.

  3. Review supported patterns and understand which secret types are protected.

  4. Create custom patterns for important internal credential formats.

  5. Dry-run custom patterns before enforcing them.

  6. Protect important branches from unresolved secret scanning alerts.

  7. Teach developers how to respond to blocked pushes instead of bypassing them automatically.

  8. Rotate real credentials immediately when they have been exposed.

  9. Review bypass activity to identify recurring false positives or process problems.

Advantages and Disadvantages

Advantages

Disadvantages

Final Checklist

Before enabling GitHub Secret Protection across a development organization, verify:

Check

Recommended approach

Secret scanning

Enable for repositories containing sensitive code

Push protection

Enable for supported secret patterns

Custom secrets

Define organization-specific patterns

Custom pattern testing

Use dry runs before enforcement

Pull request protection

Require relevant alerts to be resolved

Developer workflow

Document how to handle blocked pushes

Bypasses

Restrict and review them

Exposed credentials

Rotate or revoke immediately

Application configuration

Keep production secrets outside source code

Conclusion

The best time to detect a leaked secret is before it reaches the repository.

GitHub Secret Protection provides that prevention layer through push protection, while secret scanning provides broader detection for credentials that already exist in repository history or other scanned content.

For most teams, the practical approach is to combine push protection with custom patterns, pull request controls, proper secret storage, and a clear remediation process.

The security control works best when developers understand that a blocked push is not an obstacle to work around. It is an early warning that gives them a chance to fix the problem before the credential becomes a repository-level security issue.