Block GitHub PRs with Exposed Secrets Using Rulesets


Direct answer: GitHub now lets eligible organizations block a pull request when it introduces an unresolved secret-scanning alert. In the repository, organization, or enterprise settings, open Repository → Rulesets, create or edit a branch ruleset, target the branches you protect, and enable Require secret scanning alerts are resolved. The pull request cannot merge until a scan finishes for its head commit and all alerts introduced by its commits are resolved.[1]

Availability: GitHub announced this rule in public preview for customers with GitHub Secret Protection or GitHub Advanced Security. Do not assume that ordinary free secret scanning on a public repository includes this merge-blocking rule; check whether the option appears in your ruleset editor.[1]

What the new merge rule checks

The rule performs two gates before allowing a merge:

  1. A secret scan must have completed for the pull request’s head commit.
  2. No secret-scanning alert introduced by the pull request’s commits can remain open.

Provider-pattern secrets are blocked by default. GitHub also lets administrators include categories such as custom or generic patterns. Developers who do not have bypass permission must resolve the blocking alert.[1]

Quick setup checklist

  • Confirm GitHub Secret Protection or GitHub Advanced Security is available for the selected repositories.
  • Confirm secret scanning is enabled and producing alerts.
  • Choose the target branches, normally the default and release branches.
  • Decide whether custom and generic patterns should block merges.
  • Review bypass actors; keep the list narrow and auditable.
  • Test with a harmless custom pattern—not a real credential.
  • Document how developers rotate a credential and close an alert.

How to enable the rule in GitHub

1. Open the ruleset editor

Open the repository, organization, or enterprise settings and navigate to Repository → Rulesets. Create a new branch ruleset or edit the ruleset that already protects your default branch. GitHub rulesets can apply at repository or organization scope, and multiple applicable rulesets are combined; when versions of the same rule conflict, the most restrictive version applies.[4]

2. Target the branches that receive pull requests

Include the default branch and any release branches that must not accept exposed credentials. Avoid selecting every branch without considering developer workflows. The meaningful protection is on branches where pull requests are merged and released.

3. Enable the secret-scanning resolution rule

Select Require secret scanning alerts are resolved. Start with provider patterns if you want the lowest-noise rollout. Add custom patterns for organization-specific token formats, or generic patterns when your team has a process for reviewing broader matches.[1]

4. Review bypass permissions

Rulesets can grant bypass rights to selected roles, teams, users, or GitHub Apps. A bypass is operationally useful for emergencies, but broad bypass access weakens the control. GitHub’s ruleset documentation confirms that administrators can explicitly configure who may bypass a rule.[4]

5. Save and test before broad rollout

Use a non-production repository first. Define a harmless custom pattern such as a clearly fake prefix, commit a matching dummy string on a test branch, and open a pull request. Never use a live API key for testing.

Safe test plan

  1. Create a temporary test repository covered by the required security license.
  2. Enable secret scanning and define a custom pattern that matches only a fake value such as DEMO_LEAK_[A-Z0-9]{12}.
  3. Add DEMO_LEAK_ABC123DEF456 to a text fixture on a branch.
  4. Open a pull request into the protected branch.
  5. Confirm the merge control waits for the head-commit scan and blocks while the introduced alert is open.
  6. Remove the dummy value, close the alert with the accurate resolution reason, and confirm the block clears after scanning completes.
  7. Delete the temporary pattern and repository when testing is complete.

This test validates the workflow without exposing a real credential. GitHub scans repository history for hardcoded credentials and can also inspect pull-request text and other collaboration surfaces, so test data should remain unmistakably fake.[5]

Audit the active rules from the command line

The GitHub REST API can list repository rulesets and return all active rules that apply to a specific branch. GitHub notes that rulesets in evaluate or disabled state are not returned by the active branch-rules endpoint.[3]

With GitHub CLI authenticated, list the repository’s rulesets:

OWNER="your-org"
REPO="your-repo"

gh api \
  -H "X-GitHub-Api-Version: 2026-03-10" \
  "/repos/$OWNER/$REPO/rulesets" \
  --jq '.[] | {id, name, enforcement, source_type}'

Then inspect all active rules that GitHub applies to the default branch:

BRANCH="main"

gh api \
  -H "X-GitHub-Api-Version: 2026-03-10" \
  "/repos/$OWNER/$REPO/rules/branches/$BRANCH"

