Skip to content

Server-side PII detection on metadata: Json fields sent to AI service #213

Description

@kilodesodiq-arch

Problem Statement. Models in app/backend/prisma/schema.prisma's Campaign.metadata,
Claim.recipientRef, Session.metadata, SessionStep.input/output, and
InternalNote.content accept arbitrary PII (the README and SECURITY.md both flag PII as
in-scope for hardening). Some of these fields are forwarded to the AI service which, per the
AI service's own design, anonymises input text but cannot undo PII that lives in
metadata blobs.

Why it matters. Humanitarian PII leakage is a humanitarian incident. The platform's
private-by-design stance is only as strong as its widest write path.

Technical Context. The backend does not run the same PII scrubber that
pii_scrubber.py does. Either it accepts a JSON metadata blob unchanged, or it sends a
recipient address as a raw string.

Expected Outcome. A PiiScrubInterceptor (backend) strips common PII (email, phone,
personal-name patterns, IDs) from metadata-typed payload fields before storage or before
forwarding to the AI service. A redact mode replaces values with structured tokens; a strict
mode rejects the request with a 422 listing the offending field paths.

Acceptance Criteria.

  • An interceptor that traverses any object tree, identifies a configurable list of
    high-risk keys (email, phone, name, nin, etc.), and either redacts or rejects.
  • Unit tests cover deeply nested cases and arrays.
  • An opt-out knob PII_SCRUB_MODE=redact|reject|off (default redact).
  • The interceptor is registered after ValidationPipe in main.ts.

Implementation Notes. Share a Redis-cached, periodically-refreshed regex set from
/api/v1/pii/patterns. Consider a subtree-level allowlist (e.g. raw recipientRef from a
known-good JWT subject).

Files or modules likely to be affected. src/common/interceptors/pii-scrub.interceptor.ts
(new), src/main.ts, app/backend/test/pii-interceptor.spec.ts (new),
app/ai-service/services/pii_scrubber.py (reuse logic).

Dependencies. None.

Difficulty. Medium
Estimated effort. M



Backlog item #5 from `docs/maintainer-issue-backlog.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions