Skip to main content

Verificar integridade da cadeia de auditoria — API

Recalcula e confere a cadeia de hash de um ou mais escopos de auditoria (um tenant, ou o escopo __system__ de eventos sem tenant), para provar que nenhuma entrada persistida foi alterada, removida ou inserida fora de ordem desde que foi gravada. É a rota que responde "esta trilha ainda é confiável?" — não lista entradas, só atesta a cadeia.

Funcionamento​

  1. JwtAuthenticationGuard + AuthorizationGuard exigem audit:read no escopo tenant-list (mesma exigência da rota geral de listagem — por isso um leitor restrito só a unidades, sem nenhum tenant concedido, é recusado aqui mesmo que consiga listar logs de sua unidade).
  2. O parâmetro scope (um tenantId ou __system__) é resolvido para a lista de escopos que o chamador pode verificar: se scope for omitido ou *, verifica todos os escopos que existem e que o chamador pode acessar (com __system__ sempre verificado primeiro, quando presente e acessível); se um escopo específico for pedido fora do que o chamador acessa, a verificação roda sobre uma lista vazia (sucesso vazio, não erro).
  3. Para cada escopo, a cadeia inteira é percorrida em páginas de 1000 linhas, em ordem de seq crescente, recalculando o hash de cada linha a partir do seu conteúdo e do hash anterior.
  4. Ao final da cadeia, o checkpoint assinado do escopo é conferido: a assinatura HMAC precisa bater, e o par (hash da última linha, contagem de entradas) do checkpoint precisa coincidir com o que foi recalculado.
  5. Se qualquer escopo verificado apresentar uma quebra, a chamada inteira falha com 409 — a resposta de sucesso (200) só existe quando todos os escopos verificados estão íntegros.

Endpoints​

MétodoRotaDescrição
GET/v1/audit-logs/integrityVerifica a cadeia de hash de um escopo, ou de todos os escopos acessíveis

Versão: v1

Swagger: Audit · Rota (Dev): http://localhost:3001/v1/audit-logs/integrity

Permissões​

RotaGuardsPerfil / escopo exigido
GET /audit-logs/integrityJwtAuthenticationGuard, AuthorizationGuardaudit:read no escopo tenant-list (mesmo requisito da listagem geral); um administrador de plataforma pode verificar explicitamente o escopo __system__

Um leitor restrito a uma unidade específica (sem nenhum tenant concedido em nível de tenant-list) é recusado com 403 FORBIDDEN_ACTION, mesmo tendo audit:read — a integridade é sempre uma operação de tenant, nunca de unidade isolada.

Headers​

HeaderObrigatórioDescrição
AuthorizationSimBearer <access_token>

Path parameters​

Nenhum.

Query parameters​

NomeTipoObrigatórioDefaultDescrição
scopestring (até 64)Não*Um tenantId específico, __system__, ou * para verificar todos os escopos acessíveis. Parâmetro repetido é tratado como se tivesse sido omitido (default *).

Body​

Não se aplica — a rota é GET.

Response​

200 — todos os escopos verificados estão íntegros (AuditIntegrityResponseDto):

json
{
"data": [
{
"scope": "02ea27af-05c0-4af6-be75-8cd17bdf6340",
"verified": true,
"checkedCount": 587
},
{
"scope": "__system__",
"verified": true,
"checkedCount": 12
}
]
}

Quando há quebra, a rota não devolve 200 com verified: false — ela lança um erro 409 (ver Erros) assim que encontra o primeiro escopo quebrado, na ordem determinística (__system__ primeiro, depois os demais em ordem alfabética). Escopos verificados com sucesso antes do primeiro quebrado não aparecem na resposta de erro.

Erros​

Classe de erroerrorCodeStatusQuando ocorre
UnauthenticatedErrorUNAUTHENTICATED401Sem token ou token inválido
ForbiddenActionAUTHORIZATION_CLAIM_UNAVAILABLE403Ator sem claim de autorização
ForbiddenActionFORBIDDEN_ACTION403Sem audit:read no escopo tenant-list
AuditChainForkErrorAUDIT_CHAIN_FORK409O primeiro escopo quebrado tem um elo rompido (previousHash da linha não bate com o hash anterior — inclui o caso de uma linha no meio da cadeia ter sido removida, ou a primeira linha alegar um predecessor inexistente)
AuditChainTamperedErrorAUDIT_CHAIN_TAMPERED409O primeiro escopo quebrado tem qualquer outro tipo de violação: hash ausente, hash recalculado diferente do armazenado, checkpoint ausente para uma cadeia não vazia, checkpoint com assinatura forjada, ou checkpoint que diverge da cadeia recalculada (cauda apagada)

Regras de negócio​

IDRegraComportamento esperado
RN-01Verificação falha fechada (fail closed)Qualquer quebra observável interrompe a resposta com 409; não existe um "meio-termo" de sucesso parcial
RN-02broken_link vira AUDIT_CHAIN_FORK; todo o resto vira AUDIT_CHAIN_TAMPEREDmissing_hash, hash_mismatch, missing_checkpoint, forged_checkpoint e truncated são todos reportados como adulteração; só o elo rompido é reportado como fork
RN-03Escopo vazio sem checkpoint é considerado íntegroUma cadeia que nunca recebeu entradas (sem linhas e sem checkpoint) verifica como verified: true, checkedCount: 0
RN-04Escopo com linhas mas sem checkpoint é uma quebraToda cadeia não vazia deve ter um checkpoint avançado; a ausência é missing_checkpoint
RN-05* nunca revela escopos fora do acesso do chamadorA verificação "todos os escopos" é sempre filtrada pelos tenants que o chamador acessa; um tenant não vê o escopo __system__ nem o de outro tenant
RN-06Pedir um escopo específico fora do acesso do chamador não é erroA resposta é um sucesso vazio (data: []), não 403 nem 409 — evita confirmar/negar a existência do escopo para quem não tem acesso
RN-07A ordem de verificação é determinística__system__ primeiro (quando presente), depois os demais escopos em ordem alfabética — importante porque só o primeiro breach encontrado é reportado

Compliance​

Órgão / normaExigênciaComo a rota atende
LGPD / HIPAA / ANVISA (trilha íntegra e auditável)garantir que o histórico não foi adulterado retroativamentecadeia de hash + checkpoint assinado por HMAC, verificável sob demanda; qualquer adulteração observável falha a chamada em vez de mascará-la

Esta capacidade não existia no legado descrito nos cards de auditoria (trilha em Mongo, sem hash-chain, com entradas apagáveis) — é uma melhoria confirmada no código atual.

Variáveis de ambiente​

VariávelUsoObrigatória
AUDIT_HMAC_ACTIVE_KEY_ID / AUDIT_HMAC_KEYSanel de chaves HMAC usado para assinar e verificar os checkpointsSim em produção (há fallback de desenvolvimento apenas quando NODE_ENV é local/test)

Tempo médio de resposta​

A confirmar — responsável: time de Audit; data: 24/09/2026. O custo cresce com o tamanho da cadeia verificada (paginação de 1000 linhas por vez); não há medição publicada.

Requisitos não funcionais​

RequisitoDefinição
IdempotênciaSim — leitura pura, não altera estado
PaginaçãoNão se aplica à resposta (um item por escopo verificado); internamente a cadeia é lida em páginas de 1000 linhas
Rate limitAplicado no nível do microsserviço; sem limite específico documentado para esta rota
CacheNão
AuditoriaNão se aplica

Relacionado​