Summary
deidproof.core._value_matches detects an IPv4 address with a regex that matches
each octet as 25[0-5]|2[0-4]\d|1?\d?\d, and the phone-number detector uses a
10-digit shape. Neither the k-anonymity nor the Safe Harbor logic distinguishes
an IPv6 address, which is increasingly common in device/telemetry and
web-log exports (upload_ip = 2001:db8::1). Today an IPv6 upload address in a
value cell is not flagged as S15.
Why it matters
45 CFR 164.514(b)(2) category S15 (IP address) does not distinguish IPv4 from
IPv6. A biobank/device export that logs the collaborator's IPv6 upload address
would pass the content scan and be called "de-identified" when it is not.
Suggested fix
Add an IPv6 value-level detector (a bounded pattern covering the common
xxxx:xxxx::xxxx forms and IPv4-mapped ::ffff:a.b.c.d) that emits S15,
alongside the existing IPv4 detector. Header-name detection already covers
ip/ipaddress, so this is purely a value-content gap.
Repro
from deidproof.core import _value_matches
print(_value_matches("2001:db8::1")) # -> [] (expected: ['S15'])
Summary
deidproof.core._value_matchesdetects an IPv4 address with a regex that matcheseach octet as
25[0-5]|2[0-4]\d|1?\d?\d, and the phone-number detector uses a10-digit shape. Neither the k-anonymity nor the Safe Harbor logic distinguishes
an IPv6 address, which is increasingly common in device/telemetry and
web-log exports (
upload_ip = 2001:db8::1). Today an IPv6 upload address in avalue cell is not flagged as S15.
Why it matters
45 CFR 164.514(b)(2) category S15 (IP address) does not distinguish IPv4 from
IPv6. A biobank/device export that logs the collaborator's IPv6 upload address
would pass the content scan and be called "de-identified" when it is not.
Suggested fix
Add an IPv6 value-level detector (a bounded pattern covering the common
xxxx:xxxx::xxxxforms and IPv4-mapped::ffff:a.b.c.d) that emitsS15,alongside the existing IPv4 detector. Header-name detection already covers
ip/ipaddress, so this is purely a value-content gap.Repro