TIDE 2.0: an open, model-agnostic engine for keyed de-identification of clinical notes
Organizations: Technology & Digital Solutions, Stanford Medicine, Stanford, CA, USA
Abstract
Clinical notes capture most of what is documented about a patient's care, but they cannot be used for research until protected health information (PHI) is removed. De-identification is often treated as a detection problem. Detection alone is not sufficient: redaction strips clinical content along with identifiers, date blanking destroys the temporal intervals needed for longitudinal analysis, and assigning a fresh random surrogate at each occurrence breaks links between a patient's notes. We present TIDE 2.0, an MIT-licensed engine with two separable stages: an interchangeable recognizer and a keyed anonymizer. Both run on hardware the institution owns. Surrogates are generated cryptographically with no stored linkage table. Dates shift by a per-patient, interval-preserving offset; each value receives the same surrogate across all occurrences under a given key; and a release produced under a new key cannot be linked to earlier releases. We also release TIDE2-Sentry, a recognizer distilled from a large language model. On two gold-annotated corpora from two institutions, the default configuration reached span-level recall of 0.88 in-domain and 0.77 on the second institution's corpus, at precision 0.88 and 0.87. We report recall and precision per category alongside these aggregates. The engine is open source, and the recognizer is available under a gated research-use agreement, so institutions can run, inspect and extend both within their own environments.
Figures & tables
| SHIELD | i2b2 2014 | |||||||
| micro | macro | micro | macro | |||||
| Recognizer | P | R | P | R | P | R | P | R |
| TIDE2 regex | 0.97 | 0.42 | 0.52 | 0.39 | 0.98 | 0.39 | 0.48 | 0.27 |
| tide1 | 0.48 | 0.39 | 0.41 | 0.38 | – | – | – | – |
| AIMI v1 | 0.67 | 0.72 | 0.45 | 0.55 | 0.73 | 0.67 | 0.44 | 0.49 |
| AIMI v2 | 0.63 | 0.70 | 0.43 | 0.53 | 0.70 | 0.65 | 0.43 | 0.47 |
| Property | Construction | Result | |
|---|---|---|---|
| Determinism (same key) | keyed HMAC / FF3 / selection | 2,000 | 100.0% identical |
| Remapping (rotated key) | new key remaps surrogate | 2,000 | 100.0% remapped |
| Cross-note consistency | same value same surrogate | 1,000 | 100.0% linked |
| Interval preservation | per-patient date shift | 2,000 | 100.0% exact day-delta |
| ID collisions, 8 digits | FF3, no padding | 2,000 | 0.00% (2,000 distinct) |
| ID collisions, 3–5 digits | FF3, padded, truncated | 111,000 | 34.8%–36.6% |
| SHIELD | Longest notes | |||
| Stage | L4 path | CPU-only | L4 path | CPU-only |
| Transformer | 4,063 | 200 | 10,104 | 358 |
| Recognizer | 6,127 | 6,127 | 27,591 | 27,591 |
| Anonymizer | 4,421 | 4,421 | 21,547 | 21,547 |
| End-to-end | 1,573 | 186 | 5,506 | 348 |
Appendix figures & tables15 assets
Supplementary material from the paper’s appendix.
Appendix
| Model | AGE | DATE | DOCTOR | HOSP | ID | LOC | PATIENT | PHONE | WEB |
|---|---|---|---|---|---|---|---|---|---|
| Recall | |||||||||
| TIDE2 regex | 0.00 | 0.92 | 0.00 | 0.00 | 0.56 | 0.38 | 0.00 | 0.80 | 0.82 |
| AIMI v1 | – | 0.95 | 0.46 | 0.90 | 0.95 | – | 0.78 | 0.92 | – |
| AIMI v1 + regex | 0.00 | 0.95 | 0.46 | 0.90 | 0.95 | 0.36 | 0.78 | 0.94 | 0.60 |
| AIMI v2 | – | 0.95 | 0.42 | 0.89 | 0.95 | – | 0.71 | 0.81 | – |
| AIMI v2 + regex | 0.00 | 0.96 | 0.42 | 0.88 | 0.95 | 0.37 | 0.71 | 0.86 | 0.56 |
| Model | AGE | DATE | DOCTOR | HOSP | ID | LOC | PATIENT | PHONE | WEB |
|---|---|---|---|---|---|---|---|---|---|
| Recall | |||||||||
| TIDE2 regex | 0.00 | 0.75 | 0.00 | 0.00 | 0.44 | 0.13 | 0.00 | 0.38 | 0.71 |
| AIMI v1 | – | 0.94 | 0.25 | 0.87 | 0.81 | – | 0.56 | 0.94 | – |
| AIMI v1 + regex | 0.00 | 0.95 | 0.25 | 0.87 | 0.81 | 0.08 | 0.56 | 0.93 | 0.57 |
| AIMI v2 | – | 0.94 | 0.23 | 0.84 | 0.80 | – | 0.54 | 0.88 | – |
| AIMI v2 + regex | 0.00 | 0.95 | 0.23 | 0.84 | 0.80 | 0.09 | 0.54 | 0.88 | 0.29 |
| Gemini 2.5 Flash | TIDE2-Sentry | ||||||
|---|---|---|---|---|---|---|---|
| Category | P [95% CI] | R [95% CI] | P [95% CI] | R [95% CI] | R | ||
| AGE | 0.85 [0.79-0.90] | 0.90 [0.87-0.93] | 0.71 [0.65-0.77] | 0.78 [0.74-0.83] | -0.12 | <0.0005 | <0.005 |
| DATE | 0.99 [0.98-0.99] | 0.98 [0.98-0.99] | 0.97 [0.96-0.97] | 0.94 [0.93-0.95] | -0.04 | <0.0005 | <0.005 |
| DOCTOR | 0.95 [0.94-0.97] | 0.96 [0.96-0.97] | 0.93 [0.92-0.94] | 0.90 [0.88-0.92] | -0.06 | <0.0005 | <0.005 |
| HOSPITAL | 0.67 [0.64-0.71] | 0.88 [0.85-0.90] | 0.61 [0.57-0.65] | 0.79 [0.75-0.82] | -0.09 | <0.0005 | <0.005 |
| ID | 0.91 [0.87-0.94] | 0.95 [0.92-0.97] | 0.92 [0.89-0.94] | 0.90 [0.86-0.94] | -0.05 | =0.0050 | 0.045 |
| Category | Metric | TIDE2 regex | AIMI v1 | AIMI v2 | TIDE2-Sentry | TIDE2-Sentry+regex |
|---|---|---|---|---|---|---|
| SHIELD | ||||||
| AGE | Precision | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.71 [0.65-0.77] | 0.71 [0.65-0.77] |
| AGE | Recall | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.78 [0.74-0.83] | 0.78 [0.74-0.83] |
| DATE | Precision | 0.98 [0.98-0.99] | 0.94 [0.93-0.95] | 0.95 [0.94-0.96] | 0.97 [0.96-0.97] | 0.95 [0.94-0.96] |
| DATE | Recall | 0.92 [0.91-0.94] | 0.95 [0.94-0.96] | 0.95 [0.94-0.96] | 0.94 [0.93-0.95] | 0.95 [0.93-0.96] |
| DOCTOR | Precision | 0.00 [0.00-0.00] | 0.41 [0.38-0.43] | 0.37 [0.34-0.39] | 0.93 [0.92-0.94] | 0.93 [0.92-0.94] |
| Category | Metric | DeBERTa-PII | OpenMed L | OpenMed S | PII-Ident. | Ettin-68M | ekacare |
|---|---|---|---|---|---|---|---|
| SHIELD | |||||||
| AGE | Precision | 0.00 [0.00-0.00] | 0.03 [0.01-0.06] | 0.06 [0.04-0.09] | 0.14 [0.09-0.18] | 0.12 [0.05-0.20] | 0.72 [0.68-0.77] |
| AGE | Recall | 0.00 [0.00-0.00] | 0.03 [0.01-0.05] | 0.04 [0.03-0.07] | 0.09 [0.06-0.11] | 0.02 [0.01-0.04] | 0.88 [0.85-0.92] |
| DATE | Precision | 0.42 [0.40-0.44] | 0.66 [0.64-0.68] | 0.62 [0.59-0.64] | 0.65 [0.63-0.67] | 0.65 [0.63-0.67] | 0.57 [0.54-0.59] |
| DATE | Recall | 0.39 [0.36-0.42] | 0.75 [0.73-0.77] | 0.72 [0.70-0.75] | 0.74 [0.71-0.76] | 0.73 [0.71-0.75] | 0.66 [0.63-0.68] |
| DOCTOR | Precision | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] |
| SHIELD category | i2b2 2014 tags | Treatment |
|---|---|---|
| AGE | AGE | straight through; right edge extended over the age unit |
| DATE | DATE | straight through (Philter safe-date re-mapping: sensitivity only) |
| DOCTOR | DOCTOR | straight through |
| HOSPITAL | HOSPITAL | straight through |
| ID | MEDICALRECORD / IDNUM / USERNAME / DEVICE / HEALTHPLAN / BIOID | relabelled |
| LOCATION | CITY / STATE / STREET / ZIP / COUNTRY / LOCATION-OTHER | relabelled; adjacent components merged into one span |
| Capability | TIDE 1.0 | TIDE 2.0 |
|---|---|---|
| Recognizer | coupled, fixed NER | model-agnostic (regex / transformer / LLM) |
| Name / location surrogate | yes (RNG, non-deterministic) | yes (cryptographic keyed) |
| Same value same surrogate | no | yes, automatic (keyed) |
| New key gives an unlinkable release | n/a | yes |
| ID / MRN / SSN / phone | redaction only | format-preserving encryption / hash |
| Email / URL / organization | redaction only | surrogate |
| Category | PHI span | TIDE 1.0 | TIDE 1.0 strat. | TIDE 2.0 | TIDE 2.0 strat. |
|---|---|---|---|---|---|
| Name | John Smith | Ziyad Bromberg | surrogate (RNG) | Flynn Singleton | keyed surrogate |
| Location | 123 Main St, New York, NY 10001 | Nashua NH 03060 | surrogate (RNG) | 13737 Chestnut Hill Rd, Balance Of Jerome County, NY 49885 | keyed surrogate |
| Org | Stanford Health Care | Stanford Health Care | unchanged (no org surrogate) | Unity Ridge Community Hospital | keyed surrogate |
| Date | April 18, 2012 | 04/28/2012 | date-shift (jitter) | April 28th, 2012 | date-shift (jitter) |
| Age | 95 years old | [90 year old] old | generalization (90+) | 89 years old | cap at 89 |
| Age | 88 years old | 88 years old | unchanged (fires 90+ only) | 88 years old | cap at 89 |
| Value | Occ. | TIDE 1.0 | TIDE 2.0 (same key) | TIDE 2.0 (new key) |
| Jose (Name) | A/1 | Rourke | Tidwell | Rowland |
| A/2 | Suskin | Tidwell | (same) | |
| B/1 | Abid | Tidwell | (same) | |
| 15851368 (MRN) | A/1 | [MRN] | 15068153 | 24176984 |
| A/2 | [MRN] | 15068153 | (same) | |
| B/1 | [MRN] | 15068153 | (same) |
| Axis | TIDE 2.0 (batch engine) | OpenMed (detection toolkit) |
|---|---|---|
| Primary artifact | de-id engine/pipeline (recognizer-agnostic) | model collection + toolkit |
| Target unit of work | batch corpora | per-document / on-device inference |
| Recognizer flexibility | any HF token classifier, LLM, regex/Aho-Corasick | own MoE Privacy-Filter + NER families |
| LLM recognizer support | yes (structured-JSON extraction) | not provided |
| Anonymization strategies | mask / keyed surrogate / FPE / hash / per-patient date shift | mask / synthetic replace / hash / temporal shift |
| Longitudinal consistency across notes | yes, cryptographic keyed | not guaranteed across documents |
| Axis | TIDE 2.0 | GCP Sensitive Data Protection | Azure Health De-id | AWS Comprehend Medical |
|---|---|---|---|---|
| Deployment | on-prem, open-source (PHI local) | managed cloud | managed cloud | managed cloud |
| De-identify (replace) or only detect? | detect + replace | detect + redact/replace/mask/crypto/tokenize | detect + surrogation | detect only |
| Longitudinal consistency across notes | yes, cryptographic keyed | not documented as built in | not documented as built in | n/a |
| Interval-preserving per-patient date shift | yes | generic date-shift, not per-patient | limited | n/a |
| Model-agnostic recognizer | yes | fixed service models | fixed service models | fixed service models |
| Batch execution | Ray distributed (single-node benchmark in this paper) | via cloud APIs (egress + quota) | via cloud APIs | via cloud APIs |
| Share (%) | Recall | |||||
|---|---|---|---|---|---|---|
| Category | SHIELD | i2b2 | SHIELD | i2b2 | Recall term | Mix term |
| AGE | 3.5 | 7.3 | 0.78 | 0.68 | +0.006 | -0.028 |
| DATE | 34.7 | 45.7 | 0.94 | 0.85 | +0.037 | -0.099 |
| DOCTOR | 25.4 | 17.6 | 0.90 | 0.85 | +0.010 | +0.069 |
| HOSPITAL | 9.0 | 8.5 | 0.79 | 0.39 | +0.034 | +0.003 |
| ID | 7.1 | 6.8 | 0.90 | 0.64 | +0.018 | +0.002 |
| SHIELD | i2b2 2014 | |||
|---|---|---|---|---|
| Category | R [95% CI] | P [95% CI] | R [95% CI] | P [95% CI] |
| AGE | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] |
| DATE | +0.001 [+0.000 to +0.004] | -0.011 [-0.016 to -0.007] | +0.007 [+0.004 to +0.010] | -0.007 [-0.009 to -0.005] |
| DOCTOR | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] | +0.000 [+0.000 to +0.000] |
| HOSPITAL | -0.008 [-0.014 to -0.002] | -0.001 [-0.004 to +0.001] | -0.000 [-0.001 to +0.000] | +0.000 [-0.001 to +0.002] |
| ID | +0.012 [+0.000 to +0.029] | -0.000 [-0.004 to +0.002] | +0.009 [+0.005 to +0.014] | -0.003 [-0.007 to +0.000] |
| SHIELD | i2b2 2014 | |||
|---|---|---|---|---|
| Model | P [95% CI] | R [95% CI] | P [95% CI] | R [95% CI] |
| TIDE2 regex | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] | 0.00 [0.00-0.00] |
| AIMI v1 | 0.55 [0.53-0.58] | 0.59 [0.56-0.61] | 0.35 [0.34-0.37] | 0.35 [0.33-0.37] |
| AIMI v2 | 0.53 [0.51-0.55] | 0.56 [0.54-0.58] | 0.33 [0.32-0.35] | 0.33 [0.32-0.35] |
| TIDE2-Sentry | 0.95 [0.94-0.96] | 0.91 [0.89-0.92] | 0.93 [0.92-0.94] | 0.84 [0.83-0.86] |
| TIDE2-Sentry + regex | 0.95 [0.94-0.96] | 0.91 [0.89-0.92] | 0.93 [0.92-0.94] | 0.84 [0.83-0.86] |