HIPAA for AI Developers
Healthcare AI is exploding — and so are HIPAA enforcement actions. Sending patient records to LLM APIs without de-identification or a BAA is a breach by definition. Every Rule mapped to what your AI pipeline must actually do, in code.
What is HIPAA?
The Health Insurance Portability and Accountability Act (HIPAA) — 45 CFR Parts 160, 162, and 164 — governs how Covered Entities and their Business Associates create, receive, maintain, or transmit Protected Health Information (PHI). Enforced by HHS Office for Civil Rights (OCR), HIPAA has three operational rules: the Privacy Rule (what you can do with PHI), the Security Rule (how to protect electronic PHI), and the Breach Notification Rule (what to do when things go wrong).
In 2024, HHS OCR issued explicit guidance clarifying that AI systems creating, receiving, maintaining, or transmitting PHI are fully subject to HIPAA. Sending PHI to an LLM API is a "disclosure" under 45 CFR 164.502. The LLM vendor becomes a Business Associate and requires a BAA — or the PHI must be de-identified before transmission.
Who is affected?
What is PHI?
Protected Health Information is any individually identifiable health information — information that relates to the past, present, or future physical or mental health of an individual, the provision of healthcare, or payment for healthcare — that is linked or linkable to a specific individual.
For AI systems, the practical definition is broader than most developers expect. A clinical note, an insurance claim number, a medical appointment date, an IP address in a patient portal access log, or a discharge summary — all PHI when linked to a specific patient. The key test: can this information, alone or combined, identify a specific patient?
The 18 Safe Harbor identifiers
The HIPAA Safe Harbor method of de-identification (45 CFR §164.514(b)) requires removal of all 18 specified identifiers plus any other information that could identify the individual. If all 18 are removed, the data is no longer PHI and can be transmitted to LLM APIs without a BAA.
locale='us'. Names, geographic data, dates, fax numbers, URLs, vehicle/device identifiers, biometrics, and photos require NER models or specialised detection beyond regex patterns.De-identification in AI pipelines
The Safe Harbor method is the only practical de-identification approach at the throughput of an AI pipeline. Expert Determination (the other HIPAA method) requires a qualified statistician to certify re-identification risk is "very small" — impossible to do per-request at scale.
Safe Harbor de-identification before LLM calls also eliminates the need for a BAA with the LLM vendor for that specific call — because de-identified data is not PHI. This is the simplest architectural choice: strip PHI locally, send clean data to the LLM, keep the original PHI in your controlled environment.
import governor, openai
from governor_tracer import GovernorTracer
tracer = GovernorTracer(agent_id="clinical-coder-v2")
# locale='us' activates: SSN_US, MRN, NPI, US_PHONE, EMAIL, IP addresses, CREDIT_CARD
client = governor.wrap(
openai.OpenAI(),
locale="us",
tracer=tracer, # every call logged to audit trail
)
# PHI is stripped before reaching OpenAI — no BAA required for this call.
# Audit trail records pii_types=["MRN", "SSN_US"] with pii_redacted=True.
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": "Code this note: Patient MRN P123456, SSN 123-45-6789. "
"Admitted 2026-06-10 with chest pain. Discharged 2026-06-12.",
}]
)
# Prompt sent to OpenAI:
# "Code this note: Patient [MRN], [SSN_US]. Admitted 2026-06-10 with chest pain..."
# Dates are not redacted by regex — use NER model for full Safe Harbor complianceBusiness Associate Agreements with LLM vendors
If PHI will reach an LLM API (because de-identification is partial or not implemented), a HIPAA-compliant BAA must be signed before any PHI is transmitted. The BAA must include the 45 CFR §164.504(e) mandatory provisions:
Minimum necessary rule (45 CFR §164.502(b))
HIPAA requires that only the minimum PHI necessary to accomplish the intended purpose be used or disclosed. For AI systems this means: pass only the PHI fields the current task requires — not the entire patient record. An AI agent coding a discharge diagnosis needs the clinical note, not the patient's SSN, insurance ID, or home address.
from governor_tracer import GovernorTracer
tracer = GovernorTracer(agent_id="icd10-coder")
with tracer.run() as run:
# Log exactly which fields were accessed and why
run.data_access(
source="ehr_api",
# MINIMUM — only what the coding task requires
fields_accessed=["clinical_note", "primary_diagnosis", "procedure_codes"],
purpose="icd10_coding",
data_principal_id="PATIENT-8821", # hashed before storage
)
# NOT: fields_accessed=["full_record"] — violates minimum necessaryAudit controls — 45 CFR §164.312(b)
The Security Rule's audit controls standard is a required implementation specification. Covered Entities must implement hardware, software, and procedural mechanisms to record and examine activity in systems containing ePHI. For AI systems, this means a tamper-evident log of every agent action — not just the final outcome.
HHS OCR has consistently found that audit log gaps are one of the top causes of HIPAA enforcement actions. In 2023–2024, OCR settled cases where breaches were not discovered for months because no audit logs existed.
from governor_tracer import GovernorTracer
tracer = GovernorTracer(agent_id="prior-auth-agent")
with tracer.run() as run:
# §164.312(b) — every activity recorded
run.data_access(
source="claims_db",
fields_accessed=["diagnosis_codes", "procedure_codes", "plan_id"],
purpose="prior_authorization_review",
data_principal_id="PATIENT-4419",
)
run.llm_call(
provider="openai",
model="gpt-4o",
prompt="[MRN] patient, ICD-10: J45.20, CPT: 94640", # PHI stripped
response="Clinical criteria met. Approve authorization.",
pii_types=["MRN"],
redact_pii=True,
)
run.decision(
reason="Diagnosis J45.20 meets plan criteria for CPT 94640",
outcome="authorize",
confidence=0.94,
)
# Clinical decision requires clinician review (FDA CDS guidance)
run.human_checkpoint(
question="Approve prior auth for PATIENT-4419, CPT 94640?",
approved=True,
reviewer_id="dr.patel.npi.1234567893", # NPI of reviewing clinician
notes="Reviewed clinical note and plan criteria. Criteria met.",
)
# Verify chain integrity — required by §164.312(c)(1) integrity controls
valid, msg = run.verify()
print(f"Audit chain intact: {valid}")Breach notification — 45 CFR §164.400–164.412
A breach of unsecured PHI triggers notification obligations. Unlike GDPR's 72-hour window, HIPAA allows up to 60 days from discovery — but discovery is the key word. If you had audit logs that would have revealed the breach earlier, regulators have found that the clock started at the point where logs would have revealed it.
For AI systems, the most likely breach scenario is un-redacted PHI reaching an LLM API. The Governor audit trail records pii_redacted: true/false for every LLM call — making it possible to determine exactly which calls exposed PHI, what types, and on behalf of which patients.
Risk analysis for AI systems — 45 CFR §164.308(a)(1)
A thorough and accurate risk analysis is a requiredSecurity Rule implementation. HHS OCR treats missing or inadequate risk analysis as one of the most serious HIPAA violations. For AI systems, the risk analysis must now cover AI-specific threats that didn't exist when most organisations last ran their assessment:
Implementation: PHI detection
# pip install pygovernor
import governor
# Detect US PHI identifiers
entities = governor.detect(
"Patient MRN P123456, SSN 123-45-6789, NPI 1234567893, phone +1-800-555-1234",
locale="us",
)
# [
# Entity(type='MRN', value='P123456', start=12, end=18),
# Entity(type='SSN_US', value='123-45-6789', start=25, end=36),
# Entity(type='NPI', value='1234567893', start=43, end=53),
# Entity(type='US_PHONE', value='+1-800-555-1234', start=61, end=77),
# ]
# Redact — token replacement
result = governor.redact("SSN: 123-45-6789, MRN: P123456", locale="us")
result.text # "SSN: [SSN_US], MRN: [MRN]"
# Redact — mask (preserves last segment for reference)
result = governor.redact("SSN: 123-45-6789", locale="us", replacement="mask")
result.text # "SSN: XXX-XX-6789"US PHI types Governor detects
Implementation: HIPAA-compliant AI audit trail
// npm install governor-sdk
import { GovernorTracer } from 'governor/tracer';
import { wrap } from 'governor-sdk';
import OpenAI from 'openai';
const tracer = new GovernorTracer('clinical-coder-v2');
// wrap auto-logs every API call with pii_types and pii_redacted=true
const client = wrap(new OpenAI(), { locale: 'us', tracer });
async function codeNote(patientId: string, note: string) {
const run = tracer.run();
run.dataAccess('ehr_api', ['clinical_note', 'diagnosis'], 'icd10_coding', patientId);
// PHI stripped before OpenAI receives it; call logged automatically
const result = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: note }],
});
run.decision(
'Diagnosis codes extracted from clinical note',
result.choices[0].message.content ?? '',
0.95,
);
// FDA CDS guidance — clinician must review AI coding output
run.humanCheckpoint(
`Confirm ICD-10 codes for patient ${patientId}?`,
true,
'dr.smith.npi.9876543210',
);
const { valid } = await run.verify();
console.log('HIPAA audit chain intact:', valid);
return result;
}Penalties
HIPAA penalties have four tiers based on culpability. Annual caps apply per violation category. For multi-year violations discovered in a single audit, the annual cap applies separately per year — meaning a 3-year violation can result in 3× the annual cap.
HIPAA compliance checklist for AI systems
Before deploying AI on PHI
governor.wrap(client, locale='us')GovernorTracer(agent_id='...')At runtime
Ongoing
run.verify()governor.wrap(client, locale='us').