redact: name the tiers where they are used, and stop the docstring lying about tier 3
Review caught that the tier vocabulary was used in the report, the commit message and the docs without being defined anywhere the reader would land, and inspecting that turned up two real defects rather than just a wording gap. 1. STALE DOCSTRING. The module still described tier 3 as if it redacts, which stopped being true when the 403-hit measurement demoted it to report-only. It also credited tier 3 with resolving the 40-hex-PAT-vs-commit-sha collision — false by default, since a reporting rule resolves nothing. Corrected, with the consequence stated plainly: in the default configuration a sha-shaped PAT is caught if and only if it belongs to THIS machine, because only a known value (tier 1) or a naming key (tier 3, reporting) can separate it from a commit sha. That is an accepted gap; the alternative is redacting every sha in the palace. 2. THE VOCABULARY NEVER REACHED THE OUTPUT. The tool prints rule names (github-pat, env-value, url-credentials) and nothing printed a tier, so the docs' tier language was unconnected to what an operator actually sees. Added RULE_TIERS as the authoritative rule -> tier mapping, tier_of(), and Finding.tier; the feeder now prints "T2:github-pat=6" so what matched and how much to trust it are both visible on one line. A self-test asserts every rule that can appear in a Finding maps to a tier, so adding a rule without classifying it fails the tests instead of printing "T?". Tiers, for the record, are three kinds of EVIDENCE (not three severities): T1 known value from this process's env — near-certain, zero FP by construction; T2 known vendor shape — strong, the prefix is meaningful; T3 key name says secret — candidate only, measured FP-heavy, reported. T0 is reserved for suspicions(), which is a measured NON-detection. Docs gain worked one-line examples per tier and a "which tier fired?" section showing real output. 46 self-test cases pass.
This commit is contained in:
@@ -856,7 +856,10 @@ for path in paths:
|
||||
if _hard:
|
||||
_by = {}
|
||||
for x in _hard:
|
||||
_by[x.rule] = _by.get(x.rule, 0) + 1
|
||||
# "T2:github-pat" — rule says what matched, tier says how much to
|
||||
# trust it, which is what the reader of this line actually needs.
|
||||
_k = f"T{x.tier}:{x.rule}"
|
||||
_by[_k] = _by.get(_k, 0) + 1
|
||||
print(f" [REDACTED] {path.name} "
|
||||
+ ", ".join(f"{k}={v}" for k, v in sorted(_by.items()))
|
||||
+ " fp=" + ",".join(sorted({x.fingerprint for x in _hard})),
|
||||
|
||||
Reference in New Issue
Block a user