---
title: "O conflito entre minimização da LGPD e trilha de auditoria em prontuário eletrônico"
author: "Pedro Dalben"
date: "2026-10-08T11:02:57Z"
category: "Arquitetura & CTO"
reading_time: "7 min"
canonical: "https://pedrodalben.com.br/blog/o-conflito-entre-minimizacao-da-lgpd-e-trilha-de-auditoria-em-prontuario-eletronico"
---

# O conflito entre minimização da LGPD e trilha de auditoria em prontuário eletrônico

> Como equilibrar retenção de logs e minimização de dados sensíveis em prontuários eletrônicos usando PostgreSQL e Rails sem criar passivos.

**Autor:** Pedro Dalben (CTO no Integrar Plus)  
**Publicado em:** 08 de October de 2026  
**URL Canônica Oficial:** [https://pedrodalben.com.br/blog/o-conflito-entre-minimizacao-da-lgpd-e-trilha-de-auditoria-em-prontuario-eletronico](https://pedrodalben.com.br/blog/o-conflito-entre-minimizacao-da-lgpd-e-trilha-de-auditoria-em-prontuario-eletronico)  

---


A maioria das discussões sobre LGPD em sistemas de saúde trava em uma contradição prática que ninguém quer admitir no código. De um lado, a equipe jurídica exige minimização rigorosa e direito ao esquecimento, defendendo que qualquer dado pessoal dispensável saia do banco imediatamente. Do outro lado, conselhos profissionais de classe e normas sanitárias exigem que o histórico clínico e os acessos fiquem intactos por décadas, sob pena de processo ético ou judicial contra a clínica.

Quando essa conversa desce para a camada de persistência, surgem dois extremos problemáticos.

O primeiro grupo trata a trilha de auditoria como um mero dump de eventos em uma tabela genérica do PostgreSQL ou em um bucket S3. Eles serializam o `payload` inteiro do ActiveRecord em JSON a cada leitura ou alteração. Acreditam que estão seguros porque "tudo está registrado". O problema dessa abordagem é que a tabela de auditoria se torna um vazamento permanente de dados sensíveis. Se um usuário pede a exclusão de um telefone, endereço ou observação administrativa, o registro original na tabela principal é limpo, mas uma cópia em texto puro continua vivendo para sempre em trinta linhas de log espalhadas pelo banco de dados.

O segundo grupo comete o erro oposto. Com medo de manter dados sensíveis em duplicidade, confia apenas em colunas de controle comuns como `updated_at` e `updated_by_id`, ou aplica um `soft delete` ingênuo com sobrescrita de campos. Quando ocorre um incidente de segurança ou uma suspeita de vazamento interno por um operador autorizado, o sistema não consegue responder quem visualizou a tela de evolução clínica em uma terça-feira às três da manhã. Não existe trilha de leitura, apenas o estado atual da linha.

Ambas as posições estão erradas. A auditoria de prontuário eletrônico não pode ser um espelho de dados, mas sim um registro de intenção e autoria de leitura.

### A anatomia do que realmente precisa ser auditado

Auditoria em saúde precisa cobrir tanto operações de escrita quanto eventos de leitura (o infame `SELECT`). Em sistemas convencionais, raramente registramos quem leu um registro para evitar gargalos de I/O. Em prontuários, contudo, a invasão de privacidade quase sempre ocorre por curiosidade ou bisbilhotice interna sem nenhuma alteração no cadastro.

Para não explodir o armazenamento e não duplicar dados sensíveis dentro da trilha, a regra de ouro que adoto na modelagem é separar metadados de acesso do conteúdo clínico em si:

```sql
CREATE TABLE medical_record_access_logs (
    id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    patient_id bigint NOT NULL,
    medical_record_id bigint NOT NULL,
    user_id bigint NOT NULL,
    action varchar(20) NOT NULL, -- read, update, export, sign
    ip_address inet NOT NULL,
    user_agent text,
    accessed_at timestamptz NOT NULL DEFAULT clock_timestamp()
);

CREATE INDEX idx_record_access_logs_patient_lookup 
ON medical_record_access_logs (patient_id, accessed_at DESC);
```

Perceba que essa tabela não armazena o diagnóstico, a prescrição médica ou o nome do paciente. Ela armazena chaves estrangeiras, a operação executada e o contexto temporal e de rede. Se o paciente solicitar a exclusão de dados puramente cadastrais amparados pela lei, os identificadores numéricos continuam preservando a integridade legal do histórico de acesso sem violar a retenção mínima.

### O perigo de auditar pelo ActiveRecord

Um erro comum em projetos Ruby on Rails é pendurar essa auditoria em callbacks de modelo, como `after_find` ou gems que interceptam ciclos de vida do ActiveRecord sem critério.

Colocar lógica de log em `after_find` destrói a performance da aplicação. Qualquer rotina em segundo plano, consulta de listagem ou exportação em lote dispara centenas de inserções desnecessárias. Além disso, o modelo muitas vezes não tem a menor ideia de quem é o usuário atual logado, a menos que você recorra a variáveis globais de thread (`CurrentAttributes`), o que frequentemente gera sujeira quando tarefas do Sidekiq reutilizam a mesma thread.

A auditoria de acesso pertence à camada de serviço ou ao controller, exatamente onde o contexto da requisição HTTP e a intenção do operador são explícitos:

```ruby
class MedicalRecords::ShowService
  def initialize(patient:, current_user:, request_metadata:)
    @patient = patient
    @current_user = current_user
    @request_metadata = request_metadata
  end

  def call
    record = @patient.medical_record
    
    MedicalRecordAccessLog.create!(
      patient_id: @patient.id,
      medical_record_id: record.id,
      user_id: @current_user.id,
      action: "read",
      ip_address: @request_metadata[:ip],
      user_agent: @request_metadata[:user_agent],
      accessed_at: Time.current
    )

    record
  end
end
```

Se o volume de acessos for muito alto, persistir de forma síncrona dentro da transação principal pode degradar a latência percebida pelo médico no consultório. Uma alternativa viável é enfileirar o log ou usar inserções diretas em lote via `insert_all` após o ciclo da requisição terminar. Mas eu hesito em jogar logs de auditoria jurídica em filas que podem falhar silenciosamente ou perder mensagens se a infraestrutura cair. Gravar direto no PostgreSQL local, mantendo a escrita curta e enxuta, continua sendo a escolha mais previsível para servidores próprios.

### Imutabilidade no PostgreSQL

A LGPD e as normas sanitárias convergem em um ponto específico: a trilha de auditoria precisa ser confiável e resistente à adulteração. Se um administrador do banco puder alterar um log com um simples comando `UPDATE` para acobertar um acesso indevido, a trilha perde a validade pericial.

Em vez de contratar ferramentas externas caras para garantir integridade de log, o próprio PostgreSQL resolve isso com permissões restritas e triggers de bloqueio:

```sql
CREATE OR REPLACE FUNCTION prevent_audit_tampering()
RETURNS TRIGGER AS $$
BEGIN
    RAISE EXCEPTION 'Registros de auditoria medica sao imutaveis e nao podem ser alterados ou deletados.';
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_protect_medical_access_logs
BEFORE UPDATE OR DELETE ON medical_record_access_logs
FOR EACH ROW
EXECUTE FUNCTION prevent_audit_tampering();
```

Essa barreira impede que erros de aplicação ou comandos acidentais apaguem linhas. Naturalmente, um usuário com privilégios de `superuser` ainda pode desativar o gatilho se quiser fraudar o sistema, mas para isso o usuário da aplicação que o Rails utiliza jamais deve rodar como dono da tabela ou com privilégios elevados. O isolamento de roles no banco é o mecanismo mais negligenciado em arquiteturas menores.

### Retenção e particionamento

Existe ainda a questão do prazo. Prontuários médicos no Brasil possuem prazos legais de guarda de até vinte anos segundo o Conselho Federal de Medicina. Logs de acesso geral de conexão têm outros prazos no Marco Civil da Internet. Tratar tudo no mesmo saco cria tabelas gigantescas que sufocam os discos da VPS e inviabilizam rotinas de backup.

O caminho pragmático é particionar a tabela de logs por data (mensal ou anual) nativamente no PostgreSQL. Quando o período legal de um bloco expira, descartar uma partição inteira com `DROP TABLE` não gera fragmentação de disco, não trava a tabela inteira e não sobrecarrega o processo de autovacuum.

Minimizar dados não significa apagar o que é necessário para a segurança jurídica do negócio. Significa registrar apenas o estritamente necessário para comprovar autoria e contexto, sem carregar o conteúdo sensível a reboque em tabelas secundárias. Quem tenta auditar salvando tudo cria um passivo invisível; quem audita de menos descobre o valor do log no primeiro processo judicial.
