Join our Newsletter — 33% off our NHI Course
Home› Guides› Git Secret Scanning Guide: Finding and Stopping Leaked…
Guide Secrets Management

Git Secret Scanning Guide: Finding and Stopping Leaked Credentials

PDF for newsletter subscribers · free to read online

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

Credentials committed to Git stay readable in every clone, fork and history rewrite that missed them, long after someone deletes the line from the latest commit. Secret scanning finds API keys, tokens, private keys and connection strings in repositories and blocks new ones before they land, but most programmes scan only one layer and treat a closed alert as a fixed problem. This guide covers where to scan (IDE, pre-commit, push, CI, history and the places code travels to), how the main detection approaches differ, how to tune verification and baselines, and how to run remediation so a leaked secret is actually dead. It is written for application security, platform and identity teams who own developer tooling and the non-human identities those secrets belong to.

Key takeaways

  • Revoke before you rewrite. A leaked secret is fixed when the credential no longer works; removing it from Git history is secondary and never sufficient on its own.
  • Scan in layers. Pre-commit hooks can be skipped, push protection only covers supported patterns, and CI scanning sees code after it has left the laptop, so each layer catches what the others miss.
  • Verification changes triage. Tools that test whether a key is live (TruffleHog verification, GitHub validity checks) let you fix active credentials first, but an unverified result is not proof the secret is dead.
  • Code goes beyond the repository. Container images, build logs, issue comments, wikis and exposed .git folders on web servers all carry secrets that repository scanning alone does not see.
  • Every finding is an identity problem. Each key belongs to a service account, app or workload; remediation needs an owner and a rotation path, which is why scanning belongs alongside NHI governance.

What git secret scanning finds and why history matters

Git stores every version of every file. A key added in one commit and deleted in the next is still present in the object store, in every existing clone and in any fork made in between. Scanners therefore work on two targets: the change being made now (a diff, a push, a merge request) and the full history of all branches.

  • Provider-specific secrets: tokens with a recognisable prefix or structure, such as cloud access keys, Git platform tokens, payment API keys and chat bot tokens. These give high precision and are what push protection usually blocks.
  • Generic secrets: private keys (RSA, EC, OpenSSH, PGP), database connection strings with embedded credentials and HTTP Basic or Bearer authentication headers. GitHub lists these as non-provider patterns such as generic_private_key, postgres_connection_string and http_bearer_authentication_header, with no validity checks available.
  • Unstructured secrets: human-chosen passwords in configuration files. GitHub uses an AI-detected password pattern for these and states that push protection and validity checks are not supported for it. Regex and entropy tools struggle here too.
  • Custom secrets: internal token formats, signing keys and service passwords that only your organisation recognises. These need custom patterns written and tested by you.

Attackers search public code for exactly these patterns (MITRE ATT&CK T1593.003 Search Open Websites/Domains: Code Repositories) and harvest credentials from files once inside (T1552.001 Credentials In Files, T1552.004 Private Keys). The GitLab public repositories study shows the scale: a verified TruffleHog scan of about 5.6 million public projects surfaced 17,430 live secrets, the oldest committed in 2009.

Where to scan: the layers and what each catches

LayerWhen it runsStrengthsGaps
IDE scanningAs the developer types or savesEarliest feedback; nothing has been committedDepends on extension adoption; no central enforcement
Pre-commit hookBefore the commit is created locallyStops secrets entering history at allOpt-in per clone; skipped with git commit --no-verify or tool-specific skip variables
Push protection (server side)When the push reaches the Git platformCentral, cannot be skipped without a recorded bypassLimited to supported, high-precision patterns; GitHub supports only the most recent token versions
CI/CD pipeline scanningOn merge or pull request pipelinesCovers repositories without push protection; can fail the build; outputs SARIFSecret is already pushed; must scan the diff range, not just the head
Full history and continuous scanningScheduled, and when new detectors are addedFinds old leaks; GitHub rescans history when it adds new secret typesLarge backlog; needs a triage process
Non-code surfacesIssues, pull request comments, wikis, discussionsGitHub scans issues, PRs, discussions, wikis and secret gists; GitLab has client-side detection for issue and merge request textChat, ticketing and documentation tools outside the Git platform need separate tooling
Build outputsContainer images, packages, artefactsCatches secrets copied in at build timeUsually a separate scanner and owner

Platform features differ in naming but follow the same idea. GitHub offers secret scanning, push protection for repositories and users, custom patterns, generic patterns, validity checks and a partner programme that notifies the issuer when a partner token is found in public code. On private and internal organisation repositories these need GitHub Secret Protection; public repositories are scanned at no cost. GitLab provides secret push protection, pipeline secret detection and client-side secret detection, and records findings in the vulnerability report. See the GitHub and GitHub Actions Security Guide.

Detection approaches compared

