Padrões de Conformidade PHI/PII para Saúde
Padrões para proteger dados de pacientes, clínicos e financeiros em aplicações de saúde. Aplicáveis a HIPAA (EUA), DISHA (Índia), GDPR (UE) e proteção geral de dados de saúde.
Quando Usar
- Construir qualquer recurso que toque em prontuários de pacientes
- Implementar controle de acesso ou autenticação para sistemas clínicos
- Projetar esquemas de banco de dados para dados de saúde
- Construir APIs que retornam dados de pacientes ou clínicos
- Implementar trilhas de auditoria ou registro de logs
- Revisar código em busca de vulnerabilidades de exposição de dados
- Configurar Segurança em Nível de Linha (RLS) para sistemas de saúde multi-instituição
Como Funciona
A proteção de dados de saúde opera em três camadas: classificação (o que é sensível), controle de acesso (quem pode ver) e auditoria (quem viu).
Classificação de Dados
PHI (Informações Protegidas de Saúde) — qualquer dado que possa identificar um paciente E esteja relacionado à sua saúde: nome do paciente, data de nascimento, endereço, telefone, e-mail, números de identificação nacionais (SSN, Aadhaar, número NHS), números de prontuário, diagnósticos, medicamentos, resultados de exames, imagens, detalhes de apólices e sinistros, registros de consultas e internações, ou qualquer combinação dos itens acima.
PII (Informações Pessoalmente Identificáveis não sensíveis a pacientes) em sistemas de saúde: dados pessoais de clínicos/funcionários, tabelas de honorários médicos e valores de pagamento, salários e dados bancários de funcionários, informações de pagamento a fornecedores.
Controle de Acesso: Segurança em Nível de Linha
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
-- Escopo de acesso por instituição
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')
));
-- Log de auditoria: apenas inserção (à prova de adulteração)
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);
Trilha de Auditoria
Todo acesso ou modificação de PHI deve ser registrado:
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;
}
Vetores Comuns de Vazamento
Mensagens de erro: Nunca inclua dados que identifiquem pacientes em mensagens de erro enviadas ao cliente. Registre os detalhes apenas no servidor.
Saída de console: Nunca registre objetos completos de pacientes. Use identificadores internos opacos (UUIDs) — não números de prontuário, IDs nacionais ou nomes.
Parâmetros de URL: Nunca coloque dados que identifiquem pacientes em strings de consulta ou segmentos de caminho que possam aparecer em logs ou no histórico do navegador. Use apenas UUIDs opacos.
Armazenamento do navegador: Nunca armazene PHI em localStorage ou sessionStorage. Mantenha PHI apenas em memória, buscando sob demanda.
Chaves de função de serviço: Nunca use a chave service_role no código do lado do cliente. Sempre use a chave anônima/pública e deixe o RLS aplicar o controle de acesso.
Logs e monitoramento: Nunca registre prontuários completos de pacientes. Use apenas IDs de registro opacos (não números de prontuário). Sanitize stack traces antes de enviar para serviços de rastreamento de erros.
Marcação de Esquema de Banco de Dados
Marque colunas PHI/PII no nível do esquema:
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';
Lista de Verificação para Implantação
Antes de cada implantação:
- Sem PHI em mensagens de erro ou stack traces
- Sem PHI em console.log/console.error
- Sem PHI em parâmetros de URL
- Sem PHI em armazenamento do navegador
- Sem chave service_role no código do cliente
- RLS habilitado em todas as tabelas com PHI/PII
- Trilha de auditoria para todas as modificações de dados
- Tempo limite de sessão configurado
- Autenticação de API em todos os endpoints de PHI
- Isolamento de dados entre instituições verificado
Exemplos
Exemplo 1: Tratamento de Erros Seguro vs Inseguro
// RUIM — vaza PHI no erro
throw new Error(`Paciente ${patient.name} não encontrado em ${patient.facility}`);
// BOM — erro genérico, detalhes registrados no servidor com IDs opacos apenas
logger.error('Falha na busca do paciente', { recordId: patient.id, facilityId });
throw new Error('Registro não encontrado');
Exemplo 2: Política RLS para Isolamento Multi-Instituição
-- Médico da Instituição A não consegue ver pacientes da Instituição B
CREATE POLICY "isolamento_instituicao"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments WHERE user_id = auth.uid()
));
-- Teste: login como medico-instituicao-a, consultar pacientes da instituicao-b
-- Esperado: 0 linhas retornadas
Exemplo 3: Registro Seguro de Logs
// RUIM — registra dados identificáveis do paciente
console.log('Processando paciente:', patient);
// BOM — registra apenas o ID de registro interno opaco
console.log('Processando registro:', patient.id);
// Nota: mesmo patient.id deve ser um UUID opaco, não um número de prontuário