rgs (ripgrep secrets)
A ripgrep-powered secret scanner that uses JSON rule packs (regex rules) to find secrets in codebases, configs, and repositories.
Go >= 1.23 | License: MIT | Built-in rules: 217 | Packs: 13 | Types: 117
Table of Contents
Overview
rgs is a CLI wrapper around rg (ripgrep) for secret scanning. It loads a ruleset (built-in rules plus optional custom rules), filters it by pack/type/id and confidence, writes the enabled regex patterns to a temporary pattern file, then runs ripgrep against a directory tree.
Important behavior to understand before using it in CI or sharing output:
- Matches are regex hits. There is no online verification that a token is valid.
- Output includes secret values by default. Treat it as sensitive data.
- Rules are executed as a single ripgrep pattern file, so scan output does not currently label which specific rule matched.
Features
-
ripgrep-backed scanning for fast repository traversal and searching.
-
Built-in coverage across many providers and categories:
- 217 built-in rules
- 13 packs
- 117 leak types
-
Pack, type, and rule id filtering for targeted scans.
-
Generic rules that catch unknown secrets based on common assignment patterns (useful, noisier).
-
Output formats:
text (ripgrep-style output)
json (ripgrep --json event stream)
html (single-file report)
-
"Only matching" mode to extract just the matched substring(s) rather than full lines.
-
Optional sorting by file modification time (mtime) for deterministic review workflows.
-
Pass-through support for additional ripgrep flags.
Installation
Using Go Install
go install github.com/doug147/rgsecrets/cmd/rgs@latest
This installs rgs into your Go bin directory (commonly $(go env GOPATH)/bin).
Building from Source
git clone github.com/doug147/rgsecrets
cd rgsecrets
make build
./bin/rgs --help
Adding Go Bin to PATH
If go install succeeds but rgs is not found, add Go's bin directory to your PATH.
Linux / macOS (bash or zsh):
export PATH="$PATH:$(go env GOPATH)/bin"
Windows (PowerShell):
$env:PATH += ";$(go env GOPATH)\bin"
Verify:
rgs version
Usage
rgs <command> [options]
Commands:
scan Scan a directory tree
packs List available rule packs (and which are enabled by filters)
types List available leak types (and which are enabled by filters)
rules List rules (id, type, confidence, allow-binary)
version Show version information
help Show help
Scanning
Basic scan of the current directory using built-in rules:
rgs scan -r .
Scan a different root:
rgs scan -r /path/to/repo
By default, rgs includes built-in rules and applies default excludes (like .git, node_modules, etc).
Default scans skip the crypto pack to reduce false positives, even when scanning “all rules”. To include it, pass --include-packs crypto (or an include filter that targets crypto types/rules).
Filtering by Pack, Type, and Rule ID
Include packs (comma-separated):
rgs scan -r . --include-packs ai,cloud,scm
Exclude packs:
rgs scan -r . --exclude-packs generic
Include type tokens (substring match against the rule type field):
rgs scan -r . --include-types aws,github
Exclude type tokens:
rgs scan -r . --exclude-types generic
Include specific rule ids (exact match, case-insensitive):
rgs scan -r . --include-rules cloud_aws_access_key_id
Exclude specific rule ids:
rgs scan -r . --exclude-rules cloud_aws_secret_access_key
Raise the minimum confidence threshold (0-100):
rgs scan -r . --min-confidence 80
Pack shorthand: any non-flag positional argument that matches a known pack name is treated as an include-pack.
rgs scan -r . ai
rgs scan -r . ai,cloud
Shorthand aliases are also supported:
rgs scan -r . -ip ai,cloud
rgs scan -r . -it aws,github
rgs scan -r . -mc 80
Text output (default):
rgs scan -r . -f text
JSON output (ripgrep --json event stream, JSON lines):
rgs scan -r . -f json
HTML report output (requires --out):
rgs scan -r . -f html -o report.html --title "Secrets Report"
Only Matching Substrings
--only-matching prints the matched substring(s) rather than the full line.
Text:
rgs scan -r . --only-matching
JSON (emits JSON lines of {file,line,text} objects):
rgs scan -r . -f json --only-matching > matches.jsonl
HTML (highlights only the matched substring):
rgs scan -r . -f html -o report.html --only-matching
Sorting
Sort file scan order by mtime:
rgs scan -r . --sort mtime-asc
rgs scan -r . --sort mtime-desc
Notes:
- Sorting changes how
rgs executes the scan: it first lists matching files, sorts them, then scans the sorted list.
- When sorting is enabled and you do not provide a ripgrep
--threads override, rgs forces rg --threads 1.
Passing ripgrep Arguments
Everything after -- is passed directly to ripgrep.
Examples:
Pass max line length:
rgs scan -r . -- -M 250
Limit max file size:
rgs scan -r . -- --max-filesize 10M
Include hidden files and ignore ignore-files:
rgs scan -r . -- --hidden --no-ignore
You can also pass extra ripgrep args with --rg-arg (repeatable):
rgs scan -r . --rg-arg --max-filesize --rg-arg 10M
Dry-run the underlying ripgrep command:
rgs scan -r . --dry-run
Inspecting Packs, Types, and Rules
List packs:
rgs packs
rgs packs -f json
List types:
rgs types
rgs types -f json
List rules:
rgs rules
rgs rules -f json
These commands apply the same filters (include/exclude packs/types/rules, min-confidence, no-default-rules) so you can validate what will be enabled before scanning.
Examples
Scan only cloud and SCM related rules, require higher confidence, write an HTML report:
rgs scan -r . -ip cloud,scm -mc 80 -f html -o report.html --title "Cloud + SCM Secret Scan"
Run a vendor-specific pass first (lower noise), then a broader generic pass:
rgs scan -r . -ip ai,cloud,scm,db,pay,obs,financial,pkg,auth,url -mc 80
rgs scan -r . -ip generic -mc 60
Exclude common build output directories (in addition to defaults):
rgs scan -r . -x "coverage,bin,out,*.min.js"
Disable default excludes (scan everything under the root):
rgs scan -r . --no-default-excludes
Disable built-in rules and use only your custom config rules:
rgs scan -r . --no-default-rules -c rgs.config.json
Only extract matching token strings (useful for piping into other tooling):
rgs scan -r . --only-matching -- --max-filesize 10M
Options Reference
Global Options
| Option |
Default |
Description |
--log-level |
info |
Log level: debug, info, warn, error |
-v, --verbose |
false |
Verbose output (sets log level to debug) |
-q, --quiet |
false |
Suppress non-error output |
--version |
false |
Print version and exit |
version |
|
Print version information |
scan Options
| Option |
Default |
Description |
-r, --root |
. |
Root directory to scan |
-c, --config |
empty |
Optional JSON config file (relative to --root if not absolute) |
-f, --format |
text |
Output format: text, json, html |
-o, --out |
empty |
Write output to a file (required for html) |
--title |
empty |
Report title (HTML only) |
-b, --include-binary |
true |
Scan binary files as text (rg --text) |
-x, --exclude |
empty |
Exclude globs (comma-separated) |
--no-default-excludes |
false |
Disable default excludes |
-n, --dry-run |
false |
Print the rg command and exit |
--fail |
false |
Exit with code 2 if matches are found |
-m, --only-matching |
false |
Output only matched substring(s) |
-s, --sort |
empty |
Sort mode: mtime-asc or mtime-desc (if -s is used with no value, defaults to mtime-asc) |
--rg-arg |
empty |
Extra ripgrep arg (repeatable). Prefer passing args after -- |
--progress |
auto |
Progress display: auto, on, off (stderr) |
--pcre2 |
auto |
PCRE2 mode: auto, on, off |
--multiline |
auto |
Multiline mode: auto, on, off |
Filter Options
| Option |
Default |
Description |
--no-default-rules |
false |
Do not load built-in rules |
-C, --min-confidence |
40 |
Minimum confidence (0-100) required for a rule to be enabled |
-t, --include-types |
empty |
Only scan types whose name contains any of these tokens |
-T, --exclude-types |
empty |
Exclude types whose name contains any of these tokens |
-I, --include-rules |
empty |
Only scan these rule ids (exact match) |
-E, --exclude-rules |
empty |
Exclude these rule ids (exact match) |
-P, --include-packs |
empty |
Only scan these packs |
-K, --exclude-packs |
empty |
Exclude these packs |
Shorthand aliases (normalized before flag parsing):
| Alias |
Expands to |
-mc |
--min-confidence |
-ib |
--include-binary |
-it |
--include-types |
-et |
--exclude-types |
-ir |
--include-rules |
-er |
--exclude-rules |
-ip |
--include-packs |
-ep |
--exclude-packs |
Configuration
Config File Schema
Config is JSON. Pass it with --config (relative to --root if not absolute).
{
"no_default_rules": false,
"rules": [],
"exclude": [".git", "node_modules"],
"no_default_excludes": false,
"include_binary": true,
"min_confidence": 40,
"include_types": [],
"exclude_types": [],
"include_rules": [],
"exclude_rules": [],
"include_packs": [],
"exclude_packs": [],
"format": "text",
"out": "",
"title": "",
"sort": "mtime-asc",
"pcre2": "auto",
"multiline": "auto"
}
Config precedence and merge behavior:
Adding Custom Rules
Custom rules can be appended via config under rules. Each rule supports:
id (string): unique rule id
type (string): type name used for type filtering
pack (string, optional): pack name. If omitted, pack is derived from the prefix of type or id up to the first . or _
description (string): human-readable description
regex (string): regex pattern
base_confidence (int 0-100): used by --min-confidence
value_group (int): capture group index (currently informational)
allow_binary (bool): rule hint (currently informational)
max_match_bytes (int): rule hint (currently informational)
Example:
{
"rules": [
{
"id": "custom_example_token",
"type": "custom_tokens",
"pack": "custom",
"description": "Example token format",
"regex": "\\bEXAMPLE_[A-Za-z0-9]{32}\\b",
"base_confidence": 80,
"value_group": 0,
"allow_binary": false,
"max_match_bytes": 256
}
]
}
Built-in Coverage
Built-in rules: 217 rules across 13 packs and 117 types.
Built-in Rule Packs
| Pack |
Rules |
ai |
38 |
cloud |
37 |
msg |
26 |
pay |
25 |
obs |
16 |
financial |
14 |
crypto |
13 |
scm |
12 |
pkg |
11 |
db |
10 |
auth |
9 |
generic |
3 |
url |
3 |
Built-in Types
| Type |
Pack |
Rules |
ai_ai21_labs |
ai |
1 |
ai_aleph_alpha |
ai |
1 |
ai_anthropic |
ai |
4 |
ai_azure |
ai |
1 |
ai_cohere |
ai |
2 |
ai_deepseek |
ai |
2 |
ai_fireworks |
ai |
2 |
ai_google_vertex |
ai |
1 |
ai_groq |
ai |
2 |
ai_huggingface |
ai |
4 |
ai_ibm_watson |
ai |
1 |
ai_mistral |
ai |
2 |
ai_openai |
ai |
4 |
ai_openrouter |
ai |
3 |
ai_perplexity |
ai |
1 |
ai_replicate |
ai |
3 |
ai_stability_ai |
ai |
1 |
ai_together |
ai |
2 |
ai_xai |
ai |
1 |
auth_auth0 |
auth |
1 |
auth_azure_ad_entra_id |
auth |
1 |
auth_header |
auth |
2 |
auth_jwt |
auth |
1 |
auth_okta |
auth |
2 |
auth_onelogin |
auth |
1 |
auth_ping_identity |
auth |
1 |
cloud_alibaba |
cloud |
5 |
cloud_aws |
cloud |
5 |
cloud_azure |
cloud |
5 |
cloud_cloudflare |
cloud |
1 |
cloud_digitalocean |
cloud |
3 |
cloud_gcp |
cloud |
5 |
cloud_heroku |
cloud |
2 |
cloud_huawei |
cloud |
1 |
cloud_ibm |
cloud |
1 |
cloud_linode |
cloud |
1 |
cloud_oci |
cloud |
2 |
cloud_ovh |
cloud |
1 |
cloud_tencent |
cloud |
4 |
cloud_vultr |
cloud |
1 |
crypto_bip39_mnemonic_12_or_24_words |
crypto |
1 |
crypto_dogecoin_wif_private_key |
crypto |
1 |
crypto_ethereum_private_key |
crypto |
1 |
crypto_hd_wallet_extended_private_key |
crypto |
1 |
crypto_litecoin_wif_private_key |
crypto |
1 |
crypto_private_key |
crypto |
2 |
crypto_ripple_secret_key |
crypto |
1 |
crypto_tron_private_key |
crypto |
1 |
crypto_wallet |
crypto |
4 |
db_connection_string_userpass_in_url |
db |
1 |
db_generic_db_password_vars |
db |
1 |
db_jdbc_userpass |
db |
1 |
db_mongodb |
db |
1 |
db_mssql |
db |
1 |
db_mysql |
db |
1 |
db_pgpass |
db |
1 |
db_postgres |
db |
1 |
db_redis |
db |
1 |
db_url_env |
db |
1 |
financial_alpaca |
financial |
1 |
financial_binance |
financial |
2 |
financial_bitvavo |
financial |
2 |
financial_coinpayments |
financial |
1 |
financial_kraken |
financial |
2 |
financial_nowpayments |
financial |
2 |
financial_okx |
financial |
2 |
financial_plaid |
financial |
1 |
financial_robinhood |
financial |
1 |
generic_medium |
generic |
2 |
generic_tight |
generic |
1 |
msg_brevo |
msg |
2 |
msg_discord |
msg |
3 |
msg_mailchimp |
msg |
2 |
msg_mailgun |
msg |
2 |
msg_postmark |
msg |
1 |
msg_sendgrid |
msg |
3 |
msg_slack |
msg |
4 |
msg_sparkpost |
msg |
1 |
msg_telegram |
msg |
3 |
msg_twilio |
msg |
4 |
msg_vonage |
msg |
1 |
obs_bugsnag |
obs |
1 |
obs_datadog |
obs |
2 |
obs_dynatrace |
obs |
2 |
obs_grafana |
obs |
1 |
obs_honeycomb |
obs |
1 |
obs_new_relic |
obs |
2 |
obs_rollbar |
obs |
1 |
obs_sentry |
obs |
4 |
obs_splunk |
obs |
1 |
obs_sumologic |
obs |
1 |
pay_adyen |
pay |
1 |
pay_amazon_pay |
pay |
1 |
pay_authorize_net |
pay |
1 |
pay_klarna |
pay |
1 |
pay_mollie |
pay |
2 |
pay_paypal |
pay |
1 |
pay_paypal_braintree |
pay |
2 |
pay_paystack |
pay |
2 |
pay_paytm |
pay |
1 |
pay_razorpay |
pay |
3 |
pay_square |
pay |
4 |
pay_stripe |
pay |
4 |
pay_twocheckout_verifone |
pay |
1 |
pay_worldpay |
pay |
1 |
pkg_crates_io |
pkg |
1 |
pkg_npm |
pkg |
3 |
pkg_nuget |
pkg |
1 |
pkg_packagist_composer |
pkg |
1 |
pkg_pypi |
pkg |
3 |
pkg_rubygems |
pkg |
1 |
pkg_sonatype_ossrh |
pkg |
1 |
scm_azure_devops |
scm |
1 |
scm_bitbucket |
scm |
2 |
scm_github |
scm |
5 |
scm_gitlab |
scm |
4 |
url_credentials |
url |
3 |
Generic Rules
In addition to provider-specific patterns (high precision), rgs includes a generic pack designed to catch secrets that do not match a known vendor token format.
These generic rules focus on common assignment patterns and "secret-ish" variable names. This makes them useful for catching internal tokens and bespoke API keys, but they will typically produce more false positives than vendor-specific packs.
Common ways to manage noise:
- Run vendor packs first, then run
generic as a second pass.
- Increase
--min-confidence.
- Exclude
generic when you only want known token formats.
If scans feel slow, these are the first settings to review:
-
Reduce scope with packs and types:
rgs scan -r . -ip cloud,scm -mc 80
-
Disable binary scanning if you do not need it:
rgs scan -r . --include-binary=false
-
Prefer ripgrep limits for large repositories:
rgs scan -r . -- --max-filesize 10M
-
Avoid sorting unless you need deterministic ordering:
- sorted scans do extra work and may run single-threaded unless you explicitly set ripgrep threads.
Troubleshooting
rg not found in PATH
Install ripgrep and ensure rg is available:
rg --version
HTML requires --out
rgs scan -r . -f html -o report.html
No rules enabled after filters
You may have filtered everything out (packs/types/rules too restrictive or --min-confidence too high). Inspect what is enabled:
rgs packs
rgs types
rgs rules
PCRE2 errors
If you set --pcre2 on (or if --pcre2 auto selects PCRE2 for your custom rules) and your ripgrep build does not include PCRE2 support, the scan will fail.
Check support:
rg --pcre2-version
Disclaimer
This tool is intended for scanning code and repositories that you own or have explicit authorization to test. Output may contain sensitive data. Do not commit reports or raw scan output to source control or attach them to public issues.
License
MIT. See LICENSE.