Repository navigation
secretscan v1.1.0
secretscan 1.1.0 is the first release with published binaries. It is a
precision-first secret scanner shipped as a single Go binary with no
dependencies. It scans files, git history, staged changes, outgoing pushes
and raw diffs. The aim is to find more real credentials than existing
scanners without the noise that leads developers to bypass the hook.
The v1.0.0 release on GitHub was created by hand before the release
workflow ran, so it has no binaries or signatures. Use 1.1.0. Detection is
identical to 1.0.0, so the benchmark below applies to both.
New since 1.0.0
- Deterministic trufflehog triage. A trufflehog finding whose metadata
names several source locations that disagree is no longer checked
against whichever one Go's map order produced. It stays uncorroborated,
with the conflicting locations listed, unless exactly one matches the
report's own source. - Keyed fingerprints. Set
SECRETSCAN_HASH_KEY(or--hash-key-file)
and every fingerprint in a report becomeshmac-sha256:<hex>. Without a
key, reports carry the plain SHA-256 of each secret, which is enough to
confirm a guessed weak password, so treat such reports as secrets. - Output files are never written through a link. Reports, fix
patches, hooks and--fixedits go to a new file that is renamed into
place; a symlink at a report path is refused. - Bounded triage input. Reports larger than
--max-report-megabytes
(default 256) are rejected before parsing. - Benchmark integrity. Every published figure is generated from one
results file and checked against the measurement it comes from;
confidence is documented as an evidence level, not a probability.
Highlights
- Evidence-based detection. There are 136 built-in rules. Provider
formats (AWS, Azure, GCP, GitHub, GitLab, Slack, Stripe, OpenAI,
Anthropic, private keys, ...) are high confidence on their own. A
generic match needs several independent signals, and every finding
carries a confidence level and its reasons. - Recognises dummies and local credentials. Placeholders
(some_password,postgres:postgres@, values that repeat their key
name) are filtered. Credentials for localhost, private networks and
compose services, and values in.env.example, are reported at low
confidence for review instead of blocking. - No silent passes. Every filtered candidate is counted and can be
listed with its reason (--show-suppressed). - Strict or balanced policy. Strict blocks every finding and is the
default for scans and CI. Balanced is the default for git hooks: it
blocks high- and medium-confidence findings and generic values in test
files, and lists weak evidence under "Needs review". Provider tokens
block everywhere, including intests/. secretscan triage. The same precision layer applied to gitleaks,
trufflehog or any SARIF report. It reads source only inside--root,
reads history findings at their commit, and never drops a finding
silently.- Fix guidance. Every finding says how urgent it is and how to rotate
it.--fix-patchwrites a reviewable patch that replaces literals with
environment lookups, andsecretscan explainshows loading patterns
for env, Vault, AWS, Azure and GCP. - Optional live verification (
--verify, off by default) for 12
providers. Only a provider's documented success response counts as
verified. - Drop-in gitleaks compatibility. The config schema, fingerprints,
.gitleaksignore,gitleaks:allowand the JSON report shape all carry
over. - Reports in text, JSON, SARIF 2.1.0, CSV, JUnit XML and an anonymised
statssummary.
Benchmark
Samsung CredData, 181 repositories never used for design
(secrets-only labels, default settings):
| Tool | Precision | Recall | F1 |
|---|---|---|---|
| secretscan 1.1.0 | 91.5% | 59.2% | 0.719 |
| gitleaks | 91.8% | 28.9% | 0.440 |
gitleaks + secretscan triage |
93.6% | 27.5% | 0.425 |
trufflehog 3.97.9 (--no-verification) |
44.7% | 3.4% | 0.064 |
secretscan matches gitleaks' precision on these repositories and finds
twice as many of the labelled secrets. With the hook default (balanced,
testFixtures = "block"), 39.9% of the labelled secrets block, at 90.2%
precision; strict blocks all 59.2% it reports. On the half of CredData used
for design, secretscan reaches 98.8% precision and 89.0% recall. The gap
between the two halves shows how much of the tuning carries over to
repositories it has not seen. trufflehog was run without verification, so
its recall reflects detector coverage, not its usual verified-only workflow.
Full method, per-class misses and false positives:
bench/results/2026-10-17.md.
Every number can be regenerated with bench/reproduce.sh or the
benchmark workflow in a fork. How the figures are produced, how label
disagreements are handled and how to run a second independent benchmark:
docs/benchmark-policy.md.
Precision by confidence level, path, detector family and policy is in
section 6 of the results file.
Install
Linux and macOS (amd64, arm64):
curl -fsSL https://raw.githubusercontent.com/AISolutionLabs/secret-scanner/main/install.sh | sh -s -- v1.1.0Windows (PowerShell):
irm https://raw.githubusercontent.com/AISolutionLabs/secret-scanner/main/install.ps1 | iexWith Go 1.24+:
go install github.com/AISolutionLabs/secret-scanner/cmd/secretscan@v1.1.0As a pre-commit hook: use rev: v1.1.0 with the repository's
.pre-commit-hooks.yaml, or run secretscan install-hook --type both.
The installers check the binary against SHA256SUMS and install nothing
if it does not match. With cosign installed they also check the Sigstore
signature; set SECRETSCAN_REQUIRE_SIGNATURE=1 to make that check
mandatory.
Assets
| File | Platform |
|---|---|
secretscan-linux-amd64, secretscan-linux-arm64 |
Linux |
secretscan-darwin-amd64, secretscan-darwin-arm64 |
macOS |
secretscan-windows-amd64.exe, secretscan-windows-arm64.exe |
Windows |
SHA256SUMS |
SHA-256 of every binary |
SHA256SUMS.sigstore.json |
Keyless Sigstore signature of SHA256SUMS, bound to this repository's release workflow and tag |
Every binary also has a GitHub build-provenance attestation. To verify a
download by hand:
cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json \
--certificate-identity-regexp '^https://github.com/AISolutionLabs/secret-scanner/\.github/workflows/release\.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum --ignore-missing -c SHA256SUMS
gh attestation verify secretscan-linux-amd64 --repo AISolutionLabs/secret-scannerAfter publishing, the release workflow installs this release from scratch
on clean Linux, macOS and Windows runners and checks that it blocks a
freshly generated token.
Security hardening
The code went through an internal security audit, an adversarial review
and several external code reviews. Every finding is fixed, each with a
regression test that fails on the earlier code. Full list:
docs/security-audit.md.
- Outputs: reports, fix patches, hooks and
--fixedits are never
written through a symlink or hard link. They are created as a new file
with mode 0600 and renamed into place. - Resource limits: triage limits the reports it reads
(--max-report-megabytes, default 256) and the source files and
history blobs they name (8 MiB). Inputs too large to scan are listed in
the summary instead of passing silently. - Verification:
--verifysends each secret only to a hard-coded
provider endpoint, does not follow redirects, and checks each secret
once per run. It never reports a proxy's page, a JSON error or a 403 as
"verified". --fix: edits need confirmation or--yes, are syntax-checked, and
are never applied inside comments, multi-line strings or constant
positions.
Known limitations
- 41% of CredData's labelled secrets on unseen repositories are not
found (59.2% recall). Balanced trades recall for fewer interruptions
(39.9% of labelled secrets block with the defaulttestFixtures = "block");
use strict where that matters more. - In its default conservative mode, triage drops 54 of gitleaks'
1,110 true findings on unseen repositories. 41 of those are AWS WAF
ChangeTokenvalues, which are deliberately not treated as
credentials (label policy). - Confidence levels measure the strength of the evidence, not the
probability that a value is a credential. On CredData, low-confidence
findings are the most precise, mostly because CredData labels test
fixtures as real secrets. - Verification sends the secret to its provider. It is off by default and
should not run from a commit hook. - Not yet shown: a second independently labelled corpus, an outside
reproduction of the benchmark, and dismissal rates from real users.
Contributions of any of these are welcome.
Compatibility
secretscan follows Semantic Versioning.
docs/compatibility.md
defines what is stable: the CLI flags, exit codes, report formats, config
schema and fingerprints.
Full changelog: CHANGELOG.md