ApproachHow it worksPrecisionBest use
Pattern (regex) rulesMatch known token formats and prefixesHigh for structured tokensPush protection, blocking in CI
Entropy detectionFlags random-looking strings above a thresholdLow to medium; noisy on hashes and test dataFinding unknown key formats during history audits
Keyword and context rulesLook for names such as password= near a valueMediumConfiguration files, generic credentials
Verified scanningCalls the issuing API to test whether the credential worksVery high for live findingsPrioritising remediation; proving impact
AI or model-based detectionClassifies unstructured strings such as passwordsVaries; vendor-specificPasswords that regex cannot express
Decoding and archive traversalDecodes base64, hex or percent encoding and opens archives before matchingDepends on underlying rulesSecrets hidden in encoded config or zipped fixtures

Open-source tools and their controls

  • Gitleaks: commands git (uses git log -p, narrowed with --log-opts), dir and stdin; the older detect and protect commands were deprecated in v8.19.0. Rules live in .gitleaks.toml with [extend] useDefault = true to inherit defaults, allowlists by commit, path, regex or stopword, a --baseline-path to report only new findings, --max-decode-depth and --max-archive-depth (both off by default) and --redact to keep secrets out of logs. Reports are JSON, CSV, JUnit or SARIF. Its README now says the project is feature complete and will receive security patches only, which matters for long-term tool choice.
  • TruffleHog: classifies over 800 secret types with over 700 detectors that support verification. Results are verified, unverified or unknown (verification attempted but failed), filtered with --results. Sources go well past Git: github, gitlab, docker, s3, gcs, filesystem, postman, jenkins, elasticsearch, huggingface, circleci and travisci. The analyze command reports what a credential can access for around 20 common types.
  • detect-secrets: built around a .secrets.baseline file that accepts existing findings so the hook blocks only new ones, with detect-secrets audit for labelling true and false positives and pragma: allowlist secret for inline exceptions. Its documentation notes it does not catch multi-line secrets.

OWASP's Secrets Management Cheat Sheet recommends running more than one detection tool and de-duplicating results to expose coverage gaps, and agreeing standard test secrets so fixtures stop generating noise.

How to implement: a phased rollout

  1. Inventory and baseline (weeks 1 to 2): list every Git organisation, group and self-hosted server, including mirrors and archived repositories. Run a full-history scan with verification enabled and store the results as a baseline. On GitHub, the free organisation assessment (Security and quality, Assessments, Scan your organization) gives a first view.
  2. Revoke live findings first: sort the baseline by verified or active status and rotate those credentials before touching anything else. Assign each one to an owning team; unowned keys go to the platform team by default.
  3. Enable server-side push protection in audit posture: turn it on for a pilot group of repositories, watch bypass volume and reasons for two to four weeks, then extend organisation-wide. Keep the default list of supported patterns before adding custom ones.
  4. Add CI scanning for diffs: scan only the commit range of each pull request, for example TruffleHog with --since-commit main --branch <feature> --results=verified,unknown --fail, or Gitleaks with --baseline-path. Upload SARIF where your platform supports it so findings appear next to the code.
  5. Distribute pre-commit hooks: ship a shared .pre-commit-config.yaml (hook ids gitleaks or detect-secrets) through repository templates and developer onboarding. Treat hooks as a convenience for developers, not as the control you rely on.
  6. Add custom patterns: write rules for internal token formats, test them against the baseline and against known-good fixtures, then promote them to blocking only once the false positive rate is acceptable.
  7. Extend beyond Git: scan container registries, artefact stores, CI logs and the wiki and ticketing systems that sit next to the code. Exposed .git directories on web servers should be checked from outside.
  8. Roll back safely: if push protection blocks a release-critical pattern wrongly, use delegated bypass for named people rather than disabling the control, and fix the pattern. Custom patterns can be disabled individually without affecting the default set.

Push protection bypasses and delegated bypass

On GitHub, anyone with write access can bypass repository push protection by default if they give a reason: "it's used in tests" and "it's a false positive" close the resulting alert, while "I'll fix it later" leaves it open. Every bypass creates an alert, an audit log entry and an email to people watching the repository. Delegated bypass lets you restrict this so that only named reviewers can bypass or approve bypass requests, and exemptions let specific actors push without triggering the check.

  • Small organisations: default bypass with weekly review of bypass alerts is usually workable; the audit trail is the control.
  • Large or regulated organisations: use delegated bypass with a security reviewer group, and require a ticket reference in the bypass comment.
  • Watch the "used in tests" reason: it closes the alert automatically. Sample these regularly, because real credentials are often pasted into test fixtures.
  • User push protection is not organisation coverage: GitHub enables it by default for personal accounts pushing to public repositories, but it does not raise bypass alerts unless repository push protection is also on. A developer can also switch it off, as the CISA Private-CISA GitHub leak showed when commit history revealed the default protection had been disabled.

Remediating a leaked secret

  1. Revoke or rotate the credential at the issuer. GitHub's own guidance says that once the secret can no longer be used, rewriting history may not be necessary. See the Secrets Rotation Runbook Template.
  2. Check for use during the exposure window in the issuer's logs (cloud audit trails, API access logs). OWASP lists who had access, when it was used and when it was last rotated as the lifecycle information responders need.
  3. Replace the secret with a reference to a secrets manager or, better, a short-lived federated credential so the code no longer needs a static key. See the Secrets Management Guide.
  4. Decide whether to rewrite history. For sensitive data that cannot be rotated, GitHub documents git-filter-repo --sensitive-data-removal (version 2.47 or later) followed by a mirror force push. The side effects are real: commit hashes change, signatures are removed, open pull requests lose their diffs, forks keep the data, and anyone who merges an old clone brings it back. Cached views and refs/pull/ references need GitHub Support.
  5. Close the alert with the right resolution (for GitHub, revoked rather than wont_fix) so metrics reflect reality, and record the root cause.

