
关于
受保护健康信息(PHI)和个人身份信息(PII)合规模式,确保医疗应用符合 HIPAA 等法规要求。
name: healthcare-phi-compliance description: 医疗应用中受保护健康信息 (PHI) 和个人身份信息 (PII) 的合规模式。涵盖数据分类、访问控制、审计追踪、加密和常见泄漏向量。 origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel version: "1.0.0"
医疗 PHI/PII 合规模式
保护医疗应用中患者数据、临床医生数据和财务数据的模式。适用于 HIPAA(美国)、DISHA(印度)、GDPR(欧盟)和一般医疗数据保护。
适用场景
- 构建任何涉及患者记录的功能
- 为临床系统实现访问控制或认证
- 设计医疗数据的数据库 schema
- 构建返回患者或临床医生数据的 API
- 实现审计追踪或日志记录
- 审查代码中的数据暴露漏洞
- 为多租户医疗系统设置行级安全 (RLS)
工作原理
医疗数据保护在三个层面运作:分类(什么是敏感的)、访问控制(谁可以看到)和审计(谁确实看到了)。
数据分类
PHI(受保护健康信息) — 任何可以识别患者身份且与其健康相关的数据:患者姓名、出生日期、地址、电话、邮箱、国民身份证号(SSN、Aadhaar、NHS 号码)、病历号、诊断、药物、化验结果、影像、保险保单和理赔详情、预约和入院记录,或以上任何组合。
PII(非患者敏感数据) 在医疗系统中:临床医生/员工个人详情、医生费用结构和支付金额、员工薪资和银行详情、供应商付款信息。
访问控制:行级安全
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
-- Scope access by facility
CREATE POLICY "staff_read_own_facility"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments
WHERE user_id = auth.uid() AND role IN ('doctor','nurse','lab_tech','admin')
));
-- Audit log: insert-only (tamper-proof)
CREATE POLICY "audit_insert_only" ON audit_log FOR INSERT
TO authenticated WITH CHECK (user_id = auth.uid());
CREATE POLICY "audit_no_modify" ON audit_log FOR UPDATE USING (false);
CREATE POLICY "audit_no_delete" ON audit_log FOR DELETE USING (false);
审计追踪
每次 PHI 访问或修改都必须记录:
interface AuditEntry {
timestamp: string;
user_id: string;
patient_id: string;
action: 'create' | 'read' | 'update' | 'delete' | 'print' | 'export';
resource_type: string;
resource_id: string;
changes?: { before: object; after: object };
ip_address: string;
session_id: string;
}
常见泄漏向量
错误消息: 永远不要在抛给客户端的错误消息中包含患者识别数据。仅在服务端记录详情。
控制台输出: 永远不要记录完整的患者对象。使用不透明的内部记录 ID(UUID)——而非病历号、国民身份证号或姓名。
URL 参数: 永远不要将患者识别数据放在可能出现在日志或浏览器历史中的查询字符串或路径段中。仅使用不透明的 UUID。
浏览器存储: 永远不要将 PHI 存储在 localStorage 或 sessionStorage 中。仅在内存中保留 PHI,按需获取。
Service role 密钥: 永远不要在客户端代码中使用 service_role 密钥。始终使用 anon/publishable 密钥并让 RLS 强制执行访问。
日志和监控: 永远不要记录完整的患者记录。仅使用不透明的记录 ID(非病历号)。在发送到错误追踪服务之前清理堆栈追踪。
数据库 Schema 标记
在 schema 级别标记 PHI/PII 列:
COMMENT ON COLUMN patients.name IS 'PHI: patient_name';
COMMENT ON COLUMN patients.dob IS 'PHI: date_of_birth';
COMMENT ON COLUMN patients.aadhaar IS 'PHI: national_id';
COMMENT ON COLUMN doctor_payouts.amount IS 'PII: financial';
部署检查清单
每次部署前:
- 错误消息或堆栈追踪中无 PHI
- console.log/console.error 中无 PHI
- URL 参数中无 PHI
- 浏览器存储中无 PHI
- 客户端代码中无 service_role 密钥
- 所有 PHI/PII 表启用 RLS
- 所有数据修改有审计追踪
- 配置了会话超时
- 所有 PHI 端点有 API 认证
- 验证了跨机构数据隔离
示例
示例 1:安全与不安全的错误处理
// BAD — leaks PHI in error
throw new Error(`Patient ${patient.name} not found in ${patient.facility}`);
// GOOD — generic error, details logged server-side with opaque IDs only
logger.error('Patient lookup failed', { recordId: patient.id, facilityId });
throw new Error('Record not found');
示例 2:多机构隔离的 RLS 策略
-- Doctor at Facility A cannot see Facility B patients
CREATE POLICY "facility_isolation"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments
WHERE user_id = auth.uid()
));
