Skip to main content
Technical docs

Profiles and coverage

the five profiles, sensitive attributes, and the coverage matrix (HIPAA Safe Harbor's 18 identifiers, GDPR, PCI) mapped to rules and corpus cases.

Profiles and coverage

Profiles

A profile is the policy for one scrub. The control plane names it in the claim (absent: strict); the runner resolves it with profiles.get, fails the job on an unknown or unavailable name, activates it, and reports profiles.summary(p) (id, version, enforced fields, pending fields). HIPAA profiles are always strict underneath (extends: strict) and add their own date, linkage and stand-in rules.

profiles.json 1.3.0; default strict.

Field Strict (strict) Standard (standard) B2B (b2b) Strict, HIPAA Safe Harbor (hipaa_safe_harbor) Strict, HIPAA Expert Determination (hipaa_expert)
dates deal_offset deal_offset deal_offset year deal_offset
zip3 yes no no yes yes
age_cap 90 – – 90 90
faces blur blur blur blur blur
voices hold hold hold hold hold
special_categories hold flag flag hold hold
minors hold flag flag hold hold
third_party_companies tokenize tokenize keep tokenize tokenize
fallback_allowed no yes yes no no
linkage_table risk_checked risk_checked risk_checked off risk_checked
stand_ins keyed keyed keyed random random
skus keep keep keep keep keep
surrogates tags tags tags tags tags
  • Enforced fields: dates, zip3, age_cap, stand_ins, fallback_allowed, third_party_companies, linkage_table, special_categories, minors, faces, voices, skus, surrogates
  • Pending capabilities (profiles.MISSING): none
  • Allowed values: dates year, deal_offset, keep; zip3 yes, no; age_cap integer from 18 to 120, or null for no cap; faces blur, keep; voices hold, keep; special_categories hold, flag; minors hold, flag; third_party_companies tokenize, keep; fallback_allowed yes, no; linkage_table risk_checked, off; stand_ins keyed, random; skus keep, tokenize; surrogates tags, realistic
  • Expert Determination certificate fields: id, expert, scope, expiresAt

What each field does:

Field Effect
dates deal_offset: every date shifted by the deal's keyed whole-week offset; year: every date element but the year removed (fixed-width healthcare date fields become the year's first day); keep: unchanged. Birth dates go to the year under every mode but keep
zip3 ZIP columns cut to 3 digits; the restricted ZIP3 areas become 000
age_cap age columns at or over the cap become <cap>+
faces blur: faces boxed in images and video frames
voices hold: audio with speech is held (its scrubbed transcript still ships)
special_categories, minors hold: the record (or file, where there are no records) is held; flag: counted and reported, shipped scrubbed
third_party_companies tokenize: other companies' names become [ORG_…]; keep: they ship
fallback_allowed false: a missing or mismatched model, or a detector error, fails the job or holds the file instead of falling back
linkage_table risk_checked: the person-linkage table ships only for people in a linked-view class of at least k (held whole when more than half would be cut); off: no table
stand_ins keyed: HMAC stand-ins; random: CSPRNG tokens held in the sealed identity map (needs the map, fails closed without it)
skus tokenize: product codes become stand-ins; keep: they ship
surrogates tags: bracketed stand-ins; realistic: plausible fake names, emails and phones (never with random stand-ins or a HIPAA profile)

Expert Determination (hipaa_expert) also needs a certificate reference in the claim (id, expert, scope, expiry). profiles.check_certificate checks its shape and that it hasn't expired; it can't check that the determination is real or covers this data. That is the expert's and the control plane's job.

Sensitive attributes

GDPR Art. 9 special categories, Art. 10 criminal data and minors, by sensitive.json. Text is classified per row, record or message where the format has records, and per file otherwise; code, config and git history are not read for them. A held record is dropped and counted (sensitive_held:<reason>); a held file is listed with the reason. The desk can release the releasable reasons for a source; the never-released ones can't be.

sensitive.json 1.0.0. Person cue window: 80 characters; 149 person cues; 62 global cancel contexts.

Category Strong Medium Weak Not Column rule
health 113 59 28 12 yes
racial_ethnic 17 7 17 4 yes
political 21 3 21 6 yes
religion 19 33 44 9 yes
trade_union 21 8 19 4 yes
genetic 22 5 8 3 yes
biometric 23 3 7 4 yes
sex_life 23 8 10 5 yes
criminal 50 14 18 13 yes
minor 37 11 32 5 yes
sexual content 15 0 5 2 –
  • Tiers: strong: flags on its own. medium: a term specific to the category; flags beside a person (within window chars). weak: a common word; needs a person and a second distinct hit. not: contexts that cancel any hit they overlap.
  • Releasable by the desk: health, racial_ethnic, political, religion, trade_union, genetic, biometric, sex_life, criminal, minor, image_unclassified, pending_detector
  • Never released: sexual_minor, image_sexual, escalated, voice

