Writing rules

Rules live in TOML. Built-ins are in src/secretsweep/builtin_rules.toml; yours go in <repo>/.secretsweep.toml (auto-loaded) or any file passed with --rules. A user rule whose id matches a built-in replaces it; new ids are added. disabled_rules = ["id", ...] at the top level removes rules.

disabled_rules = ["jwt"]

[[rules]]
id = "acme-api-key"
description = "ACME Corp API key"
regex = '''\b(acme_[a-z0-9]{32})\b'''
keywords = ["acme_"]
severity = "high"
confidence = "high"
entropy = 3.2
allowlist = ['''(?i)example''']
rotate = "https://acme.example/settings/keys"

Use TOML literal strings ('''...''') so backslashes need no escaping.

Field Required Meaning
id yes Unique kebab-case id; appears in reports, SARIF and baselines
regex yes Python regex, applied to the whole text (multi-line capable)
description no Human text for reports
keywords no Lowercase substrings; if none occur in the file the rule is skipped. This is the main performance lever, so always set it for prefixed formats
severity no low, medium (default), high, critical
confidence no Base confidence when no validator speaks: low, medium (default), high
secret_group no Group holding the secret (default: group 1 if any, else the whole match). Fingerprints, redaction and entropy use this group
entropy no Minimum Shannon entropy of the secret; weeds out placeholders like aaaaaaaa
allowlist no Regexes searched in the secret; a hit drops the finding
path_regex no Rule only runs on paths matching this regex (relative POSIX path; archive members are archive.zip!member)
validator no github_checksum, jwt, pem, base64_userpass. valid raises confidence to high, invalid lowers it to low
pairs_with no Rule id; when both rules fire in the same file both become high confidence (used for the AWS key id and secret)
verifier no github or slack; makes the rule eligible for --verify
rotate no URL or hint printed by rewrite-guide

Process

  1. Pick a distinctive prefix or context phrase and put it in keywords.
  2. Capture only the secret in a group, with \b or a negative lookahead to avoid matching a longer string.
  3. Add entropy for random-looking secrets, an allowlist for placeholders.
  4. Test it: secretsweep rules list --rules my.toml validates the file (bad regexes, unknown validators and severities are errors with exit code 2), then scan a file containing a fake value.

Contributing a built-in rule

Add the rule to builtin_rules.toml and a (path, positive, negative) entry keyed by its id to tests/fakes.py. tests/test_rules.py fails if any rule lacks fixtures, and each positive must fire while the negative (a near miss such as a wrong length or a test-mode prefix) must not. Fixtures must be generated, well-formed but invalid values.