GitHub Secret Protection vs GitLab push protection vs TruffleHog vs Gitleaks

Only two of the four can refuse a push, and all four fail open — so the real choice is not which detector finds more, it is which failure you can see. GitLab publishes its skip thresholds as numbers (1 MiB, 3,150 paths, 350,000 lines), GitHub charges $19 per active committer for the paid half, TruffleHog is the only one that tells you whether a found secret is still live, and Gitleaks has stopped taking new rules.

By Agentic AI Wiki 12 min read

Two of these four tools can stop a secret from reaching a repository; the other two can only tell you it already did. That distinction decides the outcome now that exploitation of a leaked credential has been observed finishing in five minutes — and the harder question underneath it is not which tool detects more, but which tool's failures you can see.

At a glance

Figures below are from each project's own documentation as of November 2026.

ToolPositionCost or licenceVerifies liveness
GitHub Secret ProtectionServer-side push protection plus repository scanning$19 per active committer/month; push protection free on public reposYes — validity checks (Team and Enterprise)
GitLab secret push protectionPre-receive hook; GA since GitLab 17.5Ultimate tierNo
TruffleHogDetector; pre-commit hook and scheduled scansAGPL-3.0 since v3Yes — verified, unverified, unknown
GitleaksDetector; pre-commit hook and CIMITNo
Where each secret-scanning tool sits on one timeline A timeline runs left to right through commit, push, landing in the repository, and exposure. Four stations sit under it. A pre-commit hook, run by Gitleaks or TruffleHog on the developer's machine, sits before the commit and can simply not be run. A server-side gate, GitHub push protection or GitLab secret push protection, sits at the push and refuses the write, but can be bypassed with an audited flag. A repository scan, GitHub secret scanning or a GitLab pipeline, alerts after the secret has landed, by which point it is already public. Verification, TruffleHog with results set to verified, sits after exposure and only tells you whether the credential is still live. One timeline, four places to stand commit push lands in repo exposed Pre-commit hook Gitleaks, TruffleHog on the laptop Server-side gate GitHub, GitLab refuses the write Repository scan GitHub, pipelines alerts, does not stop Verification TruffleHog is it still live? When it fails, the failure looks like: Nobody installed it and nothing noticed A flag or a commit message skipped it The alert is true and already too late No detector exists for that credential
Four positions on one timeline — and the failure that is specific to each position.
Four secret scanners on four separating questions A four by four matrix. GitHub Secret Protection refuses the write server-side, checks whether a secret is still live through validity checks, costs nineteen dollars per active committer per month, and is still gaining detection coverage. GitLab secret push protection refuses the write in a pre-receive hook, does not check liveness, requires the Ultimate tier, and is still gaining coverage. TruffleHog refuses nothing, verifies liveness with three result states, is AGPL-3.0 licensed, and is still gaining detectors. Gitleaks refuses nothing, verifies nothing, is MIT licensed, and is frozen: its README says future releases will be security patches only. Legend: decisive, partial, no. Four tools, four separating questions Refuses the write Checks if live Price or licence Still gaining rules GitHub Secret Protection Yes, server-side Yes, validity checks $19/committer/mo Yes GitLab push protection Yes, pre-receive No Ultimate tier Yes TruffleHog No, detector only Yes, three states AGPL-3.0, free Yes, 700+ detectors Gitleaks No, detector only No MIT, free No, 222 rules, frozen Decisive Conditional Absent
The fourth column is the one teams never evaluate and the one that decays.

GitHub Secret Protection

What you actually buy

GitHub unbundled Advanced Security, and Secret Protection is now a standalone SKU at $19 per active committer per month, with Code Security priced separately at $30. Billing on committers rather than seats matters more than it sounds: read-only accounts and dormant users do not bill, so the invoice tracks the population that can actually create the exposure.

On public repositories, push protection, secret scanning, provider patterns and provider notification are free. That is the single highest-leverage configuration change available to most organisations, and it covers exactly the population an attacker queries — Microsoft's November report describes agents searching public GitHub for client secrets.

Where the paid line falls

The paid tiers are where coverage widens past known provider formats. Validity checks — asking the issuing provider whether the token still works — are Team and Enterprise. So are generic patterns (unknown-provider tokens, connection strings, private keys) and AI-detected secrets for alerts, which is how unstructured credentials such as plain passwords get found at all. “AI-detected secrets in push protection” is separate again: it is in preview and consumes AI Credits.