Media: the image classifier and voice detector hooks exist (policy.image, policy.audio) but no classifier is registered in the reference runner yet. Under a profile with no fallback, an image that would need one is held (image_unclassified, pending_detector). Not live: image content classification.

Coverage matrix

coverage.json maps every identifier class the package claims to handle to the rules that detect it and the corpus cases that prove it. tests/test_coverage.py fails when a row cites a rule or case that doesn't exist, cites a known-gap case as proof, or cites no case at all. Status words:

  • covered: rules and passing cases for the class as defined;
  • partial: rules and cases exist, but part of the class is missed (the note says which);
  • planned: not handled yet; the phase names the plan step that builds it.

coverage.json 1.0.0.

HIPAA Safe Harbor, 45 CFR 164.514(b)(2)(i)

Row Ref Identifier Status Phase
hipaa.A 164.514(b)(2)(i)(A) Names partial ensemble
hipaa.B 164.514(b)(2)(i)(B) Geographic subdivisions smaller than a state, ZIP beyond the first 3 digits partial ensemble
hipaa.C 164.514(b)(2)(i)(C) Dates (except year) related to an individual; ages over 89 partial hipaa
hipaa.D 164.514(b)(2)(i)(D) Telephone numbers covered –
hipaa.E 164.514(b)(2)(i)(E) Fax numbers covered –
hipaa.F 164.514(b)(2)(i)(F) Email addresses covered –
hipaa.G 164.514(b)(2)(i)(G) Social Security numbers covered –
hipaa.H 164.514(b)(2)(i)(H) Medical record numbers covered –
hipaa.I 164.514(b)(2)(i)(I) Health plan beneficiary numbers partial ensemble
hipaa.J 164.514(b)(2)(i)(J) Account numbers covered –
hipaa.K 164.514(b)(2)(i)(K) Certificate and license numbers partial ensemble
hipaa.L 164.514(b)(2)(i)(L) Vehicle identifiers and serial numbers, including license plates partial images
hipaa.M 164.514(b)(2)(i)(M) Device identifiers and serial numbers partial ensemble
hipaa.N 164.514(b)(2)(i)(N) Web URLs partial ensemble
hipaa.O 164.514(b)(2)(i)(O) IP addresses covered –
hipaa.P 164.514(b)(2)(i)(P) Biometric identifiers, including finger and voice prints planned av
hipaa.Q 164.514(b)(2)(i)(Q) Full-face photographs and comparable images planned images
hipaa.R 164.514(b)(2)(i)(R) Any other unique identifying number, characteristic or code partial workflow

GDPR

Row Ref Identifier Status Phase
gdpr.name Art. 4(1) name Names partial ensemble
gdpr.identification_number Art. 4(1) identification number National and tax identification numbers partial ensemble
gdpr.location Art. 4(1) location data Location data partial ensemble
gdpr.online_identifier Art. 4(1) online identifier; Recital 30 Online identifiers: IP, cookie, device and ad ids partial ensemble
gdpr.contact Art. 4(1) Contact details: email and phone covered –
gdpr.financial Art. 4(1) Bank and payment identifiers covered –
gdpr.special_categories Art. 9(1) Special categories: health, racial or ethnic origin, political opinions, religious beliefs, union membership, genetic, biometric, sex life or orientation partial sensitive
gdpr.criminal Art. 10 Criminal convictions and offences partial sensitive
gdpr.children Art. 8 Children's data partial sensitive
gdpr.identity_factors Art. 4(1) physical, physiological, genetic, mental, economic, cultural or social identity Quasi-identifiers in combination planned surrogates

PCI DSS cardholder data

Row Ref Identifier Status Phase
pci.pan PCI DSS 3.3, 3.4 Primary account number partial ensemble
pci.cardholder_name PCI DSS cardholder data Cardholder name partial ensemble
pci.expiry PCI DSS cardholder data Expiration date partial ensemble
pci.cvv PCI DSS 3.3.1.2 sensitive authentication data Card verification code partial ensemble
pci.track PCI DSS 3.3.1.1 sensitive authentication data Full track data covered –

Totals: hipaa 7 covered, 9 partial, 2 planned; gdpr 2 covered, 7 partial, 1 planned; pci 1 covered, 4 partial Rules, corpus cases and each row's note on what it misses are in the auditor edition.

Two notes in the matrix are older than the code. hipaa.P (voice prints) says the voices field is pending and hipaa.Q (full-face photographs) says the faces field is pending and images are redacted for text only; at this version profiles.json enforces both fields and the reference runner boxes faces with its pinned face detector. The status words (planned) and notes will change in the next coverage.json version, which also changes every report's engine.rules hash; until then the matrix is the conservative reading.

The report's coverageOpen metric counts partial and planned rows, and the Strong privacy band needs it at 0. With the rows above open, no report can reach Strong privacy at this version; Good is the ceiling.

Engine docs at commit 1c5af8f39ebb. Plain-language versions: what happens to your data, the workflow score.