For automation, GitHub identifies the REST rule type as require_secret_scanning_alert_resolution with a secret_types parameter. The GraphQL rule name is REQUIRE_SECRET_SCANNING_ALERT_RESOLUTION.[1] Retrieve the current ruleset first and preserve its conditions, bypass actors, and existing rules when updating it; do not overwrite a production ruleset with a minimal payload.

What developers should do when a PR is blocked

Do not merely delete the string and declare the incident closed. GitHub advises treating a committed secret as compromised. Review where it was used, rotate or revoke it, update dependent services, and check relevant security logs for unauthorized activity.[2]

  1. Open the repository’s Security and quality → Secret scanning view.
  2. Inspect the alert and identify the credential owner and affected service.
  3. Revoke or rotate the credential before relying on code cleanup.
  4. Update applications, CI variables, deployment environments, and integrations that used the old value.
  5. Remove the secret from the pull request and push the correction.
  6. Close the alert using the truthful resolution reason and add an audit comment when useful.
  7. Wait for secret scanning to finish on the new head commit, then re-check the merge status.

Removing the token from the repository does not automatically close the secret-scanning alert. GitHub says the alert must be closed manually, and the ruleset may continue blocking until the scan of the pull request’s head commit completes.[2]

Ruleset versus push protection

Control Where it acts Main purpose
Push protection At push time Stops a detected secret before it reaches the repository.
Secret-alert resolution ruleset At pull-request merge time Blocks merging when the pull request introduced an unresolved alert or its head scan has not completed.

These controls complement each other. GitHub specifically describes the ruleset as an additional pull-request layer for cases push protection did not catch or was not configured to catch—for example, when generic patterns are excluded from push protection but included in the merge rule.[1]

Recommended rollout for organizations

Phase 1: Inventory

  • List repositories that contain deployable code or infrastructure.
  • Confirm secret scanning status and security-plan coverage.
  • Document default branches, release branches, and existing rulesets.

Phase 2: Pilot

  • Enable the rule on a small set of representative repositories.
  • Start with provider patterns.
  • Measure blocked pull requests, alert resolution time, and bypass use.
  • Train responders to rotate first and close alerts accurately.

Phase 3: Expand carefully

  • Apply an organization ruleset to selected repository groups.
  • Add custom patterns only after validating them with fake samples.
  • Introduce generic patterns after teams understand likely false positives.
  • Review bypass actors and stale exceptions on a schedule.

Troubleshooting

The option is missing

Check plan eligibility and whether GitHub Secret Protection or GitHub Advanced Security is enabled for the target repository. The merge-blocking feature was announced as a public preview for those customers.[1]

The PR remains blocked after the code was fixed

Open the alert and verify that it has been closed with the correct resolution. Secret scanning does not automatically close the alert merely because the token was removed. Then wait for the scan on the latest head commit to finish.[2]

The branch has stricter behavior than expected

Inspect repository- and organization-level rulesets. Applicable rules are aggregated, and the most restrictive form wins when rules overlap.[4]

The API audit does not show a ruleset

When using the active branch-rules endpoint, remember that rulesets in evaluate or disabled state are omitted. List all repository rulesets separately and inspect their enforcement values.[3]

Frequently asked questions

Does this replace push protection?

No. Push protection operates before a secret reaches the repository. The new rule is a separate merge-time layer for pull requests.[1]

Will deleting the exposed value unblock the pull request?

Not by itself. Rotate or revoke the compromised credential, remove it from the change, close the alert with the correct reason, and allow the new head-commit scan to complete.[2]

Can administrators include custom or generic secret patterns?

Yes. GitHub says provider patterns are blocked by default and other categories, including custom or generic patterns, can be configured.[1]

Can the rule be configured through an API?

Yes. GitHub lists require_secret_scanning_alert_resolution for REST and REQUIRE_SECRET_SCANNING_ALERT_RESOLUTION for GraphQL.[1]

Sources

  1. GitHub Changelog: Block pull requests with exposed secrets from merging
  2. GitHub Docs: Resolving alerts from secret scanning
  3. GitHub Docs: REST API endpoints for rules
  4. GitHub Docs: About rulesets
  5. GitHub Docs: Secret scanning

Leave a Comment

muddaser logo

Public Speaker, Softskills trainer and technology enthusiast

Contact

Muddaser Altaf

Social Address