Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

usdpr-phi-scrubber

License: Apache 2.0 Python 3.9+

HIPAA-compliant PHI detection + redaction for outbound patient messaging.

Catches procedure codes (CDT/CPT), tooth numbers, diagnosis terms, chart references, and insurance IDs before they leave your server. Extracted from production use at usdpr. (US Dental Patient Recovery).

Why

HIPAA's Privacy Rule permits SMS/email to patients with proper consent — as long as the message body doesn't carry clinical detail. In practice, every dental-tech team I've talked to implements this as "operator policy: don't put PHI in messages." Policies don't stop 2am typos. Enforcement has to be in code, at the query layer.

This library wraps your send function with a decorator that rejects any message containing PHI patterns. @scrubbed.

Install

pip install usdpr-phi-scrubber

Use

from usdpr_phi_scrubber import scrubbed, PHIViolation

@scrubbed
def send_patient_sms(patient_id: str, body: str) -> None:
    twilio_client.messages.create(to=patient_id, body=body, from_=OUR_NUMBER)

send_patient_sms("p_123", "Time for your cleaning tomorrow at 10am")      # OK
send_patient_sms("p_123", "Your root canal on tooth #14 is ready")         # raises PHIViolation
send_patient_sms("p_123", "Crown prep for D2740 on Tuesday")               # raises PHIViolation

What it catches

Category Example Regex source
CDT codes D0150, D2740, D7210 ADA 2024 Code on Dental Procedures
CPT codes 99213, 41899 AMA 2024 CPT
ICD-10 K02.1, M79.3 CDC ICD-10-CM 2024
Tooth numbers tooth #14, #3-5, UR1 Universal + Palmer numbering
Diagnosis terms root canal, crown prep, extraction, periodontitis HHS phi gazetteer + clinical dict
Insurance IDs member ID 1234567, group 5678 Common EHR exports
Chart references chart #12345, MRN 67890 PMS export patterns

Performance

Single-pass regex + string match. ~0.4ms per message on M1 (benchmarked). Zero allocation overhead; no deps beyond stdlib.

Custom patterns

from usdpr_phi_scrubber import Scrubber

scrubber = Scrubber()
scrubber.add_pattern(r"\bclaim-\d{6}\b", kind="claim_id")
scrubber.scrub("Your claim-123456 is approved")  # raises PHIViolation

Audit trail

Every violation carries the pattern matched + the offending substring:

try:
    send_patient_sms("p_123", "Tooth #14 extraction scheduled")
except PHIViolation as e:
    log.error("phi_blocked", pattern=e.pattern, match=e.match_text, kind=e.kind)

Testing

pip install -e .[dev]
pytest

Passes 187 tests covering every pattern family + 40 edge cases.

What this isn't

  • A HIPAA compliance program (you still need BAAs, encryption, audit logs, access controls)
  • A medical NER system (use ScispaCy or MedSpaCy for that)
  • A substitute for training (operators still need to know what they can and can't say)

License

Apache-2.0. Patent-grant clauses apply. Built and maintained by Colin Smith at usdpr. — a patient reactivation SaaS for US dental practices.

If you're running a dental practice and fighting the reactivation leak: run the ROI calculator or read The State of Dental Patient Reactivation 2026.

About

HIPAA-compliant PHI scrubber — blocks CDT/CPT/ICD-10 codes, tooth numbers, diagnosis terms before they leave your server. Extracted from usdpr. (US Dental Patient Recovery).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages