gitleaks/gitleaks
Composite (multi-part / required) rules
Introduced in v8.28.0. A composite rule is a primary rule that only fires when one or more auxiliary rules also produce findings within a configurable proximity. Useful for "AWS access key paired with a secret access key on the same line" style patterns.
Per the README, this is an experimental feature: "It's subject to change so don't go sellin' a new B2B SaaS feature built on top of this feature."
TOML shape
[[rules]]
id = "aws-keypair"
description = "AWS access key + secret key on the same line"
regex = '''AKIA[0-9A-Z]{16}'''
keywords = ["AKIA"]
[[rules.required]]
id = "aws-secret-access-key"
withinLines = 0
withinColumns = 80The required entry references another rule by ID. withinLines and withinColumns constrain the proximity of the auxiliary match to the primary match.
Proximity semantics
withinLines |
withinColumns |
Behavior |
|---|---|---|
| unset | unset | Fragment-level match: required finding can be anywhere in the same fragment |
N |
unset | Within N lines vertically |
| unset | N |
Within N columns horizontally |
N |
M |
Both (rectangular search area, both must be satisfied) |
The README has ASCII-art diagrams for each case. Implementation is Detector.withinProximity in detect/detect.go:
if requiredRule.WithinLines == nil && requiredRule.WithinColumns == nil {
return true // fragment-level
}
if requiredRule.WithinLines != nil && abs(primary.StartLine - required.StartLine) > *requiredRule.WithinLines {
return false
}
if requiredRule.WithinColumns != nil && abs(primary.StartColumn - required.StartColumn) > *requiredRule.WithinColumns {
return false
}
return trueThe proximity uses StartLine / StartColumn for both findings — i.e., the upper-left corner of each match's location.
Implementation flow
graph TD
P[primary findings from rule R] --> RR[for each rule R.RequiredRules]
RR --> Recurse[detectRule on auxiliary rule<br/>fragment.InheritedFromFinding=true]
Recurse --> Coll[collect all auxiliary findings]
Coll --> Loop[for each primary finding]
Loop --> Prox[filter aux findings by withinProximity]
Prox --> Has{at least one aux<br/>per required rule?}
Has -->|no| Drop[drop primary finding]
Has -->|yes| Attach[attach aux findings,<br/>emit primary]processRequiredRules in detect/detect.go does this:
- Pre-collect all auxiliary findings once per required rule (so an N×M loop becomes N+M).
- Mark the fragment as
InheritedFromFinding = truebefore recursing intodetectRulefor the auxiliary, which prevents an auxiliary that is itself composite from re-recursing. - For each primary finding, filter pre-collected auxiliaries by
withinProximity. hasAllRequiredRuleschecks that we have at least one auxiliary for every entry inR.RequiredRules. If any required rule yielded zero in-proximity auxiliaries, the primary is dropped.- Surviving primary findings get the auxiliary findings attached via
Finding.AddRequiredFindings.
SkipReport
Auxiliary rules often only exist to validate a primary rule and shouldn't produce standalone findings. Set skipReport = true on a rule to keep it out of the main findings list:
[[rules]]
id = "aws-secret-access-key"
description = "(used only as auxiliary)"
regex = '''(?i)aws.{0,20}(secret|access).{0,20}[A-Za-z0-9/+=]{40}'''
skipReport = true
keywords = ["aws"]Inside detectRule, the very first guard is if r.SkipReport && !fragment.InheritedFromFinding { return findings } — so the rule still runs when called from processRequiredRules (where InheritedFromFinding is true), but is silent for top-level scanning.
Output
When a composite rule fires, the primary finding's requiredFindings slice is populated. In verbose terminal output, Finding.PrintRequiredFindings (report/finding.go) prints:
Required: aws-secret-access-key:42:wJalrXU...truncated...In structured output formats, RequiredFinding is a report type that's currently kept private (requiredFindings is unexported on Finding) per the comment "keeping private for now to during experimental phase". Library consumers can call f.AddRequiredFindings(...) but cannot read them back yet.
Related
- Secret detection — the surrounding rule pipeline
- systems/detect — full implementation walk-through
- systems/config — how
[[rules.required]]is parsed
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.