Os Logs de Auditoria no Node.js registram ações importantes para responder quem fez o quê, quando, em qual recurso e com qual resultado. Diferentemente de logs operacionais, que ajudam a diagnosticar falhas, a auditoria precisa preservar uma trilha confiável de alterações de acesso, configurações, pagamentos, exportações e operações administrativas.
Uma trilha útil não deve armazenar senhas, tokens ou conteúdo sensível desnecessário. Ela precisa ser estruturada, resistente a alterações, associada ao tenant e protegida por retenção e acesso restrito. Eventos de auditoria também não podem desaparecer quando o serviço de logs está temporariamente indisponível.
Neste guia, você aprenderá a modelar eventos, registrar mudanças, proteger integridade, usar outbox, definir retenção, consultar com segurança, implementar alertas e testar a trilha.
O que é log de auditoria?
Auditoria registra eventos relevantes para segurança, conformidade e investigação. A OWASP Logging Cheat Sheet apresenta práticas de logging seguro. A publicação NIST SP 800-92 descreve gestão de logs de segurança.
Para logs operacionais, consulte Logs com Pino no Node.js. Para autorização, veja RBAC no Node.js e ABAC no Node.js.
Eventos que devem ser auditados
- login e logout relevantes;
- falhas de autenticação de alto risco;
- ativação e remoção de MFA;
- mudança de senha ou e-mail;
- criação e revogação de tokens;
- alteração de roles e permissions;
- impersonação por suporte;
- exportação e exclusão de dados;
- mudanças de cobrança;
- alterações de configuração;
- operações administrativas;
- acesso a dados altamente sensíveis.
Evento estruturado
{
"eventId": "...",
"eventType": "member.role_changed",
"occurredAt": "2026-08-28T12:00:00.000Z",
"actor": {
"type": "user",
"id": "user-42"
},
"tenantId": "tenant-8",
"target": {
"type": "membership",
"id": "membership-91"
},
"action": "update",
"result": "success",
"changes": {
"role": {
"from": "viewer",
"to": "admin"
}
},
"requestId": "...",
"ipAddress": "...",
"userAgent": "..."
}Campos essenciais
- ID único;
- tipo do evento;
- horário do servidor;
- ator;
- tenant;
- alvo;
- ação;
- resultado;
- mudanças relevantes;
- request ID;
- origem, quando necessária.
Ator humano e serviço
O ator pode ser usuário, serviço, job ou administrador de suporte:
actorType: 'user' | 'service' | 'job' | 'support'Não atribua uma ação automática ao usuário apenas porque o job começou a partir de uma requisição antiga. Registre também o causador original quando útil.
Antes e depois
Para mudanças de configuração, registre valores anteriores e novos, mas filtre segredos:
changes: {
logLevel: { from: 'info', to: 'debug' },
apiKey: { from: '[REDACTED]', to: '[REDACTED]' }
}Não registre senhas
Nunca armazene senha, código TOTP, recovery code, access token, refresh token, cookie ou chave privada.
Dados pessoais
Registre apenas o necessário. IP e user agent podem ser dados pessoais e precisam de finalidade, retenção e controles.
Auditoria versus log comum
- Log operacional: pode ser amostrado, rotacionado rapidamente e focado em diagnóstico.
- Auditoria: não deve ser amostrada, possui retenção definida e exige integridade.
Tabela PostgreSQL
CREATE TABLE audit_events (
id UUID PRIMARY KEY,
tenant_id UUID,
event_type TEXT NOT NULL,
actor_type TEXT NOT NULL,
actor_id TEXT,
target_type TEXT,
target_id TEXT,
result TEXT NOT NULL,
payload JSONB NOT NULL,
occurred_at TIMESTAMPTZ NOT NULL,
recorded_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_audit_tenant_time
ON audit_events (tenant_id, occurred_at DESC);Append-only
A role da aplicação deve possuir INSERT e SELECT controlado, mas não UPDATE ou DELETE no período de retenção.
Não permita edição pela API
Uma rota administrativa não deve “corrigir” um evento. Se algo está incorreto, grave um novo evento de correção ou anotação.
Transação com o negócio
await withTransaction(pool, async client => {
await changeMemberRole(client, input);
await insertAuditEvent(client, auditEvent);
});A alteração e a auditoria confirmam juntas.
Outbox
Quando a auditoria vai para outro sistema, grave uma mensagem de outbox na mesma transação. Consulte Outbox Pattern no Node.js.
Não dependa de envio síncrono remoto
Se a API externa de auditoria falha, não mantenha locks do banco esperando. Persistência local ou outbox garante entrega posterior.
Falha na auditoria
Para operações críticas, se não for possível persistir o evento localmente, a operação deve falhar junto com a transação. Para eventos de baixo risco, defina uma política explícita.
Integridade por hash
Uma cadeia de hashes pode evidenciar alteração:
hash = SHA256(
previousHash + canonicalEventJson
)Armazene o hash anterior e o atual. Isso detecta edição ou remoção dentro da sequência, mas não substitui controle de acesso.
Canonicalização
JSON precisa de ordenação e serialização determinística antes do hash. Caso contrário, objetos equivalentes geram valores diferentes.
Assinatura digital
Assinar lotes ou checkpoints com chave protegida oferece prova mais forte. Mantenha a chave fora do banco auditado.
Armazenamento imutável
Object storage com retenção WORM ou um sistema dedicado pode proteger arquivos exportados. Configure políticas e contas separadas.
Separação de responsabilidades
Administradores da aplicação não devem conseguir apagar silenciosamente a trilha. Use permissões e contas distintas.
Multi-tenancy
Eventos precisam de tenant, e consultas devem filtrar organização. Um administrador local não pode ler auditoria de outro tenant.
Row-Level Security
RLS pode proteger a tabela por tenant. Consulte Row-Level Security no Node.js.
Auditoria global
Eventos de plataforma, como criação de tenant ou impersonação, podem não pertencer a um único tenant. Use um escopo explícito.
Request ID e trace ID
Esses identificadores conectam auditoria a logs e traces. Não substituem o event ID.
Horário confiável
Use o relógio do servidor e UTC. Sincronize hosts com serviço de tempo e registre recorded_at separadamente de occurred_at quando eventos chegam atrasados.
Resultado da ação
Audite sucessos e falhas relevantes:
result: 'success' | 'denied' | 'failed'Uma tentativa negada de escalada de privilégio é importante.
Autorização negada
Não registre todas as respostas 403 como auditoria de alto valor. Selecione operações sensíveis para evitar ruído.
Impersonação
Registre o administrador real, usuário impersonado, motivo, início, fim e ações durante a sessão.
Exportação de dados
Registre quem solicitou, filtros, quantidade aproximada, destino e expiração do arquivo. Não copie o conteúdo para o log.
Exclusão
Registre o pedido, aprovação, escopo e resultado. A trilha pode precisar preservar metadados sem manter os dados excluídos.
Retenção
Defina prazos por tipo de evento e requisito. Retenção infinita aumenta custo e risco de privacidade.
Particionamento
Tabelas grandes podem ser particionadas por mês. Isso simplifica retenção e consultas por período.
Arquivamento
Mova partições antigas para armazenamento protegido e mantenha um índice de localização.
Consulta administrativa
Ofereça filtros por período, ator, ação, alvo e resultado, com paginação por cursor.
Não permita query arbitrária
Use filtros predefinidos e limites. Uma pesquisa sem restrição pode sobrecarregar o banco ou expor dados.
Paginação
Consulte Paginação em APIs Node.js para cursor estável.
Exportação da auditoria
Execute em job, gere arquivo cifrado, use URL de curta duração e audite a própria exportação.
Alertas
Eventos que podem gerar alerta:
- admin concedido;
- MFA removido;
- muitas falhas de login;
- impersonação iniciada;
- exportação em massa;
- política de segurança alterada;
- chave de API criada;
- auditoria indisponível.
Correlação
Um alerta deve agrupar eventos relacionados e fornecer contexto, não disparar por cada linha individual.
Logs da própria auditoria
Monitore falha de inserção, backlog da outbox, atraso, erros de assinatura e partições próximas do limite.
Métricas
- eventos por tipo;
- falhas de persistência;
- idade da fila;
- tempo de consulta;
- exportações;
- erros de integridade;
- volume armazenado.
Cardinalidade
Não use actor ID ou target ID como labels de Prometheus. Esses dados pertencem ao evento pesquisável.
Testes unitários
Teste sanitização, estrutura, campos obrigatórios e redaction.
Teste transacional
test('reverte mudança sem auditoria', async () => {
auditRepository.failNextInsert();
await assert.rejects(() =>
changeRole({ userId, role: 'admin' })
);
const membership = await findMembership(userId);
assert.notEqual(membership.role, 'admin');
});Teste de redaction
Inclua token, senha e recovery code em um objeto de entrada e confirme que não aparecem no evento.
Teste de isolamento
Um administrador do tenant A não pode consultar eventos do tenant B.
Teste de integridade
Altere um evento em uma cópia de teste e confirme que a cadeia de hashes falha.
Teste de outbox
Simule queda após commit e confirme que o relay publica o evento mais tarde.
Teste de retenção
Remova apenas partições expiradas e preserve eventos sujeitos a legal hold.
Erros comuns
- Auditoria em logger comum: eventos são amostrados ou perdidos.
- Registrar segredos: a trilha vira fonte de vazamento.
- Permitir UPDATE: histórico pode ser reescrito.
- Envio remoto dentro da transação: locks ficam abertos.
- Sem tenant: investigação e isolamento falham.
- Retenção infinita: custo e privacidade aumentam.
- Sem auditar o acesso à auditoria: consultas sensíveis ficam invisíveis.
Boas práticas
- Defina eventos relevantes.
- Use estrutura estável.
- Não registre segredos.
- Grave na mesma transação ou outbox.
- Mantenha append-only.
- Proteja integridade.
- Separe privilégios.
- Defina retenção.
- Audite consultas e exportações.
- Teste falhas e isolamento.
Conclusão
Os Logs de Auditoria no Node.js criam uma trilha confiável de ações sensíveis, permitindo investigar mudanças de acesso, configurações, exportações e operações administrativas.
Uma auditoria útil precisa ser transacional, estruturada, imutável e livre de segredos. Com outbox, controles por tenant, retenção e verificação de integridade, a aplicação mantém evidências confiáveis sem transformar o histórico em um novo risco de segurança e privacidade.




