Join our Newsletter — 33% off our NHI Course
Home› Guides› How to respond to a GitHub secret scanning…
Guide Secrets Management

How to respond to a GitHub secret scanning alert

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 11 November 2026 13 min read
On this page

A GitHub secret scanning alert means a working credential may already be in someone else's hands, yet many alerts are closed by deleting the line of code, which removes nothing. GitHub's own position is that once a secret has been committed you should consider it compromised, and that secret scanning does not close an alert when the secret is removed from the repository. This guide is the runbook for one alert: read what GitHub tells you about it, decide urgency, contain the credential with its provider, check what it was used for, and close the alert with the right resolution and evidence. It is for repository administrators, security engineers and the developers who own the leaked credential. The wider triage process across many alerts and tools is in Developer Secret Scanning Triage.

This is an independent guide from NHI Mgmt Group, based on GitHub Docs as of November 2026. It is not sponsored or reviewed by GitHub. Several features named here (on-demand metadata, report leak) are in public preview and may change.

Key takeaways

  • Removing the commit is not remediation. The secret stays in history, forks and clones, and the alert stays open; only revoking or rotating at the provider ends the exposure.
  • Read the alert's labels first. Validity active, a public leak label or a multi-repo label each raise urgency and change who you need to involve.
  • Rotate before you report or rewrite. GitHub advises rotating first because reporting a leak may get the secret revoked, and rewriting history is a hygiene step that comes last.
  • Check usage from first commit to revocation. An inactive secret can still have been used while it was live; review the provider's logs either way.
  • Close with the true reason and a comment. The resolution and comment become the audit record, and the API does not let you edit the comment afterwards.

When you need this

Alert typeWhere it appearsYour action
User alertRepository Security and quality > Secret scanning (generic and AI-detected patterns are listed separately)Follow this runbook
Push protection alertSame list, created when a contributor bypasses repository-level push protection; filter with bypassed: trueFollow this runbook and review the bypass reason with the contributor
Partner alertSent to the secret's provider for public repositories and npm packages, not to repository adminsGitHub says no action is needed for this type, but expect the provider to revoke the secret; check for breakage

Bypassing user-level push protection does not create an alert, so it is not covered by this list. Setting up push protection itself is covered in How to enable GitHub secret scanning push protection.

Before you start

  • Access: viewing and closing alerts needs repository admin, organisation owner or security manager rights. For the REST API, a fine-grained token needs the "Secret scanning alerts" repository permission (read to list, write to update); a classic token needs repo or security_events.
  • Owner of the credential: identify who can revoke it at the provider. For a cloud key that is the account owner, not the developer who committed it.
  • Do not copy the secret around: work from the alert view and the provider console. Pasting the value into tickets or chat creates new leaks; the API's hide_secret parameter keeps the value out of list output.
  • Clock: note the alert creation time and the commit date of the first location; usage review covers that whole window.

Step-by-step

