Secret Scanning
Secret scanning that finds hardcoded credentials — API keys, tokens, and private keys — across your source code and full git history, with 270+ detectors for 150+ providers. On by default.
Secret Scanning
A committed credential is an immediate compromise. Secret scanning — also called secrets detection or credential scanning — finds hardcoded API keys, tokens, and private keys committed to a repository before an attacker does. xgrep scans for secrets by default — alongside the security rules, with no extra flag — so a leaked key surfaces the moment you scan:
xgrep scan .
To scan only for secrets, select the category:
xgrep scan --category secrets .Two flags take secrets scanning further, each on its own page:
- Scanning git history (
--history) — catch secrets that were committed and later deleted but still live in the repository's past. - Decoding and validating (
--decode,--validate) — find secrets hidden one encoding layer deep, and confirm which credentials are actually live.
What it detects
xgrep ships 275+ detectors covering 150+ providers — cloud platforms (AWS, GCP,
Azure), source forges (GitHub, GitLab), and payment, messaging, AI/LLM, and
observability vendors — plus generic high-entropy API keys, PEM private keys, and
the credentials that have no token format at all: a password in a
postgresql://user:pass@host connection string, a password literal in a YAML or
.env configuration file, a credential passed to a Kubernetes container as a
literal env value, and a Terraform attribute or variable default holding one.
Detection is tuned for precision, in line with xgrep's accuracy-first goals:
- Provider-specific patterns (prefixes, lengths, checksums) rather than blanket
entropy heuristics, so a real
ghp_…token matches but a random UUID doesn't. - Placeholder filtering — well-known example/dummy values (such as AWS's
AKIAIOSFODNN7EXAMPLE) are recognized and not reported. - Severity that tracks reality — a detected secret is reported at a reduced severity until validation confirms it's live.
Every finding explains the blast radius and the fix: revoke, rotate, and move the value to a secret store or environment variable.
Supported providers
Alongside the type-based detectors — generic high-entropy API keys, PEM/PKCS private keys, JSON Web Tokens (JWTs), credential connection URIs, configuration passwords, and PII (credit-card numbers, IBANs, US SSNs) — xgrep ships dedicated, provider-specific detectors for:
1Password, Adafruit, Adobe, Age, Airtable, Algolia, Alibaba, Anthropic, Artifactory, Asana, AssemblyAI, Atlassian, Authress, AWS, Azure, Beamer, Bitbucket, Bittrex, Brevo (Sendinblue), Cerebras, Cisco, Civo, ClickHouse, Clojars, Cloudflare, Codecov, Cohere, Coinbase, Confluent, Contentful, CrowdStrike, curl (netrc), Cursor, Databricks, Datadog, Deepgram, DeepSeek, DigitalOcean, Discord, Doppler, Drone CI, Dropbox, Duffel, Dynatrace, EasyPost, Elastic, ElevenLabs, Endor Labs, Etsy, Exoscale, Facebook, Fastly, Figma, Finicity, Finnhub, Flickr, Flutterwave, Fly.io, Frame.io, Freemius, FreshBooks, Gitea, GitHub, GitLab, Gitter, GoCardless, Google Cloud (GCP), Grafana, Greptile, Groq, Harness, HashiCorp, Heroku, HubSpot, Hugging Face, Infomaniak, Infracost, Intercom, Intra 42, JFrog, Kraken, KuCoin, Kubernetes, LaunchDarkly, LightOn, Linear, LinkedIn, Lob, Looker, Mailchimp, Mailgun, Mapbox, Mattermost, MaxMind, MessageBird, Microsoft, Mistral, MongoDB, Netlify, New Relic, New York Times, Notion, npm, NVIDIA, Octopus Deploy, Okta, Ollama, OpenAI, OpenRouter, OpenShift, OVH, Perplexity, Plaid, PlanetScale, Polymarket, PostHog, Postman, Prefect, Private AI, Pulumi, PyPI, RapidAPI, ReadMe, Replicate, RubyGems, Scaleway, Scalingo, Sendbird, SendGrid, Sentry, SettleMint, Shippo, Shopify, Sidekiq, Slack, Snyk, Sourcegraph, Square, Squarespace, Stability AI, Stripe, Sumo Logic, Telegram, Together AI, Travis CI, Twilio, Twitch, Twitter/X, Typeform, UpCloud, Upstage, HashiCorp Vault, Vercel, Weights & Biases, xAI, Yandex, and Zendesk.
New providers are added regularly — run xgrep scan --category secrets to scan
with the current set.
Always reported, even in tests
xgrep's production scope drops security findings in test and example paths by default — but secrets are always kept, wherever they live. A credential committed to a test fixture is just as compromised as one in production code.
Kept is not the same as indistinguishable. On a large repository most committed keys are usually test fixtures — well-formed, so reported at their full severity — and they would otherwise bury the one production credential you ran the scan to find. So a secret in a test, spec, fixture, example or docs path is marked:
-
Every machine format carries the marker —
extra.scope: "test"in--json, ascoperesult property in--sarif, and anxgrep_scopeidentifier in the GitLab report. It is omitted for production code, so a consumer can split the two with one field. -
The human view lists production secrets first and collapses the test-path ones to a single line, so nothing disappears silently:
105 secrets in test/fixture/example paths not listed — still counted and in --json/--sarif (extra.scope: "test"); rerun with --show-test-secrets to list them--show-test-secretslists them after the production findings, labelledscope: test.--include-testslists them too.
Nothing else changes: their severity is the same as anywhere else, they count
toward --error and --max-findings, and every machine format includes them.
In CI
Secrets scanning runs in CI like any other scan, and because findings are emitted as SARIF or GitLab SAST, leaked credentials show up in GitHub Code Scanning or the GitLab Vulnerability Report. Pair history scanning with a scheduled job to audit a repository's entire past:
xgrep --history --category secrets --sarif -o secrets.sarif .On Azure Pipelines, add fetchDepth: 0 to the checkout: self step so the job
has the full history to walk (new Azure pipelines default to a shallow clone):
steps:
- checkout: self
fetchDepth: 0
- script: npm install -g @mondoohq/xgrep
- script: xgrep --history --category secrets --sarif -o secrets.sarif .