PII and logging¶
Status: Placeholder — to be developed. Last reviewed: — Reference structural sibling:
guidelines/i18n/translation-rules.md(rule + workflow + antipatterns style).
Scope (when this guideline lands)¶
What categories of data are PII (patient names, dates of birth, social security numbers, financial detail, dentist contracts) and what must never be logged, sent to Sentry, exported to CSV without redaction, or echoed back in error messages. Includes: how to scrub Sentry events, log-level conventions (DEBUG never in prod, INFO is the default), and the "if in doubt, don't log it" default for any field on Patient, Procedure, or Payment.
Out of scope (cross-refs)¶
- Multi-tenant data isolation (preventing one practice from seeing another's data via querysets) →
guidelines/security/multi-tenant-isolation.md(placeholder). This file covers WHAT can be logged about any data; that one covers WHO can read which rows. - Authentication and authorisation →
guidelines/security/auth-and-permissions.md(placeholder). - Validation of user-input PII →
guidelines/backend/forms.md(placeholder). - Audit trail on data changes (
AuditModelfromapps/core/) →guidelines/backend/models.md(placeholder); audit logging IS allowed and is a separate concern from operational logging.
Sources to mine when writing this¶
- Sentry configuration (
config/settings/*.py—before_sendscrubbing, sampling). - Logging configuration (
LOGGINGdict in settings). - Models with sensitive fields:
apps/patients/,apps/procedures/,apps/dentists/(contracts, revenue),apps/finance/. - Any export endpoints — check what they include. Grep for
HttpResponse(content_type='text/csv',excel,xlsx. sync_output*.logfiles at repo root — sample of what currently gets logged (any PII in there? red flag).
Starter hard rules to investigate¶
- Never log raw patient data (name, DOB, SSN, email, phone). Log a stable identifier (PK, external ID) instead.
logger.exception()is allowed but the exception message must not include PII — sanitize before raising.- DEBUG log level never in prod —
LOGGINGconfig must enforce. - Sentry
before_sendscrubs request bodies, query params, and form fields named in a denylist (email, password, ssn, …). - CSV / Excel exports redact PII unless the user has an explicit "PII export" permission. The CSV file path itself shouldn't be logged.
Decision points to settle¶
- PII categories list: define exactly which fields are PII vs sensitive-but-loggable. Pin to model fields explicitly so the audit can be mechanical.
- What redaction looks like: hash?
[redacted]? truncate? Different per field type. - Retention policy: how long do logs live?
sync_output*.logat the repo root suggests no rotation — risk. - Sentry scrubbing extent: is
send_default_pii=False(DRF default) set? Confirm and document.
Known deviations to look for during writing¶
logger.info(f"Importing patient {patient.first_name} {patient.last_name}")— exact PII leak.- Exception messages that interpolate user input ("Email %s already exists").
- CSV exports without redaction.
sync_output*.logat repo root — verify contents, rotate or.gitignore.
If found, file IMMEDIATELY as a backlog item with Area: security | Effort: ?.