Steps 1 to 3 are read-only. Step 4 changes the credential at its provider. Step 6 changes the alert. Step 7 is optional and disruptive.

  1. Open the alert and read its signals. In the repository go to Security and quality > Secret scanning and open the alert, or fetch it:
    GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}
    GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations
    Record the secret type, every location (file, commit, and whether it also appears in issues, pull requests or wikis), the validity, and labels. The table below sets urgency.
  2. Decide urgency.
    SignalMeaning (GitHub Docs)Response target
    Validity activeGitHub checked with the provider and the secret worksContain within hours
    Validity unknownPossibly active: validation not supported for the type or could not be verifiedTreat as active until the owner confirms
    Validity inactiveSecret no longer worksStill review usage for the period it was live
    public leak labelAlso found in GitHub's public scans of code, discussions, gists, issues, pull requests or wikisHighest urgency; GitHub notes this may need more urgent or different remediation
    multi-repo labelSame secret found in several repositories in the organisation or enterpriseOne rotation, many alerts: coordinate and close them together
    Bypassed push protectionA contributor pushed despite the blockConfirm the bypass reason was true
    For GitHub tokens that are active, GitHub can show token metadata (public preview): secret owner, creation and expiry dates, last used date and whether it has organisation access. For a small set of third-party types (currently OpenAI, Google OAuth, Slack and Replicate) extended metadata such as owner and issue date may be shown. Use these to find the owner fast.
  3. Confirm it is a real secret. A string that is genuinely a test fixture, a revoked sample or a false match should be closed with the matching reason in step 6, with evidence. If in doubt, it is real.
  4. Contain at the provider: revoke or rotate. Create the replacement, update the services that use it, then revoke the leaked one. OWASP's Secrets Management Cheat Sheet orders the response as revoke, rotate, delete and log, with rapid containment as the goal. For credentials that production depends on, a short overlap avoids an outage; for an active secret with a public leak, revoke first and accept the outage. Provider runbooks: How to revoke a leaked GitHub personal access token and check what it touched, How to rotate an AWS IAM access key without downtime, How to rotate Entra app secrets without downtime and How to rotate database credentials without downtime. For a GitHub personal access token in a private repository that you cannot reach the owner of, the alert offers Report leak (public preview), after which GitHub treats it like a publicly leaked secret and revokes it.
  5. Review what the secret did. Check the provider's security or audit logs from the first commit date to the revocation time for calls from unexpected addresses, user agents or regions. GitHub's guidance is to check logs even when the secret is inactive. For GitHub tokens, the organisation audit log is the source; see the GitHub Audit Log Detection Guide. If you find misuse, this is now an incident: hand over to the Leaked Credential Response Playbook. The Home Depot Token Exposure 2025 shows what a long window between exposure and revocation looks like.
  6. Close the alert with the right resolution. In the alert, open Close as, choose the reason, add a comment and select Close alert. Through the API:
    PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}
    {"state": "resolved", "resolution": "revoked",
     "resolution_comment": "Revoked at provider 2026-11-11 10:42 UTC; logs reviewed, no misuse; ticket SEC-1234"}
    The comment is stored on the alert timeline and cannot be updated or deleted afterwards, so write it once, completely.
  7. Clean the history only if it is still needed. GitHub's guidance is that revoking or rotating may solve the problem without rewriting history. If you must remove the value (for example a secret you cannot rotate), use git-filter-repo 2.47 or later with --sensitive-data-removal, and expect side effects: changed commit hashes, removed signatures, broken diffs on closed pull requests, and recontamination from old clones. Cached views and pull request references need GitHub Support, and forks need their owners. See How to Remove Secrets From Git History.

Containment by secret type

Secret type in the alertWho revokesContainment notesRunbook
GitHub personal access tokenThe token owner, or GitHub through Report leak for private repositoriesToken metadata shows owner and organisation access while the token is activeLeaked GitHub token
Cloud access keyCloud account administratorDeactivate first if production depends on it, then delete; review the cloud audit trail by key IDCloud Access Key Leak Playbook
Entra or other app client secretApp registration ownerRemove the credential by its key ID; check service principal sign-insRotate Entra app secrets
Database connection stringDBAChange the password and end existing sessions; a password change alone does not disconnect themRotate database credentials
SaaS API tokenSaaS tenant administratorMany SaaS tokens cannot be scoped down after issue; replace with a narrower tokenWork SaaS API tokens
Private key (TLS, SSH)Certificate or host ownerRevoke or remove the public key everywhere it is trustedLeaked TLS Private Key Response

Choosing the resolution

API resolutionUse whenEvidence to put in the comment
revokedThe credential has been revoked or rotated at the providerRevocation time, who did it, log review result, ticket
false_positiveThe match is not a credentialWhy it is not a secret; consider a custom pattern or exclusion fix
used_in_testsA deliberate test credential with no access to anything realWhere it is used, proof it grants no access
wont_fixA real secret you have accepted the risk forRisk owner, reason, expiry of the acceptance; should be rare

The API also reports pattern_edited and pattern_deleted for custom pattern alerts, but you cannot set those yourself. Closing a real, live secret as false_positive or used_in_tests to clear a dashboard is the most damaging shortcut in this process.

Evidence to preserve

If the log review in step 5 finds anything unexpected, the alert becomes an incident and the evidence you kept decides how well you can scope it. Capture these before anyone rewrites history or deletes branches:

