Identity Resolution for Healthcare: HIPAA-Compliant Patient Matching
Published February 2026 · 14 min read
Patient matching is one of the hardest identity resolution problems. The data is messy (handwritten intake forms, inconsistent formatting), the stakes are high (wrong match = wrong treatment), and the regulatory environment is strict (HIPAA, state privacy laws, 21st Century Cures Act).
Despite this, the US healthcare system still lacks a universal patient identifier. The result: an estimated 8-12% of patient records are duplicates within a single health system, and up to 20% across systems (AHIMA, 2023). These duplicates cause medication errors, repeated tests, billing mistakes, and fragmented care.
This post covers how to implement identity resolution for patient matching in a way that's both accurate and HIPAA-compliant.
Why Patient Matching Is Hard
No Universal Identifier
In 1998, Congress prohibited HHS from funding a national patient identifier. 27 years later, healthcare systems still rely on matching demographic data — name, date of birth, address, SSN (partial) — to link records across systems.
Data Quality Is Terrible
| Problem | Frequency | Example |
|---|---|---|
| Name misspellings | 5-10% of records | "Johanson" vs "Johansson" |
| Nickname variations | 15-20% | "William" vs "Bill" vs "Will" |
| Transposed digits (DOB) | 2-5% | 03/15/1987 vs 03/51/1987 |
| Address changes | 10-15% per year | Patient moved, old address on file |
| Missing fields | 5-30% | No SSN, no phone, no email |
| Cultural name formats | Variable | Family name first vs last, middle names |
The Cost of Getting It Wrong
| Error Type | Impact |
|---|---|
| False positive (merging different patients) | Wrong medication, wrong diagnosis, wrong treatment — potentially fatal |
| False negative (failing to link same patient) | Repeated tests ($$$), fragmented medical history, missed drug interactions |
In healthcare, false positives are generally more dangerous than false negatives. A conservative matching strategy with human review is preferred over aggressive automated merging.
HIPAA Compliance Requirements
Any system that processes Protected Health Information (PHI) must comply with HIPAA's Privacy Rule and Security Rule.
What Counts as PHI
All 18 HIPAA identifiers are relevant to patient matching:
| Identifier | Used in Matching? |
|---|---|
| Name | Yes (primary) |
| Date of birth | Yes (primary) |
| Address | Yes (secondary) |
| Phone number | Sometimes |
| Sometimes | |
| SSN | Sometimes (last 4) |
| Medical record number | Yes (within system) |
| Health plan ID | Sometimes |
Compliance Requirements for Identity Resolution
| Requirement | What It Means for Matching |
|---|---|
| Minimum necessary | Only access PHI fields needed for matching — don't pull diagnosis, procedures, or clinical notes into the matching engine |
| Access controls | Role-based access to matching results; audit who viewed what |
| Audit trail | Log every match decision with reason codes |
| Encryption at rest | All PHI stored encrypted (AES-256) |
| Encryption in transit | All PHI transmitted over TLS 1.2+ |
| Business Associate Agreement | If using a third-party matching service, a BAA is required |
| Data retention | PHI must be retained per policy and disposed of securely |
| Breach notification | If PHI is exposed, notify within 60 days |
PII Masking in Matching Pipelines
A best practice is to separate identifiable data from matching mechanics:
Input: Full patient records with PHI
↓
Step 1: Extract matching fields only (name, DOB, address, MRN)
Step 2: Run matching on extracted fields
Step 3: Output match decisions (cluster IDs, confidence scores)
↓
Output: Match decisions reference record IDs only — no PHI in outputThe matching engine never needs to see diagnosis codes, lab results, or clinical notes.
Patient Matching Architecture
The Standard Pipeline
EHR A ─┐
EHR B ─┤→ Normalize → Block → Match → Cluster → Review → MPI
Claims ─┤
Labs ─┘MPI (Master Patient Index): The golden record database that maps all known identifiers to a canonical patient ID.
Matching Strategy for Patient Data
Tier 1: Deterministic (high confidence)
| Rule | Fields | Confidence |
|---|---|---|
| MRN match | Same MRN within a system | 0.99 |
| SSN + DOB | Last 4 SSN + exact DOB | 0.98 |
| Email + DOB | Exact email + exact DOB | 0.97 |
Tier 2: Fuzzy (medium confidence)
| Rule | Fields | Algorithm | Threshold |
|---|---|---|---|
| Name + DOB | First + Last name + DOB | Jaro-Winkler + exact | Name JW > 0.92 |
| Name + Address | First + Last + Street + City | Jaro-Winkler | All JW > 0.88 |
| Name + Phone | First + Last + Phone | Jaro-Winkler + exact | Name JW > 0.90 |
Tier 3: Review queue (low confidence)
| Rule | Fields | Action |
|---|---|---|
| Name only (common) | Last name + first initial | Send to human review |
| DOB + City only | Exact DOB + exact city | Send to human review |
Blocking Strategies for Patient Data
| Pass | Blocking Key | Purpose |
|---|---|---|
| 1 | Last 4 SSN | Strong identifier when available |
| 2 | DOB + first 3 chars of last name | Catches most matches |
| 3 | Phone number (normalized) | Catches records with phone |
| 4 | Soundex(last name) + birth year | Catches spelling variations |
Healthcare-Specific Normalization
Beyond standard normalization, patient matching requires:
| Field | Normalization | Example |
|---|---|---|
| Name prefixes | Remove "Dr.", "Mr.", "Mrs." | "Dr. Robert Smith" → "robert smith" |
| Name suffixes | Remove "Jr.", "Sr.", "III" | "James Wilson Jr." → "james wilson" |
| Maiden names | Handle name changes | Store both current and previous names |
| Hyphenated names | Split and match components | "Garcia-Lopez" matches "Garcia" or "Lopez" |
| DOB | Standardize format | "March 15, 1987" → "1987-03-15" |
| Address | USPS standardization | "123 N. Main St. Apt 4B" → "123 N MAIN ST APT 4B" |
| Phone | Digits only, no country code | "(555) 123-4567" → "5551234567" |
Implementation with Kanoniv
Kanoniv's declarative approach works well for healthcare because the matching logic is explicit, auditable, and version-controlled — all properties that compliance teams value.
# patient-matching-spec.yaml
entity:
name: patient
sources:
- name: ehr_a
adapter: csv
location: ehr_a_patients.csv
primary_key: mrn
- name: ehr_b
adapter: csv
location: ehr_b_patients.csv
primary_key: mrn
- name: claims
adapter: csv
location: claims_members.csv
primary_key: member_id
rules:
# Tier 1: Deterministic
- name: ssn_dob
type: composite
children:
- type: exact
field: ssn_last4
- type: exact
field: date_of_birth
- name: email_dob
type: composite
children:
- type: exact
field: email
- type: exact
field: date_of_birth
# Tier 2: Fuzzy
- name: name_dob
type: composite
children:
- type: jaro_winkler
field: first_name
threshold: 0.92
- type: jaro_winkler
field: last_name
threshold: 0.92
- type: exact
field: date_of_birth
- name: name_address
type: composite
children:
- type: jaro_winkler
field: first_name
threshold: 0.90
- type: jaro_winkler
field: last_name
threshold: 0.90
- type: jaro_winkler
field: address
threshold: 0.85
- type: exact
field: city
survivorship:
strategy: source_priority
priority: [ehr_a, ehr_b, claims]
decision:
thresholds:
match: 0.90
review: 0.70from kanoniv import Spec, Source, reconcile, validate
spec = Spec.from_file("patient-matching-spec.yaml")
validate(spec).raise_on_error()
sources = [
Source.from_csv("ehr_a", "ehr_a_patients.csv"),
Source.from_csv("ehr_b", "ehr_b_patients.csv"),
Source.from_csv("claims", "claims_members.csv"),
]
result = reconcile(sources, spec)
print(f"Input records: {result.total_input_records}")
print(f"Unique patients (golden records): {len(result.golden_records)}")
print(f"Merge rate: {result.merge_rate:.1%}")
print(f"Pairs for review: {len(result.review_pairs)}")HIPAA-Specific Configuration
Kanoniv Cloud includes features designed for healthcare compliance:
| Feature | What It Does |
|---|---|
| PII masking | Masks PHI in logs and API responses |
| Audit logs | Immutable record of every match decision with reason codes |
| Data retention | Automatic purging of PHI after configurable retention period |
| BYOK encryption | Bring your own encryption keys for data at rest |
| Multi-tenant isolation | Row-level security prevents cross-organization data access |
Measuring Patient Matching Quality
Industry Benchmarks
| Metric | Target (within system) | Target (across systems) |
|---|---|---|
| Precision | > 99% | > 97% |
| Recall | > 95% | > 90% |
| F1 | > 97% | > 93% |
| Duplicate rate (post-dedup) | < 1% | < 3% |
The Precision-Recall Trade-off in Healthcare
Healthcare strongly favors precision over recall:
- High precision means fewer false merges → fewer patient safety incidents
- Lower recall means some duplicates remain → extra tests, fragmented history (costly but not dangerous)
Set your match threshold conservatively (0.90+) and use the review queue for borderline cases. A human reviewer catching 100 uncertain pairs per day is vastly preferable to an automated system merging the wrong patients.
Common Pitfalls
1. Matching on Name Alone
Names are not unique identifiers. "Maria Garcia" appears thousands of times in any large health system. Never match on name alone — always combine with DOB, address, or another field.
2. Ignoring Cultural Name Variations
Name matching rules built for English names fail on names from other cultures:
- Hispanic names: Two last names (paternal + maternal). "Maria Garcia Lopez" might be filed as "Garcia" or "Lopez."
- East Asian names: Family name first. "Kim Min-jun" might be filed as "Min-jun Kim" or "Kim, Min-jun."
- Arabic names: "Al-" prefix variations. "Al-Rahman" vs "Alrahman" vs "Rahman."
3. Over-Relying on SSN
SSN is not always reliable:
- Newborns don't have SSNs
- Undocumented patients may not provide SSNs
- SSN fraud/sharing exists
- Some patients provide incorrect SSNs intentionally
Use SSN as a strong signal, but never as the sole matching criterion.
4. Not Handling Twins
Twins share DOB, address, last name, and often similar first names. Without careful rules, twins get merged into one patient. Always require first name similarity above a high threshold when DOB + last name + address match.
Regulatory Landscape
| Regulation | Relevance |
|---|---|
| HIPAA | All patient matching systems must comply |
| 21st Century Cures Act | Prohibits information blocking; matching helps interoperability |
| TEFCA | Trusted Exchange Framework requires patient matching for nationwide health data exchange |
| State laws | Some states have stricter requirements (e.g., California CCPA applies to health data not covered by HIPAA) |
| ONC Patient Matching | Office of the National Coordinator has published best practices for patient demographic data quality |
Summary
Patient matching is a specialized form of identity resolution with higher stakes and stricter compliance requirements. The key principles:
- Favor precision over recall — false merges are more dangerous than missed matches
- Use tiered matching — deterministic rules first, fuzzy second, human review third
- Keep PHI out of the matching engine — extract only the fields needed for comparison
- Audit everything — every match decision needs a traceable reason code
- Version-control your rules — compliance teams need to review and approve matching logic changes
- Test with realistic data — synthetic data with name variations, missing fields, and cultural diversity
Kanoniv's declarative, auditable approach aligns well with these requirements. The YAML spec serves as both matching logic and compliance documentation.