Where identity fits

Each finding is the credential of a non-human identity: a cloud service account, a CI deploy key, a GitHub App, a bot token. Scanning tells you a secret exists; only identity governance tells you who owns it, what it can reach and whether it should exist at all. Map each verified finding to its identity, check its permissions and retire identities that no longer have a purpose. The leaked GitHub App private keys research found 474 of 4,802 leaked keys still authenticated, because App private keys do not expire and many of the Apps were small, internal or abandoned. A scanner can flag such a key; only an owner can delete it. See the CI/CD Pipeline Identity Security Guide.

Detection and measurement

  • What to log: push protection blocks and bypasses with reasons, alert state changes, validity status changes, and attempts to use revoked credentials at the issuer. OWASP advises never logging plaintext secrets, so use redaction options such as Gitleaks --redact.
  • What to alert on: any new verified or active finding, any bypass on a default-branch protected repository, and any use of a credential from an unexpected source after a leak.
MetricDefinitionHealthy direction
CoverageShare of active repositories with push protection and CI scanning enabledTowards 100%
Time to revokeMedian hours from first detection to credential revoked (not alert closed)Falling; under 24 hours for verified findings
Live backlogOpen findings with verified or active statusFalling to near zero
Bypass rateBypasses as a share of push protection blocks, by reasonLow and stable, with "fix later" bypasses closed promptly
RecurrenceRepositories or teams with repeat leaks of the same secret type in 90 daysFalling
False positive rateFindings resolved as false positive per ruleLow enough that developers trust blocks

For deeper programme measurement, see the Secret Sprawl Measurement Guide.

Common failure patterns

  • Deleting instead of revoking: developers remove the key from the file and consider it fixed. In the Docker Hub secrets leak, about a quarter of developers removed exposed secrets within a day or two, but in most cases the credential was not revoked.
  • Scanning the head commit only: CI jobs that check the current tree miss secrets added and removed within the same branch, which remain in history once merged.
  • Trusting pre-commit hooks as a control: they are local, optional and easy to skip. Server-side push protection and CI must back them up.
  • Ignoring where the repository is served: deploying a working copy to a web server can publish the whole .git folder. The misconfigured Git servers study counted 4,964,815 IP addresses serving .git directories, with 252,733 .git/config files holding deployment credentials, by the researchers' own unverified count.
  • Treating unverified as safe: verification failures can mean a network error (TruffleHog's unknown), and generic secrets such as private keys and connection strings often have no validity check at all.
  • Allowlisting by path wholesale: excluding test/ or docs/ folders hides real credentials copied into fixtures and examples.

Framework mapping

FrameworkReferenceHow scanning supports it
NIST SP 800-53 Rev. 5IA-5(7) No Embedded Unencrypted Static AuthenticatorsDetects and blocks static credentials in code
NIST SP 800-53 Rev. 5SA-11 Developer Testing and Evaluation; SA-15 Development Process, Standards, and ToolsScanning as part of developer testing and toolchain
NIST SP 800-53 Rev. 5RA-5 Vulnerability Monitoring and Scanning; IR-4 Incident HandlingContinuous history scanning; leak response
NIST CSF 2.0PR.PS-06; PR.AA-01; DE.CM-09Secure development practice; credential management; monitoring software
CIS Controls v8.1Control 16 Application Software SecuritySecure development life cycle for in-house software
ISO/IEC 27001:2022 Annex A5.17 Authentication information; 8.28 Secure codingProtecting credentials; secure coding practice
MITRE ATT&CKT1593.003; T1552.001; T1552.004; T1213.003Techniques that harvest secrets from code and repositories

Practitioner checklist

  • Run a full-history, verified scan of every Git organisation, mirror and self-hosted server, and keep it as a baseline.
  • Revoke every verified or active finding and record time to revoke, not time to close.
  • Enable server-side push protection organisation-wide after a pilot, and decide on default or delegated bypass.
  • Scan the pull request commit range in CI and fail on verified or unknown results.
  • Distribute pre-commit hooks through templates, but do not count them as coverage.
  • Write and test custom patterns for internal token formats before making them blocking.
  • Extend scanning to container images, CI logs, wikis, issues and externally exposed .git paths.
  • Map each finding to its owning non-human identity and remove credentials that have no owner.
  • Review "used in tests" and "false positive" bypasses monthly.
  • Replace static keys in code with secrets manager references or federated, short-lived credentials.

Standards and references

Related NHI Mgmt Group resources: Secrets Management Guide · Top 10 Secrets Management Mistakes · CI/CD Security Guide · Secrets Scanning Buyer's Guide · Secret Sprawl Measurement Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

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
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 24 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.