EvidenceWhere it comes fromWhy it matters
Alert record and locationsAlert view or the alert and locations endpoints, saved as JSONFirst commit, author, file path and every place the secret appeared
Commit and push detailsCommit SHA, pusher, push time, branch and whether it reached a default branchExposure start time and who could have seen it; SHAs change if history is rewritten later
Repository visibility historyOrganisation audit logA repository made public, even briefly, widens the audience
Fork and clone exposureForks list and repository traffic dataCopies you cannot clean yourself
Provider activityCloud trail, SaaS audit log or token usage log for the credentialShows whether the secret was used and from where
Revocation proofProvider console or API response, with timestampExposure end time for any notification decision

Store this in the incident ticket, not in the repository. Never attach the secret value itself. If personal data could have been reached with the credential, involve your privacy team early, because breach notification rules such as UK GDPR and EU GDPR Article 33 set a 72-hour clock from awareness for reportable personal data breaches.

Small team or large organisation

  • Small team: the repository admin runs this runbook end to end. Enable notifications for the repository's security alerts so an alert is not found weeks later.
  • Large organisation: work from the organisation endpoint GET /orgs/{org}/secret-scanning/alerts?state=open&validity=active,unknown, work the subsets returned with is_publicly_leaked=true and is_multi_repo=true first, and assign each alert with the API's assignee field to the credential owner. Organisation-wide listing needs an organisation owner or security manager.
  • Regulated environments: agree in advance which alerts count as a security incident (for example an active cloud key with a public leak) so notification clocks are not missed.

Detection and measurement

  • Alert activity: stream secret scanning alert events to your SIEM through the secret_scanning_alert webhook or the audit log, so new alerts open a ticket automatically.
  • Bypasses: review every push protection bypass weekly; repeat bypassers need coaching or a review requirement.
  • Use after revocation: failed authentications with the revoked credential at the provider show which systems you missed.

Metrics:

  1. Median time from alert creation to provider revocation for active alerts.
  2. Open alerts with validity active or unknown, by age band.
  3. Share of closures with resolution revoked against wont_fix and used_in_tests.
  4. Alerts closed without a comment (target zero).
  5. Push protection bypasses per month.

Common failure patterns

  • Delete the line, close the alert: the secret still works and is still in history; the alert was the only record.
  • Rewriting history before revoking: it takes hours, breaks clones and leaves the credential live the whole time.
  • Trusting inactive: an expired or revoked secret may have been used before it stopped working.
  • Fixing one of a multi-repo set: the same secret in other repositories, CI variables or wikis is forgotten.
  • Developers rotating keys they do not own: they create a new key but cannot revoke the old one at the provider, so both stay live.

Where identity fits

Most secret scanning alerts are non-human identity credentials: API keys, tokens, service account keys and connection strings. The lasting fix is to stop issuing long-lived secrets to code: use workload identity federation for CI, as in the GitHub Actions OIDC Federation Hardening Guide, and short-lived tokens elsewhere. Each alert should end with a question: can this credential be removed rather than replaced?

Framework mapping

FrameworkReferenceRelevance
NIST SP 800-53 Rev 5IR-4 Incident HandlingContainment, eradication and recovery for a leaked credential
NIST SP 800-53 Rev 5IA-5 Authenticator ManagementChanging authenticators on compromise
NIST CSF 2.0RS.MI-01Incidents are contained
NIST CSF 2.0PR.AA-01Credentials for services are managed by the organisation
MITRE ATT&CKT1552.001 Credentials In Files; T1593.003 Code Repositories; T1213.003 Code RepositoriesAttackers search public and internal repositories for secrets

Practitioner checklist

  • Open the alert and record type, locations, validity and labels.
  • Set urgency: active or public leak means contain within hours.
  • Find the credential owner at the provider.
  • Rotate, update dependent services, then revoke the leaked credential.
  • Review provider logs from first commit to revocation, even if inactive.
  • Close the alert with the true resolution and a complete comment.
  • Rewrite history only if revocation is not possible or policy requires it.
  • Record whether the credential can be replaced by federation or short-lived tokens.

Standards and references

Related NHI Mgmt Group resources: Git Secret Scanning Guide · Developer Secret Scanning Triage · How to revoke a leaked GitHub personal access token and check what it touched · Leaked Credential Response Playbook

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org