Skip to content

feat(observability): mask pii in structured logs - #255

Merged
tiana-code merged 1 commit into
mainfrom
feat/E-07-pii-scrub
Jun 19, 2026
Merged

feat(observability): mask pii in structured logs#255
tiana-code merged 1 commit into
mainfrom
feat/E-07-pii-scrub

Conversation

@tiana-code

Copy link
Copy Markdown
Owner

Adds best-effort PII masking to the structured logs across all three services (E-07, #247).

What

  • New shared module libs/fincore-observability with:
    • PiiMasker - a pure, ReDoS-safe masker (emails, bearer tokens, 13+ digit runs -> [REDACTED]). All three regexes use single bounded quantifiers (no catastrophic backtracking). The 13+ digit rule masks PAN/account/long-id runs (including 20+) but never a UUID's fixed 12-digit node group.
    • PiiMaskingMembersCustomizer - a Boot StructuredLoggingJsonMembersCustomizer that applies the masker to string members of the logstash JSON, skipping correlation_id/trace_id/span_id.
  • Wired into ledger, payments and decision via a single logging.structured.json.customizer line each, so the existing structured-log JSON shape is preserved (no logback-spring.xml, consistent with F-07.2 Correlation-id and MDC logging parity for payments and decision #246).

Why this hook

The services emit JSON via Boot-native StructuredLogEncoder ("logstash"), not the net.logstash encoder. The Boot 3.5.15 StructuredLoggingJsonMembersCustomizer + JsonWriter.ValueProcessor API (verified against the jar) lets us rewrite member values in-place without reconstructing the appender, keeping the JSON contract intact.

Verification

  • New module unit tests (incl. an encoder-level test that masks a message while correlation_id/trace_id/span_id survive byte-for-byte and the JSON shape holds) - all green locally (no Docker needed).
  • All three services compile/test/detekt/spotless green after the dep + yaml registration.

Gate chain

  • critic: GO-WITH-CHANGES (applied; exact API pinned).
  • security-auditor (opus): PASS - all three regexes empirically benchmarked linear/ReDoS-safe, masker cannot throw, identity fields preserved.
  • code-reviewer: deliverables APPROVED; a HIGH "slice-mixing" flag was a false positive (the F-07.2 Correlation-id and MDC logging parity for payments and decision #246 files are already in main; git log main..HEAD is empty) and its two advisory test gaps were adopted.
  • evaluator: PASS (0.93 >= 0.80).

Closes #247

Add a shared fincore-observability module with a pure, ReDoS-safe
PiiMasker (emails, bearer tokens, 13+ digit runs -> [REDACTED]) and a
Boot StructuredLoggingJsonMembersCustomizer that applies it to string
members of the logstash JSON output while leaving correlation_id,
trace_id and span_id intact. Wired into ledger, payments and decision
via a one-line logging.structured.json.customizer registration, so the
existing structured-log shape is preserved.

Closes #247
@tiana-code tiana-code added this to the v0.2.0 milestone Jun 19, 2026
@tiana-code
tiana-code merged commit 3935c70 into main Jun 19, 2026
8 checks passed
@tiana-code
tiana-code deleted the feat/E-07-pii-scrub branch June 19, 2026 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F-07.3 PII scrubbing Logback filter

1 participant