Read that layering carefully, because it means the free tier blocks what has a recognisable shape and the paid tier blocks what does not. A database connection string with an embedded password is the archetypal real leak and the archetypal unstructured one.

GitLab secret push protection

A gate with published edges

GitLab's equivalent runs in the pre-receive hook: push, and the server checks before the write is accepted. It arrived as an experiment in GitLab 16.7, went beta in 17.1 and reached general availability in 17.5; since 17.11 it scans the diff rather than the whole file. It requires the Ultimate tier.

What makes it the most useful of the four to reason about is that its exceptions are documented as numbers. Secret push protection is skipped when:

  • the file or diff patch is larger than 1 MiB;
  • the push changes more than 3,150 paths or more than 350,000 lines;
  • the ruleset fails to parse or compile, or the scan receives invalid input.

And it can be skipped deliberately: append -o secret_push_protection.skip_all to the push, or put [skip secret push protection] in a commit message. Both generate audit events, which since 17.9 record the commits that skipped the check.

That list is not a weakness disclosure — it is the feature. A gate whose bypass conditions are published as thresholds is a gate you can monitor: alert on the audit event, and on pushes that cross 3,150 paths. A gate whose exceptions are undocumented has the same holes and no alert.

TruffleHog

Detection is the cheap half; verification is the scarce half

TruffleHog refuses nothing. It has no server-side gate, and its README documents a pre-commit hook but no pre-receive one. What it has instead is the capability none of the free alternatives offer: it takes a candidate credential and asks the issuing service whether it works, returning one of three states — verified (confirmed live), unverified (detected, not confirmed, possibly dead), and unknown (verification itself failed, typically a network or API error). --results=verified reduces output to confirmed live secrets.

The three-state result is the design detail worth stealing. Most tools collapse “we checked and it is dead” into the same bucket as “we did not check”, which is precisely the distinction a triage queue needs. Keeping unknown separate is an honest admission of a failed check rather than a silent downgrade — the same discipline as a structured refusal.

Scope and the licence question

Coverage is broad — the README claims over 700 credential detectors with active verification, and classification across more than 800 secret types — and it reaches beyond git: filesystems, S3, GCS, Docker images, stdin, Postman, Jenkins, Elasticsearch, Hugging Face, CircleCI, Travis, syslog and GitLab. The analyze subcommand goes further and maps what a credential can reach, but only for roughly twenty of the most commonly leaked types, so treat it as a triage accelerator for the big providers rather than general capability.

The licence is AGPL-3.0 since v3 (pre-v3 code remains GPL-2.0). For CI use inside your own organisation this is unremarkable; if you were planning to embed it in a product you ship or host for others, that is a legal conversation and not a technical one.

Gitleaks

Fast, MIT, and no longer moving

Gitleaks is the one most teams already have: MIT-licensed, fast, trivially installed as a pre-commit hook or a GitHub Action, with 222 rules in its default config/gitleaks.toml. Current modes are git, dir and stdin; detect and protect have been deprecated since v8.19.0.

The fact that decides whether it should remain your primary detector is in the README itself: “Gitleaks is feature complete. I'm not merging new features into Gitleaks. Future releases will be security patches only.” The maintainer has moved to a successor project, Betterleaks.

This is a statement about your coverage next year, not about the code's quality today. New credential formats ship continuously — every provider that launches an API mints a new token shape — and a frozen rule set does not acquire them. A detector's value decays at the rate the ecosystem issues new secret formats, and that rate is not slowing.

The baseline is the part to watch

Gitleaks' baseline workflow — scan once with --report-path, pass that report back with --baseline-path, see only new findings — is genuinely useful for adopting the tool on an old repository without 4,000 alerts. It is also the mechanism by which real leaks become permanently invisible: everything in the baseline is, by definition, never reported again, and nothing in the baseline has been verified as dead. The same applies to .gitleaksignore, which the README marks experimental, and to inline gitleaks:allow comments.

If you adopted Gitleaks with a baseline and never went back, you have an unreviewed list of candidate live credentials in your repository. Run TruffleHog's verification over the baseline entries once. The ones that come back verified are not historical.

Cross-cutting: the three axes that actually separate them

