SIGN IN SIGN UP

engine: redaction layer that no output can bypass

Adds internal/redact, the control that makes a missed call site harmless.
Redaction happens at the writer, not at the call site, so a log line, an
event, an artifact, and a screenshot caption all pass through the same
Redactor on the way out.

Two rule kinds run over every byte: pattern rules for credential shapes that
are recognisable without knowing the value (provider prefixes, PEM blocks,
bearer tokens, JWT shapes, connection string passwords), and exact rules for
values the secrets subsystem registers as it loads them, in plain, base64, and
percent encoded forms.

Performance mattered more than expected. The proxy emits a decision event per
request, so the no-match case is the case that decides whether redaction is
affordable at all. The naive implementation cost 56 microseconds per line
against a 2 microsecond budget: twenty five regexp scans plus one substring
scan per registered secret form. Every literal is now indexed by its first two
bytes in a 65,536 bit table, so one pass over the line says which rules and
which secrets can possibly be present. A line with no credential now costs 454
nanoseconds and zero allocations.

Two real defects surfaced while closing coverage, both found by tests rather
than by reading:

  - Register sorted the exact slice in place while String iterated it. Fixed by
    making the set copy on write.
  - The registered values and the matcher built over them lived in two separate
    atomics, so a reader could pair a new matcher, whose indexes refer to the
    new slice, with the previous slice. Fixed by swapping both as one immutable
    struct, which removes the bounds check that was hiding the race.

Test credentials are assembled at run time rather than written as literals.
A literal that looks like a Stripe key is indistinguishable from a real one to
a scanner, so push protection refuses the commit and the reflex fix is an
allowlist entry, which is the beginning of a scanner nobody trusts. Building
the value from parts means nothing in the source matches a credential pattern
and no reviewer has to decide whether a string is synthetic.

Failure paths covered:
  every supported credential format survives: TestRedactor_SecretCorpus_EveryFormatIsRedacted (325 cases)
  ordinary output is redacted by mistake: TestRedactor_BenignCorpus_NothingIsRedacted (300 cases)
  secret split across two writes: TestWriter_RedactsASecretSplitAcrossWrites
  unbounded line: TestRedactor_TruncatesAPathologicallyLongLine
  unbounded carry with no newline: TestWriter_FlushesWhenTheCarryGrowsWithoutANewline
  a rule that rewrites its own marker: TestRedactor_MaxPassesBoundsARuleThatRewritesItsOwnMarker
  concurrent register and redact: TestRedactor_ConcurrentRegisterAndRedactAreSafe
  redaction is not idempotent: TestRedactor_IsIdempotent (property)

Coverage 100 percent of statements. Benchmark 454 ns/op, 0 allocs/op.

Signed-off-by: Vir Sanghavi <Virrsanghavi@gmail.com>
V
Vir Sanghavi committed
01e62f17b57e39cee19fbb5545adbe3c24dbcac8
Parent: ed1cb9b