Join our Newsletter — 33% off our NHI Course
Home› Guides› Developer Secret Scanning Triage: Prioritise real leaks and…
Guide Application Security

Developer Secret Scanning Triage: Prioritise real leaks and close false positives safely

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 28 October 2026 14 min read
On this page

Secret scanners find far more alerts than security teams can investigate, and most organisations end up with thousands of open findings that nobody owns, while the few live, privileged credentials among them stay valid for months. The scanner is rarely the problem. The missing piece is a triage process that decides quickly which findings are real, which are dangerous, who must act and how a false positive gets closed without hiding a true one. This guide gives engineering and AppSec teams that process: a prioritisation model based on validity, privilege and exposure, close reasons that stand up to audit, suppression rules that do not become blind spots, routing to owners and measurable service levels. It assumes you already run scanning; deployment of scanners and push protection is covered in the Git Secret Scanning Guide.

Key takeaways

  • Validity first, then privilege, then exposure. A verified, active credential with production write access in a public repository is an incident. An unverified test key in a private fixture is housekeeping. Score every alert on those three factors before anyone opens it.
  • Inactive does not mean safe. GitHub's guidance is that a committed secret should be treated as compromised and that inactive secrets still need a check that no unauthorised access happened before deactivation.
  • Close reasons are evidence. Use a fixed set (revoked, false positive, used in tests, won't fix) with a mandatory comment. GitHub stores the resolution comment in the alert timeline and it cannot be edited later, which makes it useful audit evidence.
  • Suppress narrowly. Fingerprint-level ignores and inline allow markers are safer than path or regex allowlists that silently cover future real secrets.
  • Revocation, not deletion, ends the incident. Removing the file or rewriting history leaves the credential valid. The fix is revoke, rotate, check usage logs, then clean up.

What triage has to decide

Every secret alert needs four answers, in this order. Teams that skip straight to "who committed this" lose hours on alerts that did not matter while live credentials wait.

  1. Is it a real secret? True positive, false positive (a pattern match on something that is not a credential), or a deliberate test value.
  2. Is it still valid? Confirmed active, confirmed inactive, or unknown.
  3. How bad would misuse be? What the credential can reach and do, and how many people or systems could have read it.
  4. Who acts, and by when? The owner of the credential (not necessarily the committer) and a service level based on the answers above.

Scanner output helps with the first two. GitHub reports validity as active, inactive or unknown, where unknown means the token type is not supported for validation or the check failed. TruffleHog reports verified, unverified and unknown, the last meaning verification was attempted but hit a network or API error, and its --results flag filters on these values. GitLab records exposures in its vulnerability report and can automatically revoke some secret types. The other two answers need context the scanner does not have: an inventory of what each credential can do and who owns it.

A prioritisation model that works

Score three factors and combine them into a priority. Keep the model simple enough that a script can apply it to every new alert.

FactorHighMediumLow
ValidityVerified active by scanner or providerUnknown or unverified, credential type supports verification laterConfirmed inactive, expired or revoked
PrivilegeCloud admin, CI/CD, source control org tokens, signing keys, production databases, identity provider keysRead access to production data, scoped service tokens, internal APIsSandbox, development-only or read-only to non-sensitive data
ExposurePublic repository, public gist, package, container image, paste site; GitHub public leak labelPrivate repository with broad internal access; same secret in many repositories (multi-repo label)Private repository with a small team, never pushed beyond a feature branch
PriorityTypical combinationResponse targetWho is paged
P1Active (or unknown) plus high privilege or public exposureRevoke within 1 hour; usage review same dayCredential owner and on-call security; open an incident
P2Active with medium privilege in a private repository, or unknown with high privilegeRotate within 1 business dayCredential owner via ticket; security reviews closure
P3Unverified, low privilege, privateRotate or confirm invalid within 7 daysTeam backlog with SLA tracking
P4Inactive or test valueClose with reason and comment within 30 days; check logs for inactive production credentialsTeam backlog

These targets are starting points; set your own and publish them so teams know what is expected. Two rules prevent common errors: unknown validity never lowers priority (it means you do not know), and age does not lower priority. The Toyota T-Connect key exposure sat in a public repository from December 2017 to September 2022; an old alert is an old exposure, not a stale one.

Handling false positives without creating blind spots

Classify before you suppress

  • False positive: the match is not a credential at all, for example a hash, a UUID or a placeholder such as EXAMPLE_KEY. Close and tune the rule if the pattern recurs.
  • Used in tests: a real-looking credential that is deliberately fake or only works against a local mock. Confirm it is not accepted by any real service. The OWASP Secrets Management Cheat Sheet recommends one standard set of test secrets across the organisation, which makes this class easy to recognise.
  • Revoked: a real secret that has been revoked and replaced. Only use this after revocation is confirmed, not planned.
  • Won't fix: a real secret accepted as a risk, for example a public client identifier that is designed to be exposed. Require security approval and an expiry date for the exception.

GitHub's REST API accepts exactly these resolution values (false_positive, used_in_tests, revoked, wont_fix) with an optional resolution_comment, so the classification can be automated and reported on. Make the comment mandatory in your process: what was checked, by whom, and the evidence (for example "provider console shows key deleted 2026-10-20").

Suppression mechanisms compared

MechanismScopeRiskUse for
Close the alert with a reasonOne findingLow; recorded in alert historyDefault for every decision
Fingerprint ignore (Gitleaks .gitleaksignore)One specific secret at one locationLow; new secrets still alertConfirmed false positives in history
Inline marker (gitleaks:allow comment)One lineMedium; any developer can add it. Gitleaks offers --ignore-gitleaks-allow so central scans can disregard markersKnown test fixtures, with review in pull requests
Stopwords and value regexes (stopwords, regexes with regexTarget)All values matchingMedium; a real secret that happens to match is hiddenPlaceholders such as changeme or example
Path allowlist (paths)Whole files or directoriesHigh; any real secret later added there is invisibleGenerated or vendored files only, reviewed quarterly
Baseline (--baseline-path)All findings in an earlier reportHigh if never revisited; the backlog disappears from viewSeparating new findings from legacy, with a parallel plan to clear the baseline
Entropy thresholdA rule's matches below a randomness levelMedium; low-entropy human passwords escapeTuning noisy generic rules

Gitleaks allowlists can be global ([[allowlists]], optionally limited with targetRules) or per rule ([[rules.allowlists]]), and a finding is ignored if any matching allowlist applies. That makes it easy for one broad entry to hide a great deal; review allowlist changes as security-sensitive code. AI-based false positive scoring, such as the confidence scores GitLab offers on some tiers, can speed up review but should rank findings, not close them unseen. For tuning detection rules themselves, see the Secret Scanner Rule Coverage Guide.

Routing to the right owner

The committer is often the wrong person: they may have copied a credential someone else owns, or left the company. Route on the credential, not the commit.

  • Use provider metadata: GitHub's extended metadata (in public preview for some token types such as OpenAI, Google OAuth, Slack and Replicate) can show owner, organisation and issue dates. Provider consoles show who created a key.
  • Use your NHI inventory: map the credential to the service account, application and owning team. If no owner exists, that is a finding in its own right. See NHI Discovery Across Cloud, SaaS, CI/CD and On-Premises Environments.
  • Use repository ownership: CODEOWNERS or service catalogue entries for the repository as a fallback.
  • Deduplicate first: the same secret in ten repositories is one credential and one rotation. GitHub's multi-repo label helps; group by secret hash in other tools.
  • Escalate unowned P1s to security: security revokes, the business finds the owner afterwards. Waiting for an owner is how a P1 stays open for months.

The response workflow for a confirmed secret

  1. Revoke or disable: the OWASP cheat sheet sets out revoke, rotate, delete and log as the incident sequence. Revocation comes first because it ends the exposure. For tokens where revoking breaks production, rotate with an overlap window, but start within the service level.
  2. Rotate: issue a replacement through the secrets manager, with least privilege and, where possible, a short lifetime. Better still, replace the static secret with workload identity or OIDC federation so there is nothing to leak next time.
  3. Review usage: check the provider's audit logs from the first commit date to revocation for calls from unexpected IP addresses, user agents or regions. GitHub's guidance is to check security logs for unauthorised activity, and to do so even for inactive secrets.
  4. Clean up: remove the secret from code and, where justified, history. History rewriting has side effects and does not remove forks or clones, so it is a hygiene step, not a fix.
  5. Close with evidence: resolution reason, comment, revocation timestamp and log review result. Alerts are not closed automatically when the secret is removed.
  6. Prevent recurrence: push protection for the repository, a pre-commit hook for the team, and a note on why the secret was in code at all.

Provider-specific steps are in the leaked credential response guides, for example How to revoke a leaked GitHub personal access token and check what it touched and How to rotate an AWS IAM access key without downtime.

Implementing the triage process

  1. Measure the backlog: export all open alerts with validity, repository visibility and secret type. Most teams find that a small share is active.
  2. Clear the active set first: treat every active or unknown alert with high privilege or public exposure as P1 in a one-off sprint, regardless of age.
  3. Automate scoring: a script or workflow applies the priority model to every new alert, adds labels and opens a ticket with the owner and due date.
  4. Agree close reasons and evidence: publish the four reasons, the evidence each requires and who may approve won't fix.
  5. Pilot with two teams for a month: measure time to close and the share of closes that security disagrees with on review.
  6. Roll out with a sampled review: security reviews a random 10 percent of closed alerts each month, with all won't fix and used in tests decisions reviewed.
  7. Keep a rollback for suppressions: allowlist and baseline files live in version control, so a bad entry can be reverted and the hidden findings resurface on the next scan.

Small teams: use the platform's built-in validity checks and close reasons, a single priority rule (active and production equals today) and a weekly review. Large organisations: centralise alerts from several scanners, deduplicate by secret, integrate with the NHI inventory for ownership and report service levels by business unit. The Secret Sprawl Measurement Guide covers organisation-wide reporting.

Where identity fits

Almost every secret alert is a non-human identity problem: an API key, token, service account key or certificate that was issued to a workload and ended up in code. Triage works best when each alert links to that identity record, with its owner, permissions, last use and rotation method. Over time the goal is fewer secrets to triage at all, by moving workloads to federated, short-lived credentials. See the Secrets Rotation Runbook Template for rotation procedures.

Detection and measurement

  • Mean time to revoke for P1 alerts: from alert creation to confirmed revocation. The headline metric.
  • Active secrets open beyond SLA: count by team; target zero.
  • Disputed closure rate: share of sampled closures that security reopens. Above 5 percent means close reasons are being misused.
  • False positive rate by rule: drives rule tuning; a rule above 50 percent false positives needs work.
  • Suppression growth: number of path allowlist entries and baselined findings over time; it should fall.
  • Repeat offenders: credentials or repositories with recurring leaks, which point at a workflow that needs a secrets manager.

Also alert on use of a revoked credential at the provider, which the OWASP cheat sheet recommends logging, and on push protection bypasses, which should each create a triage item.

Framework mapping

FrameworkReferenceTriage activity
MITRE ATT&CKT1552.001 Credentials In Files; T1078.004 Cloud AccountsThe technique exposed secrets enable, and the follow-on use of leaked cloud keys
NIST SP 800-53 Rev. 5IA-5 Authenticator Management; RA-5 Vulnerability Monitoring and Scanning; SA-11 Developer Testing and EvaluationRotation and revocation; scanning and remediation tracking; developer-side checks
NIST CSF 2.0PR.AA-01 identities and credentials managed; DE.CM-09 software and runtime monitoredCredential lifecycle; detection of exposures
CIS Controls v8.1Control 16 Application Software SecuritySecure development process including secret handling
OWASPSecrets Management Cheat Sheet sections on detection and incident responseTest secret standards; revoke, rotate, delete, log

Common failure patterns

  • Deleting the file and closing the alert: the credential stays valid. In the CISA Private-CISA GitHub leak, AWS keys reportedly remained valid for about 48 hours after the repository was taken down.
  • Bypassed controls with no triage item: in the same case, a contractor had switched off push protection. Every bypass or disablement should raise an alert someone owns.
  • No route for external reports: in the Home Depot token exposure, a researcher's reports reportedly went unanswered and the token was revoked only after press contact. External reports need the same P1 path as scanner alerts.
  • Marking "used in tests" without checking: a real key placed in a test file is still a real key.
  • Broad path allowlists: a tests/ or config/ allowlist that later hides production credentials.
  • Treating unknown validity as low risk: custom and internal credential types are always unknown, and they are often the most privileged.

Lessons from incidents

The incidents above share a pattern: the secret was found, by a scanner, a researcher or a vendor, long before it was revoked. Detection was not the gap; triage, ownership and revocation were. Supplier and contractor repositories feature repeatedly, as in the Toyota case where a development subcontractor published the code, so triage scope must include repositories outside your organisation that hold your credentials, usually found by external monitoring.

Practitioner checklist

  • Every alert scored on validity, privilege and exposure automatically.
  • P1 definition and one-hour revocation target published and paged.
  • Four close reasons in use, each with mandatory evidence comment.
  • Won't fix requires security approval and an expiry date.
  • Suppressions prefer fingerprints; path allowlists and baselines reviewed quarterly.
  • Alerts routed to the credential owner via the NHI inventory, with security revoking unowned P1s.
  • Usage logs reviewed for every confirmed secret, including inactive ones.
  • Monthly sample review of closed alerts with disputed closure rate tracked.
  • External researcher reports routed into the same P1 process.
  • Recurring leaks fed into migration to short-lived, federated credentials.

Standards and references

Related NHI Mgmt Group resources: Git Secret Scanning Guide · SAST Triage Guide · Push Protection Guide · Secret Sprawl Measurement Guide · Secrets Rotation Runbook Template

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 28 October 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