Audit trail tamper-evident: hash-chain SHA-256
"Audit trail imutável" virou commodity de marketing. Tamper-evident com hash-chain é diferente: cada evento sela o anterior. Qualquer alteração se delata.
Vários eQMS dizem ter "audit trail imutável". A maioria entende isso como "tem audit trail, e a UI não deixa apagar". Mas se o administrador do banco tem acesso de escrita, ele pode apagar — e o auditor sabe disso.
Tamper-evident é outra categoria. Em vez de prometer que ninguém vai mexer, o sistema garante que se mexerem, fica óbvio. É a diferença entre uma porta com cadeado e uma porta com sensor.
O que é uma hash-chain
Hash-chain é uma técnica criptográfica simples: cada novo registro de audit trail contém o hash SHA-256 do registro anterior. Esse hash vira parte do conteúdo que vai ser hasheado pro próximo. Resultado: uma cadeia onde alterar qualquer evento no meio quebra todos os hashes a partir dali.
Estrutura conceitual de cada evento:
- timestamp UTC
- usuário
- ação (CREATE, UPDATE, APPROVE...)
- conteúdo (canonical JSON do estado relevante)
- hash do evento anterior
- hash deste evento = SHA-256(timestamp + usuário + ação + conteúdo + hash_anterior)
O hash do último evento é o "chain tip" — uma única string de 64 caracteres que representa toda a história. Mudar 1 byte em qualquer evento muda o chain tip.
Por que isso importa pro inspetor
O auditor não precisa confiar no fornecedor. Ele pode:
- Pegar uma amostra de eventos do audit trail
- Recalcular o SHA-256 com os mesmos dados
- Confirmar que o hash bate com o registrado
- Seguir a cadeia até o chain tip
Se houver mismatch, alguém alterou. Não dá pra esconder.
Canonical JSON: o detalhe que faz funcionar
O hash só é reproduzível se o input for canônico. Isso significa:
- Campos em ordem alfabética estável
- Sem espaços extras
- Encoding consistente (UTF-8)
- Floats representados de forma deterministic
- Especificação clara (ex: RFC 8785 JCS)
Sem isso, dois servidores podem gerar hashes diferentes pro mesmo conteúdo — e o auditor não consegue reproduzir.
O que isso NÃO resolve
Hash-chain não é mágica. Não resolve:
- Falsificação contemporânea: se o atacante tem acesso desde o início, ele cria a cadeia "limpa" mas com dados falsos
- Re-write completo: se atacante apaga TODOS os eventos e recria do zero, o chain tip muda mas se não houver baseline externa, ninguém percebe
- Eventos que não chegaram: hash só protege o que entrou na cadeia
Por isso a defesa completa exige: hash-chain + chain tip persistido em local separado (idealmente write-once) + revisão periódica do chain tip.
Como o NOAH faz
O NOAH mantém o chain tip numa tabela separada com Row-Level Security e GRANT restrito (write só pelo writer do audit, leitura ampla pra auditores). Periodicamente, o chain tip pode ser enviado pra serviço externo (S3 com Object Lock WORM, por exemplo) — assim mesmo um attacker com acesso total ao banco não consegue reescrever sem deixar rastro externo.
É o que faz a diferença entre "audit trail no DB" e "audit trail à prova de fornecedor". Veja também por que hash-chain é a evidência ALCOA+ real.
Part 11 §11.10(e) e a expectativa moderna
O Part 11 §11.10(e) exige audit trail "secure, computer-generated, time-stamped". A leitura moderna do FDA — particularmente depois das Warning Letters em data integrity — é que "secure" vai além de permissão. O auditor espera evidência de que não foi alterado, não promessa de que ninguém ia tentar.
Hash-chain entrega exatamente essa evidência.
Audit trail "imutável" depende de promessa do fornecedor. Audit trail tamper-evident com hash-chain SHA-256 depende de matemática. Auditor com calculadora consegue verificar.
Veja a hash-chain do NOAH ao vivo
Em 30 min mostramos o audit trail rodando, exportamos uma amostra, e você recalcula o hash junto pra ver a cadeia fechar.
Agendar demo