HIPAA De-identification and Limited Data Sets
The two HIPAA Privacy Rule de-identification methods - Safe Harbor's 18-identifier checklist versus Expert Determination's statistical disclosure-risk certification - plus the contractual middle tier, the Limited Data Set (dates and geography retained, still PHI, under a signed Data Use Agreement). These are not the only lawful routes to using identifiable health data for research (authorization under 45 CFR 164.508, and IRB/Privacy Board waivers and other research permissions under 45 CFR 164.512(i), are others), but they are the routes that determine what fields an RWE analyst actually receives, and how each pathway's choices about dates, geography, and age reshape what can be built from them.
On this page
Before a real-world health dataset can be used for research, U.S. privacy law offers a few lawful paths. Sometimes a patient signs an authorization, or a review board approves a waiver, and the data stays fully identifiable. Often, though, a vendor strips or scrambles anything that could point back to a specific patient before an analyst ever sees the file - and there are two accepted ways to do that: delete a fixed list of 18 identifying details (names, exact addresses, and most dates among them), or have a qualified expert certify mathematically that whatever details remain are very unlikely to be traced back to anyone. A third, middle option keeps some of the most useful details, like full dates and city/state, but only under a signed contract that limits how the data can be used - this option, called a Limited Data Set, is still legally protected health information, not de-identified data. Whichever path is chosen changes what an analyst can actually calculate - stripped-down dates and zip codes make some research questions much harder to answer precisely.
Many RWE data assets - claims, EHR extracts, registries, linked mortality files - start life as protected health information (PHI) held by a HIPAA covered entity or business associate. HIPAA does not require every such file to be de-identified before an analyst can touch it: a covered entity may also use or disclose identifiable PHI for research under an individual's authorization, an IRB or Privacy Board waiver of authorization, or the other limited research permissions at 45 CFR 164.512(i). This entry covers the three routes that most often determine what an RWE analyst's fields actually look like once a dataset arrives: the two de-identification methods at 45 CFR 164.514(b) - Safe Harbor, a fixed checklist of 18 identifier categories to strip, and Expert Determination, a documented statistical certification that re-identification risk is very small - plus the contractual middle tier, the Limited Data Set (LDS). An LDS is not de-identification and is not one of the two de-identification methods; it remains PHI, shared under a signed Data Use Agreement (DUA) (45 CFR 164.514(e)) that keeps the file legally protected while permitting analytically valuable fields (full dates, city/state/ZIP) that de-identification would otherwise remove. Which of these routes a vendor or data partner chose is not a footnote - it determines whether the file an analyst receives can support day-level exposure windows, five-digit-ZIP area-level SDOH linkage, or elderly-cohort age stratification at all.
Safe Harbor (45 CFR 164.514(b)(2)) - the checklist
Eighteen identifier categories, applied to the individual and to the individual's relatives, employers, and household members, must be removed or generalized: names; geographic subdivisions smaller than a state, EXCEPT the initial three digits of ZIP may be kept if the combined population of all ZIPs sharing that 3-digit prefix is more than 20,000 - a population of 20,000 or fewer must be zeroed to "000" (the geographic ≤20,000 rule - the cutoff that gets zeroed is "20,000 or fewer," not merely "under 20,000"); all elements of dates directly related to an individual - birth, admission, discharge, death, and every service date - reduced to year only (the dates-to-year rule), except that for anyone whose age is over 89, ages and all date elements that would reveal such an age - including a birth year - must be aggregated into a single "90 or older" category (the age >89 rule: a compliant Safe Harbor file cannot retain a raw birth year for a patient over 89, only the "90+" label); plus phone/fax, email, SSN, medical record and health-plan numbers, account numbers, license/certificate numbers, vehicle and device identifiers, URLs, IP addresses, biometrics, full-face photographic images and any comparable images, and any other unique identifying number, characteristic, or code - except a re-identification code that itself meets all four separate conditions of 45 CFR 164.514(c) (it must not be derived from or related to information about the individual; it must not be otherwise capable of being translated to identify the individual; the covered entity must not use or disclose the code for any other purpose; and the covered entity must not disclose the mechanism for re-identification). A covered entity also may not have "actual knowledge" that the stripped file could still identify someone even after the checklist is satisfied - Safe Harbor is a floor, not a guarantee.
Expert Determination (45 CFR 164.514(b)(1)) - the statistics
A qualified expert applies generally accepted statistical or scientific methods to determine that the risk the information could be used, alone or combined with other reasonably available information, to identify the subject is very small, and documents the analysis and methods (the documentation, not the hashing, carries the legal claim - see `tokenization-privacy-preserving-record-linkage-rwe`). HIPAA does not mandate any single statistical method or a universal numeric threshold here - the expert chooses the methods and risk criteria appropriate to the specific dataset, the anticipated recipient, what other information is reasonably available to that recipient, and the release environment. k-anonymity (requiring every combination of retained quasi-identifiers - exact service date, five-digit ZIP, age, sex, a rare diagnosis - to match at least k similar records) is one commonly used diagnostic an expert may apply, not the definition of Expert Determination and not a value OCR requires. Whatever method is used, if the joint distribution of retained fields stays diffuse enough to satisfy the expert's chosen risk criteria, Expert Determination can justify keeping exact dates or ZIP5 that Safe Harbor would have destroyed; this is the pathway that lets tokenized-linkage vendors keep dates and geography granular enough for date-shifting or episode construction to remain meaningful at all.
Limited Data Set + Data Use Agreement (45 CFR 164.514(e)) - the pragmatic middle
An LDS excludes the 16 most direct identifiers (names, SSN, MRN, account/certificate numbers, full street address, and similar) but explicitly permits retaining full dates (birth, death, admission, discharge, service) and geography down to town, city, state, and five-digit ZIP. Because an LDS still contains dates and geography, it remains PHI - it is never "de-identified," and it is not one of the two de-identification methods - so it may only be disclosed under a signed DUA that establishes the permitted uses and recipients, restricts use to research, public health, or health care operations, prohibits the recipient from identifying or contacting the individuals, and prohibits use or further disclosure except as permitted by the DUA or otherwise required by law (any agent receiving the LDS must accept the same restrictions). Some claims and registry vendors that promise "full dates for episode construction" are shipping a Limited Data Set rather than a de-identified file, but others reach the same result through Expert Determination or an authorization/waiver route instead - the pathway varies by vendor and should be confirmed, not assumed.
Pros, cons, and trade-offs
None of "needs exact dates," "low-stakes," or "broad circulation" makes a pathway legally available on its own - the choice among these routes is a legal-and-operational decision made by whoever holds the PHI (is the holder HIPAA-regulated at all; can identifiable PHI be used here under an existing authorization or waiver; can every recipient realistically sign and honor a DUA; does the release need to be broad and unrestricted; what recipient-specific risk can a qualified expert actually justify), not a preference an analyst gets to express after the fact. With that caveat:
- Safe Harbor vs Expert Determination: Safe Harbor is cheap, auditable, and requires no statistician - a covered entity can check a list. The cost is that it is a rule, not a risk calculation: it strips information a study may genuinely need (exact fill dates, ZIP5) even when the combined re-identification risk would have been negligible, AND it can under-protect a sparsely populated rare-disease cohort where year-only dates plus ZIP3 still isolate a handful of people. A data holder more often reaches for Safe Harbor for broad, low-stakes secondary files where day-level precision is not analytically required, and for Expert Determination when the study needs exact dates or full geography and can justify the statistical documentation cost - but either choice still has to satisfy the holder's own risk assessment, not the analyst's preference.
- Expert Determination vs Limited Data Set: Expert Determination produces a file that is legally de-identified - no PHI status, no DUA needed downstream. An LDS is faster to stand up (no statistician, just a contract) and keeps dates/geography by rule rather than by risk calculation, but it remains PHI indefinitely and every recipient needs a DUA. Expert Determination tends to fit data that will circulate broadly, where ongoing PHI status would be operationally burdensome; an LDS tends to fit a small, known set of recipients who can each sign and honor a DUA, where the retained dates/ZIP5 are worth the continuing PHI obligation.
- vs treating any of these as "safe forever": The seductive error is to receive a de-identified or LDS file once and assume its privacy properties are fixed. Re-identification risk is a property of the combination of fields plus what else exists in the world (voter rolls, obituaries, social media) - it changes as external data grows. HIPAA does not impose a universal expiration date or mandatory reassessment interval on an Expert Determination, but because risk can shift, some experts issue time-limited certifications and re-examine future releases once a chosen certification period ends; a one-time sign-off with no plan for future releases is a practice gap, not a regulatory requirement, worth flagging when auditing a vendor's process.
When NOT to use - and when it is actively misleading
- Rare diagnosis + ZIP + age re-identification. A Safe-Harbor-cleared or even an Expert-Determination-cleared file can still be re-identifiable in combination: a rare cancer diagnosis, a ZIP3 covering a small town, and an age band together can isolate one or two people even when no single field looks identifying - the classic demonstration is Sweeney's estimate, from 1990 Census summary data, that 87% of the US population was likely unique on the combination of 5-digit ZIP, full date of birth, and sex, creating substantial linkage potential (population uniqueness, not verified re-identification of every person). Small-cell suppression on the joint distribution of quasi-identifiers, not per-field review, is what catches this.
- Date-shift breaking exposure-outcome ordering across linked sources. Many vendors go beyond Safe Harbor's year-only rule and instead apply a per-patient random date shift that preserves day-level intervals while hiding true calendar dates. Date shifting is a technical transformation, not a third HIPAA de-identification pathway on its own: a file that retains shifted month/day values still needs an independently valid legal basis for keeping day-level dates at all - typically Expert Determination (with the shift design itself part of the risk assessment) or an LDS+DUA with the shift layered on top for extra protection. Within that legal wrapper, the shift works within one shifted file - the interval between two shifted dates equals the true interval, because the same offset was added to both. It silently breaks across files that were shifted independently: if claims and EHR extracts for the same patient were each protected with their own, unlinked shift key, the apparent gap between a claims exposure and an EHR outcome is corrupted by the difference of the two files' signed shift offsets (s_EHR - s_claims) - see the worked example below, where the two shifts happen to have opposite signs, so that difference equals the sum of their magnitudes; with same-sign shifts, the distortion is instead the smaller difference between the two offsets. Do not assume a linked file's timing is trustworthy just because each source file's internal timing looks fine.
- Treating a linked file's privacy status as simply "the floor of its inputs." Linking narrows the population and can create combinations of fields that are more identifying than any single input was - it can raise re-identification risk above what any one source showed, and can invalidate a source file's earlier dataset-specific Expert Determination. Treat every linked output as a new disclosure-risk object: if any input source is still PHI, the linked file remains PHI unless it is separately and successfully de-identified; if the inputs were already de-identified separately, reassess whether the linkage itself creates new distinguishing combinations rather than assuming the join is automatically as safe as its most-protected input. Temporal precision for any one cross-source interval is limited by the least-precise date field that interval depends on (ZIP3 joined to ZIP5, or year-only dates joined to exact dates, both need to be reconciled and documented) - but that is a statement about that interval, not a claim that every field in the joined file inherits the coarsest input's granularity.
GDPR contrast, briefly
The EU's GDPR uses a single outcome-based test - anonymisation - asking whether any means reasonably likely to be used (by anyone, not just the recipient) could re-identify a person; there is no 18-item checklist and no regulator-blessed safe list of retained fields. A GDPR-anonymised dataset is the rough functional analog of a successfully de-identified HIPAA file (Safe Harbor or Expert Determination) - both exit their respective privacy regimes. Pseudonymisation under GDPR (replacing identifiers with a token or key) is roughly analogous to coding or tokenization, not to Expert Determination - the Article 29 Working Party opinion cited below is explicit that pseudonymisation is not anonymisation - and it remains personal data under GDPR as long as the information can still be attributed to a person using additional information held anywhere, unlike a properly HIPAA-de-identified file, which exits the Privacy Rule entirely. A HIPAA Safe Harbor or Expert Determination file is therefore not automatically GDPR-anonymous, and a GDPR-pseudonymised file is not automatically outside HIPAA's PHI definition; multi-region RWE data footprints must satisfy both regimes' tests separately.
Data-source operational depth
- Claims: Enrollment/eligibility and fill-date fields are the first casualties of Safe Harbor - year-only dates make day-level adherence (PDC) or episode construction impossible; push for Expert Determination or an LDS with a DUA whenever day-level exposure windows are required. A per-patient date-shift key can preserve day-level intervals in place of year truncation, but it does not replace the need for a valid legal basis (Expert Determination or LDS+DUA) for retaining day-level dates in the first place.
- EHR: Encounter and lab timestamps, plus free-text notes, carry the most residual identifying material - automated Safe Harbor scrubbing of unstructured notes is unreliable, so Expert Determination paired with NLP scrubbing is common specifically to preserve exact timestamps for lab/order/administration sequencing.
- Registry: Some disease and cancer registries distribute under an LDS (exact diagnosis date, full city/state/ZIP5) to keep survival and incidence analyses valid; others use Expert Determination or an authorization/waiver route instead, so confirm the pathway rather than assuming LDS. Because registries skew toward rare conditions, the ZIP+age+diagnosis re-identification risk is high regardless of pathway and needs small-cell suppression on top of whatever legal protection applies - HIPAA itself does not require IRB or Privacy Board approval for an LDS disclosed under a compliant DUA, though separate Common Rule, FDA, or institutional review may still apply.
- Linked: Document each input source's de-identification pathway, date-shift key (if any), and geographic truncation level before joining, and treat the linked output as a new disclosure-risk object rather than assuming its privacy tier is simply the floor of its inputs - linkage can create combinations more identifying than any single source and can require reassessing an earlier source-level Expert Determination. Temporal precision for a given cross-source interval is limited by the least precise date field that interval depends on.
Decision diagram
flowchart TD
Src[Source PHI file<br/>dates, geography, identifiers] --> Choice{"Which HIPAA de-id<br/>method or LDS?<br/>(authorization/waiver<br/>routes not shown)"}
Choice -- Safe Harbor --> SH[Strip 18 identifiers<br/>dates -> year only<br/>ZIP3 pop ≤20k -> 000<br/>age >89 -> 90+]
Choice -- Expert Determination --> ED[Expert certifies<br/>re-identification risk<br/>is very small]
Choice -- Limited Data Set --> LDS[Keep full dates + city/<br/>state/ZIP5<br/>still PHI]
SH --> DeID[De-identified<br/>no DUA needed]
ED --> DeID
LDS --> DUA{Signed Data Use<br/>Agreement in place?}
DUA -- No --> Blocked[Disclosure not permitted]
DUA -- Yes --> Usable[Usable under DUA terms<br/>still PHI]
DeID --> Risk[Check joint quasi-identifier<br/>cells: rare diagnosis + ZIP<br/>+ age can still re-identify]
Usable --> RiskWorked example
Scenario
A patient's claims record and EHR record are each made available for research by a different vendor - each vendor has an independent, valid legal basis (Expert Determination or an LDS+DUA) for retaining day-level dates, and layers a per-patient random date shift on top as extra protection against exposing true calendar dates. Date shifting on its own is a technical transformation, not a HIPAA pathway - it does not substitute for that legal basis. Because the two vendors do not share a shift key, the shifts are different sizes for the same patient. We want to see whether the gap between a claims-recorded prescription fill and an EHR-recorded lab result still looks right after both files are shifted and linked.
Dataset
True dates versus displayed (shifted) dates for the same patient across two independently date-shifted files, each retained under its own valid legal basis (Expert Determination or LDS+DUA).
| source_file | event | true_date | shift_applied_days | displayed_date |
|---|---|---|---|---|
| claims | prescription fill | 2022-03-01 | -47 | 2022-01-13 |
| claims | follow-up claim | 2022-04-01 | -47 | 2022-02-13 |
| ehr | lab result | 2022-03-15 | 30 | 2022-04-14 |
Steps
Result
Within one shifted file, date-shift de-identification preserves exact intervals (31 days matches 31 days). Once two independently shifted files are linked, the apparent exposure-to-outcome gap is corrupted from a true 14 days to a displayed 91 days - a 77-day artifact from the mismatched shift keys - which is why linked RWE studies need either a single harmonized shift key across all sources or exact dates preserved under a Limited Data Set.
Trade-offs
Runnable example
Two functions an analyst actually needs when receiving a claims-style extract. `apply_safe_harbor_dates_age_zip3` mechanically applies ONLY the dates-to-year, age >89, and geographic "20,000 or fewer" rules -- it is not a complete Safe Harbor implementation (the other 15 identifier categories are out of scope for...
import pandas as pd
def apply_safe_harbor_dates_age_zip3(df: pd.DataFrame, zip3_small_pop: set[str]) -> tuple[pd.DataFrame, pd.DataFrame]:
"""Apply a SUBSET of the Safe Harbor rules (45 CFR 164.514(b)(2)): dates-to-year, the age >89
aggregation, and the geographic "20,000 or fewer" ZIP3 rule. Does NOT by itself produce a
Safe-Harbor-compliant file -- the other 15 identifier categories (names, SSN, MRN, phone/email,
device/vehicle IDs, biometrics, free-text notes, etc.) must also be removed. person_id is
replaced with a study_id assigned per distinct person (not per row), so a patient's multiple
rows keep one study_id and within-person linkage survives; the person_id-to-study_id mapping is
returned separately and must be kept apart from, and never disclosed with, the de-identified
file. Returns (deidentified_df, person_id_crosswalk)."""
out = df.copy()
over_89 = out["age"] >= 90
birth_year = pd.to_datetime(out["birth_date"]).dt.year
service_year = pd.to_datetime(out["service_date"]).dt.year
# For anyone over 89, no date element that would reveal the age -- including birth year --
# may survive; only the "90 or older" label is retained.
out["birth_year_safe_harbor"] = birth_year.mask(over_89)
out["service_year"] = service_year
out["age_safe_harbor"] = out["age"].astype(object).mask(over_89, "90+")
# ZIP3 population "20,000 or fewer" (not just "under 20,000") is zeroed to "000".
out["zip3_safe_harbor"] = out["zip3"].apply(
lambda z: "000" if z in zip3_small_pop else z
)
# One study_id per distinct PERSON, not per row -- pd.factorize assigns the same code to
# every row sharing a person_id, so a patient's multiple claims/encounters keep a single
# study_id and the within-person episode structure survives.
out["study_id"] = pd.factorize(out["person_id"])[0] + 1
# Crosswalk captured before person_id is dropped; kept only for internal use and never
# disclosed alongside the de-identified file.
person_id_crosswalk = out[["person_id", "study_id"]].drop_duplicates().reset_index(drop=True)
# Drop every disallowed source field so it cannot silently survive alongside the
# generalized value.
out = out.drop(columns=["person_id", "birth_date", "service_date", "age", "zip3"])
return out, person_id_crosswalk
def flag_small_cells(df: pd.DataFrame, quasi_id_cols: list[str], k_min: int = 5) -> pd.DataFrame:
"""Illustrative joint disclosure-risk screen (one possible Expert Determination diagnostic,
not a required method): counts DISTINCT PEOPLE, not rows, sharing each combination of the
given quasi-identifier columns, and flags any combination with fewer than k_min distinct
people. Run on data the analyst is already entitled to see (requires person_id) -- this is
not itself a compliant output for external disclosure. dropna=False keeps groups with missing
quasi-identifiers instead of silently discarding them, since a missing field is not evidence
of low risk."""
counts = (
df.groupby(quasi_id_cols, dropna=False)["person_id"]
.nunique()
.reset_index(name="distinct_people")
)
counts["needs_review"] = counts["distinct_people"] < k_min
return countsSame two checks in data.table. `apply_safe_harbor_dates_age_zip3` applies ONLY the dates-to-year, age >89, and geographic "20,000 or fewer" ZIP3 rules -- not a complete Safe Harbor implementation -- drops every raw source field it generalizes (including person_id, replaced with a study_id assigned per distinct...
library(data.table)
apply_safe_harbor_dates_age_zip3 <- function(dt, zip3_small_pop) {
# Applies a SUBSET of the Safe Harbor rules (45 CFR 164.514(b)(2)): dates-to-year, the age >89
# aggregation, and the geographic "20,000 or fewer" ZIP3 rule. Does NOT by itself produce a
# Safe-Harbor-compliant file -- the other 15 identifier categories must also be removed.
# person_id is replaced with a study_id assigned per distinct person (not per row), so a
# patient's multiple rows keep one study_id and within-person linkage survives; the
# person_id-to-study_id crosswalk is returned separately and must be kept apart from, and never
# disclosed with, the de-identified data. Returns list(data = ..., crosswalk = ...).
setDT(dt)
over_89 <- dt$age >= 90
# For anyone over 89, no date element that would reveal the age -- including birth year -- may
# survive; only the "90 or older" label is retained.
dt[, birth_year_safe_harbor := fifelse(over_89, NA_integer_, year(as.IDate(birth_date)))]
dt[, service_year := year(as.IDate(service_date))]
dt[, age_safe_harbor := fifelse(over_89, "90+", as.character(age))]
# ZIP3 population "20,000 or fewer" (not just "under 20,000") is zeroed to "000".
dt[, zip3_safe_harbor := fifelse(zip3 %in% zip3_small_pop, "000", zip3)]
# One study_id per distinct PERSON, not per row -- .GRP assigns the same group index to every
# row sharing a person_id, keeping a patient's multiple claims/encounters under one study_id so
# within-person episode construction survives.
dt[, study_id := .GRP, by = person_id]
# Crosswalk captured before person_id is dropped; kept only for internal use and never
# disclosed alongside the de-identified file.
person_id_crosswalk <- unique(dt[, .(person_id, study_id)])
# Drop every disallowed source field so it cannot silently survive alongside the
# generalized value.
dt[, `:=`(person_id = NULL, birth_date = NULL, service_date = NULL, age = NULL, zip3 = NULL)]
list(data = dt[], crosswalk = person_id_crosswalk)
}
flag_small_cells <- function(dt, quasi_id_cols, k_min = 5) {
# Illustrative joint disclosure-risk screen (one possible Expert Determination diagnostic, not
# a required method): counts DISTINCT PEOPLE, not rows, per combination of quasi_id_cols, and
# flags any combination with fewer than k_min distinct people. Requires person_id and is meant
# for internal risk review, not as a compliant output for external disclosure.
setDT(dt)
counts <- dt[, .(distinct_people = uniqueN(person_id)), by = quasi_id_cols]
counts[, needs_review := distinct_people < k_min]
counts
}Citations
- [1]45 CFR 164.514 - Other requirements relating to uses and disclosures of protected health information. Code of Federal Regulations, Title 45, Volume 2 (2023 annual edition). U.S. Government Publishing Office / Department of Health and Human Services.
- [2]Benitez K, Malin B. Evaluating re-identification risks with respect to the HIPAA privacy rule. Journal of the American Medical Informatics Association. 2010;17(2):169-177.
- [3]El Emam K, Jonker E, Arbuckle L, Malin B. A systematic review of re-identification attacks on health data. PLoS ONE. 2011;6(12):e28071.
- [4]Article 29 Data Protection Working Party. Opinion 05/2014 on Anonymisation Techniques. WP216. European Commission. 2014.
- [5]Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 (General Data Protection Regulation), Recital 26 and Article 4(5). Official Journal of the European Union.