Can it refuse the write?

Only the two forge-integrated products can, because only the forge is in the path. This is not a tooling gap that an open-source project could close — a pre-commit hook runs on a machine the developer controls, so it is advisory by construction, and the two scanners are honest about living there. The consequence is that the gate decision is a platform decision: if you are on GitHub Team or Enterprise you buy Secret Protection; if you are on GitLab you need Ultimate; if you are on neither, no amount of open-source tooling gives you a gate, and your residual exposure is whatever developers push.

How does it fail, and can you see the failure?

All four fail open, in four different ways. The pre-commit hooks fail when they are not installed, and nothing records that. The GitHub gate can be bypassed with a reason, which is logged. The GitLab gate can be skipped by a push option or a commit-message string, which is audited, and silently skips above its published size thresholds. The scanners fail when no detector exists for the credential's format — Gitleaks at 222 rules and frozen, TruffleHog at 700-plus and growing.

Rank those by observability rather than by strength and the ordering inverts the marketing. The strongest control with an invisible failure is worse to operate than a weaker one whose failures emit an audit event you can alert on. This is the fail-closed versus fail-open question applied to a gate, and the practical rule is: every bypass path needs a counter, and every counter needs a threshold that pages someone.

Does it tell you whether the finding matters?

A detection queue without liveness is unprioritisable. Most findings in an old repository are dead strings — expired keys, rotated tokens, example values — and the ones that matter are indistinguishable from them by pattern alone. GitHub's validity checks and TruffleHog's verification both answer this; GitLab's push protection and Gitleaks do not. Given that the exploitation window is now measured in minutes, a queue sorted by “confirmed live” is not a nicety: it is the difference between triaging four secrets and triaging four hundred candidates.

When to pick which

SituationPrimaryPair it withWhy
Public repositories, any budgetGitHub push protection (free)TruffleHog on a scheduleThe free gate covers the population attackers query; verification prioritises history
GitHub Team/Enterprise, private reposSecret Protection at $19/committerGitleaks pre-commit for speedValidity checks and generic patterns are where private-repo leaks live
GitLab UltimateSecret push protectionAlerts on skip audit eventsThe gate is strong; the published thresholds are your residual risk
Self-hosted forge with no gateTruffleHog in CI, blockingGitleaks pre-commitCI is the closest thing to a gate you control; verification keeps the queue honest
Auditing a legacy monorepo onceTruffleHog --results=verifiedanalyze on the hitsYou need the live subset and its reach, not 4,000 candidates

Nobody should run exactly one of these. The defensible minimum is a gate you did not write plus a verifier you run on a schedule — and the gate's bypass counter on a dashboard someone looks at. Building that loop as an agent-driven workflow is the subject of secret-scanning and rotation agents.

FAQ

Is a pre-commit hook worth installing if developers can skip it?

Yes, for a reason that is not about security: it catches the accident at the only moment when fixing it is free. Once a secret is in a commit, removing it is a history rewrite; before the commit it is an edit. Treat the hook as a developer-experience feature and the server-side gate as the control.

Does GitHub's $19 figure include push protection?

Push protection is listed as included with Secret Protection on Team and Enterprise, and free on public repositories. The $19 per active committer per month buys the private-repository coverage plus validity checks, generic patterns and AI-detected secrets for alerts.

Should we replace Gitleaks now that it is frozen?

Not urgently, and not by deleting it. It still detects the 222 patterns it knows, quickly and under MIT. Plan the replacement on a coverage basis: if your stack adopts providers whose token formats post-date the freeze, those will not be caught, and a scheduled TruffleHog run is the cheaper way to cover the gap than a migration.

Why doesn't GitLab verify whether a secret is live?

Its push protection is designed as a blocking check in the pre-receive path, where a network call to a third-party provider would add latency to every push and introduce an external dependency into the write path. That is a defensible engineering choice; it just means liveness has to come from somewhere else in your pipeline.

Can an attacker use the documented GitLab skip conditions?

In principle — a diff over 1 MiB is not scanned. In practice the realistic threat is not a malicious insider crafting a 1 MiB diff but an ordinary large refactor that crosses 3,150 paths and silently goes unchecked. Alert on pushes that cross the thresholds; that converts a silent skip into a reviewable event.

Further reading

On this wiki:

Project sources: