Skip to content

chore(security): PII fixture audit — all PII_ARRAY_FIELDS clean across tier-coverage#138

Open
petterlindstrom79 wants to merge 1 commit into
mainfrom
chore/pii-fixture-audit-legal-representatives
Open

chore(security): PII fixture audit — all PII_ARRAY_FIELDS clean across tier-coverage#138
petterlindstrom79 wants to merge 1 commit into
mainfrom
chore/pii-fixture-audit-legal-representatives

Conversation

@petterlindstrom79
Copy link
Copy Markdown
Member

Summary

  • Post-incident audit prompted by the 2026-05-18 CZ near-miss (7 real Skoda board members written unscrubbed to a tier-coverage fixture; caught pre-commit; PR feat(t2): Phase 2 legal_representatives extraction for NO #136 + feat(t2): Phase 2 legal_representatives extraction for CZ #137 added legal_representatives to PII_ARRAY_FIELDS inline).
  • Swept every fixture under apps/api/tests/fixtures/tier-coverage/*.json for the full PII_ARRAY_FIELDS set (not just legal_representatives). All clean. Every present PII-array field is "[REDACTED]", null, or [].
  • Swept git history with git log -p --all -- apps/api/tests/fixtures/tier-coverage/. Zero commits ever pushed unredacted PII through that directory.
  • Single-file diff: the audit report itself. No code, no fixture, no schema changes.

Verification

  • Capture script verified: apps/api/scripts/capture-tier-fixtures.ts:91 includes legal_representatives; scrubber at line 109 redacts populated arrays.
  • 33 tier-coverage fixtures enumerated. 8 carry PII_ARRAY_FIELDS keys (br, cz, fr, gr, it, jp, no, sk); all show "[REDACTED]" / null / []. Other 25 carry no PII-array keys.
  • Git history: zero matches for unredacted PII additions.
  • tsc --noEmit / tests not re-run (docs-only diff).

Reviewer findings

Six-lens review (Pass A technical + Pass B product) returned zero HIGH. MEDIUM findings broken into two categories:

Inline-applied to the audit doc:

  • Title scope mismatch (B1) — retitled doc to "all PII_ARRAY_FIELDS" so it is findable by any of the 10 field names it covers, not just legal_representatives.
  • Validity window missing (B2) — added explicit "this audit's clean finding holds as long as (1)–(4)" paragraph to the Conclusion.
  • Scrubber caveats (B3 + A2) — documented that the scrubber is shallow (top-level keys only) and produces a type lie (T[] → string), so any future fixture-typed consumer must skip or cast PII_ARRAY_FIELDS keys.
  • Git-history grep limitation (A3) — noted that ^\+ filter only catches additions; an added-then-reverted commit would be invisible. Conclusion still defensible for the CZ incident because the pre-commit catch meant the unredacted fixture never reached git commit.

Flagged as out-of-scope follow-up (A1) — surfaced by review, not in audit scope:

Two manifest output_schema.example blocks committed to main contain real natural-person names (same class of PII the CZ near-miss surfaced):

  • `manifests/french-company-data.yaml:30-33` — three real TotalEnergies SE board members under `directors` (JACQUES ANDRE ASCHENBROICH, MARIE CHRISTINE COISNE, LISE CROTEAU).
  • `manifests/brazilian-company-data.yaml:30-32` — one real partner name + role under `partners` (CLAUDIA KICH DA SILVA, 16-Presidente).

`PII_ARRAY_FIELDS` does not touch `manifests/` (the scrubber only runs at capture time on executor output). Recommend chat-side opens a new to-do to either redact these names or replace with synthetic example data in the manifests. Not in scope for this PR.

Cross-repo

None — backend-only audit.

Test plan

  • Confirm audit report renders correctly in GitHub markdown view
  • Spot-check one or two of the per-handler verdicts against the actual fixture files
  • Confirm comfort with the four-point validity window (or push back if any of (1)-(4) feel under-stated)
  • Decide whether the surfaced manifest PII (FR + BR) warrants its own remediation PR

Refs Notion to-do `36467c87-082c-8117-8053-cb47e30a2c9f`.

🤖 Generated with Claude Code

Sweeps apps/api/tests/fixtures/tier-coverage/ for legal_representatives
arrays carrying unredacted PII from pre-PR-136/137 captures.

Handlers audited: brazilian, cz, french, greek, italian, japanese,
norwegian, slovak (8 with PII_ARRAY_FIELDS keys); plus 25 others with no
PII keys present.

Handlers re-captured: none — all clean (every PII array field present
across all fixtures is "[REDACTED]", null, or empty).

Git history check: zero commits ever pushed unredacted PII through
apps/api/tests/fixtures/tier-coverage/. The PR #125 / #136 / #137 inline
pattern (add field to PII_ARRAY_FIELDS during the capture run that
surfaced it) caught the GDPR exposure before any commit.

Verifies post-PR-136/137 capture-tier-fixtures.ts PII_ARRAY_FIELDS
scrubber catches legal_representatives going forward.

Refs Notion to-do 36467c87082c81178053cb47e30a2c9f

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant