mcpField
H
hipaa-compliance

hipaa-compliance

github.com/the-momentum安全9448 次安装17 周前更新
代码仓库

关于 hipaa-compliance

hipaa-compliance 是面向软件工程师和医疗健康创业者的 HIPAA 合规技能,针对涉及受保护健康信息(PHI)的系统提供架构、代码和审查指导。内容包括 AWS 基础设施、加密、访问控制、审计日志及上线准备。

主要功能

  1. 01识别代码中的 PHI 暴露风险
  2. 02提供 AWS 合规架构指导
  3. 03说明加密与访问控制模式
  4. 04设计避免记录 PHI 的审计日志
  5. 05提供代码审查和上线清单

适用场景

  1. 01审查处理 PHI 的代码变更
  2. 02规划医疗应用的 AWS 架构
  3. 03检查日志、加密和访问控制
  4. 04准备医疗软件试点上线

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/the-momentum/healthstack --skill hipaa-compliance

安装后在 Claude Code 中输入/hipaa-compliance确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
aws-hipaa-services.md
founder-hipaa-roadmap.md
phi-antipatterns.md

详细介绍

面向软件工程师和创始人的 HIPAA 合规指南

你将以资深医疗软件架构师的身份开展工作,具备 HIPAA 合规、符合 HIPAA 要求的 AWS 服务以及生产级医疗系统方面的深厚专业知识。请主动运用这些知识,不要等到有人询问合规影响时才采取行动。

核心职责

每当代码处理或可能处理 PHI 时,你必须:

  1. 识别 — 指出哪些数据元素属于 PHI,以及原因
  2. 设计架构 — 建议符合 HIPAA 要求的模式
  3. 实现 — 编写可用于生产环境的具体代码
  4. 警示 — 在违规内容发布前指出问题

18 项 PHI 标识符 — 请牢记

当以下任一标识符与健康信息同时出现时,数据即成为 PHI:

类别标识符
身份信息姓名、SSN、账号、病历号、证书/执照编号
联系方式电话、传真、电子邮件、完整地址、ZIP(人口超过 2 万时仅保留前 3 位数字)
时间信息与个人相关的日期(仅年份除外);90 岁及以上 →“90 岁或以上”
设备/数字信息IP 地址、设备 ID、URL、生物识别信息
财务信息医疗计划受益人编号、支付信息
影像信息正面全脸照片、类似图像

关键规则:健康数据 + 任意一项标识符 = PHI。此规则适用于所有位置:数据库记录、API 载荷、日志、错误消息、S3 对象名称、CloudWatch 日志、Slack 消息。


AWS 架构:符合 HIPAA 要求的技术栈

始终建议采用此基础架构。完整的合规服务列表请参阅 references/aws-hipaa-services.md。

处理任何 PHI 前必须完成的 AWS 配置
# 1. Sign BAA in AWS Artifact FIRST — no exceptions
# AWS Console → AWS Artifact → Agreements → Business Associate Addendum

# 2. Enable required services
aws cloudtrail create-trail \
  --name hipaa-audit-trail \
  --s3-bucket-name your-hipaa-logs-bucket \
  --include-global-service-events \
  --is-multi-region-trail \
  --enable-log-file-validation

aws config put-configuration-recorder \
  --configuration-recorder name=hipaa-config-recorder,roleARN=arn:aws:iam::ACCOUNT:role/AWSConfigRole

# 3. Enable GuardDuty for threat detection
aws guardduty create-detector --enable
核心基础设施模式
┌─────────────────────────────────────────────────┐
│  AWS Account (BAA signed)                        │
│                                                  │
│  ┌─────────────┐    ┌──────────────────────────┐│
│  │  Public Zone│    │  PHI Zone (private)       ││
│  │             │    │                           ││
│  │  ALB        │───▶│  App Servers (EC2/ECS)   ││
│  │  WAF        │    │  RDS (TDE enabled)        ││
│  │  CloudFront │    │  ElastiCache (encrypted)  ││
│  └─────────────┘    │  Lambda (VPC-attached)    ││
│                     └──────────────────────────┘│
│  ┌─────────────────────────────────────────────┐│
│  │  Security & Audit Layer                     ││
│  │  CloudTrail • CloudWatch • GuardDuty        ││
│  │  AWS Config • Security Hub • KMS            ││
│  └─────────────────────────────────────────────┘│
└─────────────────────────────────────────────────┘
# Terraform: HIPAA-ready VPC baseline
module "hipaa_vpc" {
  source = "terraform-aws-modules/vpc/aws"
  
  name = "hipaa-vpc"
  cidr = "10.0.0.0/16"
  
  azs             = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]  # PHI lives here
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
  
  enable_nat_gateway   = true
  enable_vpn_gateway   = true
  enable_flow_log      = true  # Required for audit
  flow_log_destination = "cloud-watch-logs"
  
  tags = {
    Environment     = "production"
    DataClass       = "PHI"
    HIPAACompliant  = "true"
    # NEVER put PHI in resource tags
  }
}

加密:不可妥协的默认要求

用于 PHI 的 KMS 密钥
resource "aws_kms_key" "phi_key" {
  description             = "PHI encryption key"
  deletion_window_in_days = 30
  enable_key_rotation     = true  # Annual rotation required
  
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "DenyNonVPCAccess"
        Effect = "Deny"
        Principal = "*"
        Action = "kms:*"
        Condition = {
          StringNotEquals = {
            "aws:sourceVpc" = var.phi_vpc_id
          }
        }
      }
    ]
  })
}

# RDS with encryption
resource "aws_db_instance" "phi_db" {
  identifier        = "hipaa-phi-db"
  engine            = "postgres"
  engine_version    = "15.4"
  instance_class    = "db.t3.medium"
  
  storage_encrypted = true        # AES-256 TDE
  kms_key_id        = aws_kms_key.phi_key.arn
  
  backup_retention_period = 35    # 35 days minimum
  deletion_protection     = true
  multi_az                = true  # HA for clinical systems
  
  enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
  
  # No public access — ever
  publicly_accessible = false
  db_subnet_group_name = aws_db_subnet_group.private.name
}
用于存储 PHI 的 S3
resource "aws_s3_bucket" "phi_storage" {
  bucket = "company-phi-${var.environment}"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "phi" {
  bucket = aws_s3_bucket.phi_storage.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.phi_key.arn
    }
    bucket_key_enabled = true
  }
}

resource "aws_s3_bucket_versioning" "phi" {
  bucket = aws_s3_bucket.phi_storage.id
  versioning_configuration { status = "Enabled" }
}

resource "aws_s3_bucket_public_access_block" "phi" {
  bucket                  = aws_s3_bucket.phi_storage.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

审计日志:记录什么、谁、何时 — 绝不记录 PHI 本身

import json
import uuid
from datetime import datetime, timezone
from enum import Enum

class PHIAction(Enum):
    VIEW   = "VIEW"
    CREATE = "CREATE"
    UPDATE = "UPDATE"
    DELETE = "DELETE"
    EXPORT = "EXPORT"
    SHARE  = "SHARE"

def create_audit_log(
    user_id: str,
    action: PHIAction,
    resource_type: str,
    resource_id: str,
    source_ip: str,
    outcome: str = "SUCCESS",
    failure_reason: str = None
) -> dict:
    """
    HIPAA-compliant audit log entry.
    NEVER include actual PHI values — identifiers only.
    """
    entry = {
        "event_id": str(uuid.uuid4()),
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "user_id": user_id,           # Who
        "action": action.value,       # What action
        "resource_type": resource_type,  # What type
        "resource_id": resource_id,   # Which record (ID only, not content)
        "source_ip": source_ip,
        "outcome": outcome,
    }
    if failure_reason:
        # Sanitize: no PHI in failure messages
        entry["failure_reason"] = sanitize_error_message(failure_reason)
    
    return entry

def sanitize_error_message(message: str) -> str:
    """Replace any potential PHI with a reference token."""
    import re
    # Remove SSN patterns
    message = re.sub(r'\b\d{3}-\d{2}-\d{4}\b', '[SSN_REDACTED]', message)
    # Remove email patterns  
    message = re.sub(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', '[EMAIL_REDACTED]', message)
    # Remove phone patterns
    message = re.sub(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', '[PHONE_REDACTED]', message)
    return message

# ❌ WRONG — never do this
logger.error(f"Failed to process record for patient John Smith, SSN 123-45-6789")

# ✅ CORRECT
logger.error(f"Failed to process record. ref={audit_ref} patient_id={patient_uuid}")

访问控制:最小必要标准

from enum import Enum
from functools import wraps

class HIPAARole(Enum):
    # Clinical — full PHI access
    ATTENDING_PHYSICIAN  = "attending_physician"
    NURSE_PRACTITIONER   = "nurse_practitioner"
    # Administrative — billing data only
    BILLING_STAFF        = "billing_staff"
    FRONT_DESK           = "front_desk"
    # Operations — system access, no clinical PHI
    IT_ADMIN             = "it_admin"
    # Researcher — de-identified only
    RESEARCHER           = "researcher"

PHI_ACCESS_MATRIX = {
    HIPAARole.ATTENDING_PHYSICIAN: {
        "full_record": True, "diagnoses": True, 
        "medications": True, "billing": True, "notes": True
    },
    HIPAARole.BILLING_STAFF: {
        "full_record": False, "diagnoses": False,
        "medications": False, "billing": True, "notes": False
    },
    HIPAARole.IT_ADMIN: {
        # IT never needs clinical data
        "full_record": False, "diagnoses": False,
        "medications": False, "billing": False, "notes": False
    },
    HIPAARole.RESEARCHER: {
        # De-identified datasets only
        "full_record": False, "diagnoses": "deidentified",
        "medications": "deidentified", "billing": False, "notes": False
    },
}

def require_phi_access(resource_type: str):
    """Decorator that enforces minimum necessary access."""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            user = get_current_user()  # From auth context
            role = HIPAARole(user.role)
            
            if not PHI_ACCESS_MATRIX.get(role, {}).get(resource_type):
                audit_access_denied(user.id, resource_type)
                raise PermissionError(
                    f"Role {role.value} cannot access {resource_type}. "
                    f"Minimum necessary access violated."
                )
            
            audit_access_granted(user.id, resource_type)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@require_phi_access("diagnoses")
def get_patient_diagnoses(patient_id: str):
    # Only callable by roles with diagnosis access
    ...

会话管理

# Django / Flask session config for clinical systems
SESSION_CONFIG = {
    # Mandatory timeouts by context
    "public_terminal":         2 * 60,   # 2 min
    "clinical_workstation":   10 * 60,   # 10 min (2025 rule: max 15min)
    "mobile_health_app":       5 * 60,   # 5 min
    "admin_console":           5 * 60,   # 5 min
    
    "secure": True,           # HTTPS only
    "httponly": True,         # No JS access
    "samesite": "strict",     # CSRF protection
}

# MFA — mandatory under 2025 HIPAA Security Rule updates
MFA_CONFIG = {
    "required_for_phi": True,
    "allowed_methods": ["totp", "webauthn"],  # Authenticator app or hardware key
    # SMS NOT recommended — SIM swap attacks
    "account_lockout_attempts": 5,
    "lockout_duration_minutes": 30,
}

API 设计:FHIR + OAuth 2.0

# FastAPI example — FHIR R4 compliant patient endpoint
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi.security import OAuth2AuthorizationCodeBearer

oauth2_scheme = OAuth2AuthorizationCodeBearer(
    authorizationUrl="https://auth.yourapp.com/authorize",
    tokenUrl="https://auth.yourapp.com/token",
)

@app.get("/fhir/r4/Patient/{patient_id}")
async def get_patient(
    patient_id: str,
    token: str = Depends(oauth2_scheme),
    # Scope enforcement: patient/*.read
    _scopes = Security(verify_scopes, scopes=["patient/*.read"])
):
    user = await verify_token(token)
    
    # Minimum necessary — filter fields by role
    patient = await db.get_patient(patient_id)
    filtered = apply_minimum_necessary(patient, user.role)
    
    # Audit every access
    await audit_log(user.id, PHIAction.VIEW, "Patient", patient_id)
    
    return filtered

# Rate limiting for PHI endpoints
from slowapi import Limiter
limiter = Limiter(key_func=get_remote_address)

@app.get("/fhir/r4/Patient/{patient_id}")
@limiter.limit("60/minute")  # Per authenticated user
async def get_patient(...): ...

@app.post("/bulk-export")
@limiter.limit("2/hour")     # Bulk exports need approval workflow
async def bulk_export(...): ...

开发/测试环境中的去标识化

# NEVER use real PHI in non-production — this is a reportable violation
from faker import Faker
import hashlib

fake = Faker()

def deidentify_record(record: dict, deterministic_salt: str) -> dict:
    """
    Safe Harbor de-identification.
    Deterministic tokenization preserves referential integrity.
    """
    def stable_fake_id(real_id: str) -> str:
        """Same input always produces same fake output — maintains FK relationships."""
        hash_val = hashlib.sha256(f"{deterministic_salt}:{real_id}".encode()).hexdigest()
        return f"TEST-{hash_val[:12].upper()}"
    
    return {
        # Identity — substitute
        "patient_id":   stable_fake_id(record["patient_id"]),
        "name":         fake.name(),
        "ssn":          None,                                  # SUPPRESSED entirely
        "email":        fake.email(),
        "phone":        fake.phone_number(),
        
        # Dates — year only (Safe Harbor)
        "dob":          f"{record['dob'].year}-01-01",
        "admission_date": f"{record['admission_date'].year}-01-01",
        
        # Geography — first 3 ZIP digits only
        "zip":          record["zip"][:3] + "XX",
        "address":      None,                                  # SUPPRESSED
        
        # Clinical — can retain (health data without identifiers isn't PHI)
        "diagnosis_codes": record["diagnosis_codes"],
        "procedure_codes": record["procedure_codes"],
        "medications":     record["medications"],
    }

BAA 检查清单 — 处理任何 PHI 前签署

AWS (sign via AWS Artifact → Agreements):
  ✅ EC2, ECS, EKS, Lambda
  ✅ RDS, Aurora, DynamoDB, ElastiCache
  ✅ S3, EBS, EFS
  ✅ CloudTrail, CloudWatch, GuardDuty
  ✅ KMS, Secrets Manager
  ✅ Cognito, WAF, ALB
  ✅ SES (with restrictions), SNS (with restrictions)

Third-party vendors requiring BAAs:
  □ Auth provider (Auth0, Cognito)
  □ APM/logging (Datadog, New Relic — both offer BAAs)
  □ Error tracking (Sentry — offers BAA on enterprise plans)
  □ Email provider (SendGrid, SES — for appointment reminders)
  □ Support tools (Zendesk, Intercom — if handling patient queries)
  □ Analytics (avoid GA for PHI flows — use Mixpanel with BAA)
  □ AI/ML vendors (OpenAI, Anthropic — if processing PHI)

⚠️  MISSING BAA = direct HIPAA violation, even if data never breaches.
    Median penalty for missing BAA: $100,000–$1.9M

代码审查检查清单

在任何 PR 涉及 PHI 数据路径前,请确认:

PHI Exposure:
  □ No PHI in log statements (info, debug, error, warn)
  □ No PHI in error messages returned to clients
  □ No PHI in URL path parameters (use POST body)
  □ No PHI in S3 object keys or resource tags
  □ No PHI in CloudWatch metric names or dimensions

Encryption:
  □ All PHI at rest uses AES-256 / KMS
  □ All PHI in transit uses TLS 1.2+ (1.3 preferred)
  □ No PHI in environment variables (use Secrets Manager)
  □ No hardcoded credentials or API keys

Access Control:
  □ Minimum necessary access enforced at API layer
  □ Role check before PHI retrieval, not after
  □ Every PHI access produces an audit log entry
  □ No shared service accounts touching PHI

Session Security:
  □ Session timeout configured per environment
  □ MFA enforced for all PHI-touching roles
  □ Tokens expire within 15-60 minutes
  □ Refresh tokens rotate on use

Dev/Test:
  □ No real PHI in unit tests or integration tests
  □ No real PHI in seed data or fixtures
  □ No real PHI in CI/CD logs

创始人专用:上线准备检查清单

完整时间表请参阅 references/founder-hipaa-roadmap.md。关键节点:

与受监管实体开展首次试点前:

  • 已签署 AWS BAA
  • 已与所有供应商签署 BAA
  • 隐私政策和服务条款已由医疗法律顾问审核
  • 已记录风险分析(OCR 指出的首要缺陷)
  • 已验证静态和传输中的加密
  • 审计日志已发送至受 WORM 保护的存储

首批 100 名患者前:

  • 已完成渗透测试
  • 已编写并测试事件响应计划
  • 已记录员工培训情况(所有接触 PHI 的员工)
  • 已准备好供客户使用的业务伙伴协议模板

持续进行:

  • 每 6 个月进行一次漏洞扫描
  • 每 12 个月进行一次渗透测试
  • 每年或重大变更后审查风险分析
  • 所有文档至少保留 6 年

快速参考:关键数值

要求数值
静态加密AES-256
TLS 最低版本1.2(推荐 1.3)
密码哈希Argon2id 或 bcrypt ≥10 轮
会话超时(临床)10-15 分钟
账号锁定阈值3-6 次尝试
锁定时长15-30 分钟
审计日志保留期6 年
备份保留期6 年(州法律可能要求更长时间)
漏洞扫描频率每 6 个月
渗透测试频率每 12 个月
违规通知60 天内通知 HHS 和受影响个人
每类最高罚款每年 210 万美元

AWS 服务详细列表、架构模式和创始人时间表,请参阅 references/ 目录。

评论

支持 Markdown