From 1172c5394f79d019fb78474b9efd2ec3d4766b92 Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Fri, 13 Feb 2026 20:49:58 -0500 Subject: [PATCH] docs: save Phase C redaction planning state Co-Authored-By: Claude Opus 4.6 --- .../2026-02-13-export-phase-c-planning.md | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs/plans/2026-02-13-export-phase-c-planning.md diff --git a/docs/plans/2026-02-13-export-phase-c-planning.md b/docs/plans/2026-02-13-export-phase-c-planning.md new file mode 100644 index 00000000..09295586 --- /dev/null +++ b/docs/plans/2026-02-13-export-phase-c-planning.md @@ -0,0 +1,57 @@ +# Phase C: Sensitive Data Redaction — Planning State + +> **Status:** In planning — awaiting UI complexity decision +> **Spec:** `docs/plans/2026-02-13-EXPORT-IMPROVEMENTS-SPEC.md` section C1 +> **Branch:** Not yet created (will be `feat/export-phase-c`) + +## Open Question + +**How much UI complexity for the redaction feature?** + +The spec describes per-item highlighting and individual mask/unmask toggles, which requires replacing the textarea with a custom editor component. Three options: + +1. **Simple toggle (Recommended)** — Server-side mask toggle in preview modal. "Mask Sensitive Data" checkbox re-fetches with redaction applied. User sees summary of what was found (e.g. "3 IPs, 2 emails masked"). Manual editing for fine-tuning. Keeps the existing textarea. + +2. **Highlighted preview** — Replace textarea with a rich editor that highlights detected patterns in yellow. "Mask All" button replaces them. No per-item toggle. + +3. **Full spec (per-item toggle)** — Rich editor with highlights + individual checkboxes per detected item. Most complex — requires custom editor component, match tracking, and state management for each item. + +## What's Already Decided + +### Backend Architecture +- New file: `backend/app/services/redaction_service.py` +- Redaction happens BEFORE generators (pre-process session copy) +- `redaction_mode: Literal["none", "mask"] = "none"` added to `SessionExport` schema +- Regex patterns: IPv4, IPv6, email, bearer tokens, API keys, UNC paths +- Hostname redaction: opt-in (MSP tickets legitimately need hostnames) +- Deep copy of session — original DB record never modified +- No migration needed + +### Integration Point +In `backend/app/api/endpoints/sessions.py` line 296 (after session fetch, before generator call): +```python +if export_options.redaction_mode == "mask": + session = apply_redaction(session) # Returns sanitized copy +``` + +### Regex Patterns (conservative — false positives > false negatives) +- IPv4: `\b(?:\d{1,3}\.){3}\d{1,3}\b` → `[IP REDACTED]` +- IPv6: `\b(?:[0-9a-fA-F]{1,4}:){2,7}[0-9a-fA-F]{1,4}\b` → `[IP REDACTED]` +- Email: `\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b` → `[EMAIL REDACTED]` +- Bearer tokens: `Bearer\s+[A-Za-z0-9._-]+` → `[TOKEN REDACTED]` +- API key patterns: Long hex/base64 strings (32+ chars) → `[TOKEN REDACTED]` +- UNC paths: `\\\\[\w.-]+\\[\w$.-]+` → `[UNC PATH REDACTED]` + +### Files to Modify +**Backend:** +- Create: `backend/app/services/redaction_service.py` +- Modify: `backend/app/schemas/session.py` (add `redaction_mode` to `SessionExport`) +- Modify: `backend/app/api/endpoints/sessions.py` (3-line integration) + +**Frontend:** +- Modify: `frontend/src/types/session.ts` (add `redaction_mode` to `SessionExport`) +- Modify: `frontend/src/components/session/ExportPreviewModal.tsx` (add toggle) +- Modify: `frontend/src/pages/SessionDetailPage.tsx` (wire redaction state) + +**Tests:** +- Create or extend: `backend/tests/test_psa_export.py` (add `TestPhaseC` class)