Run expert-determination-style quasi-identifier risk scoring (k-anonymity, l-diversity) plus OpenMed's empirical re-identification attack on a de-identified dataset, then document residual risk in a defensible memo. Use when the user needs HIPAA Expert Determination (45 CFR 164.514(b)(1)) support, asks whether a dataset is safe to release, worries about singling-out via age/ZIP/dates, or wants a statistical "very small risk" determination. Covers identifying quasi-identifiers, computing k-anonymity / l-diversity, running openmed.eval.attacks.reid (run_reid_attack / run_reid_benchmark) as the adversarial attack, and writing the risk memo. Pairs after deidentifying-clinical-text and auditing-deid-leakage.
78
98%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Removing direct identifiers is not enough. A record stripped of name, SSN, and MRN can still be singled out by a combination of quasi-identifiers — age, ZIP/region, admission date, sex, rare diagnosis. The HIPAA Expert Determination pathway (45 CFR 164.514(b)(1)) requires a qualified person to apply statistical methods and document that the risk of re-identification is "very small." This skill produces that evidence: quasi-identifier risk metrics (k-anonymity, l-diversity) plus OpenMed's empirical re-identification attack, written up as a residual-risk memo.
auditing-deid-leakage (no leaks) and
you must decide whether the dataset is releasable.from openmed.eval.attacks.reid import run_reid_attack, run_reid_benchmark
# Synthetic de-identified records; each row is the released, de-id'd data.
deidentified = [
{"record_id": "r1", "text": "[NAME], 47F, ZIP 021xx, admitted 2024-03."},
{"record_id": "r2", "text": "[NAME], 47F, ZIP 021xx, admitted 2024-03."},
{"record_id": "r3", "text": "[NAME], 88M, ZIP 597xx, admitted 2024-03."}, # singleton
]
# Auxiliary = what an attacker might already hold (e.g. a voter list).
auxiliary = [{"record_id": "v9", "text": "88M ZIP 597xx"}]
result = run_reid_attack(
fixtures=[], # bring your own records below
deidentified_records=deidentified,
auxiliary_records=auxiliary,
)
metric = result.to_metric()
print(metric["aux_linkage_rate"], # empirical linkage success
metric["k_min"], # smallest equivalence-class size
metric["singleton_count"], # k=1 records (uniquely identifiable)
metric["quasi_identifier_count"])k_min is the population k-anonymity floor across the dataset; a k_min of 1
means at least one record is unique on its quasi-identifiers and is the highest
re-identification risk. aux_linkage_rate is the empirical attack: how often the
adversary's auxiliary data successfully links back to a released record.
To run against the bundled golden suite and emit a leaderboard-style report:
report = run_reid_benchmark(
suite="golden",
deidentified_records=deidentified,
auxiliary_records=auxiliary,
output_markdown="reid_risk.md",
)auditing-deid-leakage); QIs are what's left to worry about.run_reid_attack returns k_min and
the list of singleton_records (k=1). A common Expert Determination target is
k ≥ a documented threshold (e.g. k ≥ 5 or k ≥ 11) for every record.run_reid_attack / run_reid_benchmark model an
adversary with auxiliary_records and measure actual linkage success
(aux_linkage_rate), residual leakage (leakage_rate), surrogate-consistency
leaks, and date-shift-inversion leaks. Structural metrics bound risk;
the attack demonstrates it.k_min and linkage rate meet your
documented threshold.k_min, l-diversity, the attack's aux_linkage_rate, the assumptions about
attacker capability, and the conclusion that residual risk is "very small."
Cite the metrics — never paste raw records into the memo.auditing-deid-leakage: only score QI risk once direct-identifier
leakage is zero. A leak short-circuits the whole determination.from openmed.eval.attacks.reid import run_reid_attack, run_reid_benchmark, generate_reid_leaderboard. The attack delegates to
openmed.risk.risk_report for k-anonymity / linkage internals.evaluating-with-leakage-gates: register reid_leakage_rate as a gate
in the eval harness so re-identification risk regressions fail CI.pseudonymizing-for-gdpr: pseudonymized output is still re-identifiable
via QIs — run this attack before claiming a dataset is low-risk or anonymized.auxiliary_records you model. Document the assumed attacker
(motivated insider vs. public voter list) — different aux sets, different risk.singleton_count and singleton_records first.date_shift_inversion_rate.
Watch it when de-id used method="shift_dates".80da98c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.