Em 2016, um funcionário de um grande banco brasileiro transferiu R$ 3,2 milhões em operações fracionadas para contas de terceiros ao longo de três meses. A fraude foi detectada não pelo monitoramento em tempo real — mas por uma auditoria trimestral que revelou o padrão. A investigação dependeu inteiramente dos logs de transação do sistema: quem iniciou cada operação, de qual terminal, em qual horário, com qual aprovação. Sem esses logs, não haveria rastreabilidade, não haveria prova, e potencialmente não haveria responsabilização. O audit log não preveniu a fraude — mas foi o que tornou a investigação e a recuperação possíveis.
Audit logs são registros imutáveis de ações executadas em um sistema — quem fez o quê, quando, sobre qual recurso, com qual resultado. A palavra "imutável" é central: um audit log que pode ser modificado ou deletado pelo ator que realizou a ação não é um audit trail — é apenas um log. A distinção técnica entre logging operacional (para debugging e observabilidade) e audit logging (para rastreabilidade e compliance) é frequentemente negligenciada em sistemas menores, com consequências que aparecem somente quando algo dá errado ou quando uma auditoria externa as revela.
Este conceito cobre o que um audit log deve registrar, como protegê-lo contra adulteração, como navegar as tensões entre retenção de dados de audit e privacidade (LGPD, GDPR), e o que auditores de SOC 2, PCI DSS, e ISO 27001 tipicamente verificam quando avaliam sistemas.
O que um audit log deve registrar
A pergunta de design de um audit log é: "se algo der errado 6 meses a partir de hoje, o que você precisaria saber para investigar?". A resposta geralmente inclui:
- Quem: identificador do ator — user_id autenticado, service account, ou identificador de sistema externo. Nunca apenas o nome ou email (mutáveis) — o identificador estável do sistema de autenticação.
- O quê: a ação realizada — CREATE, READ, UPDATE, DELETE para operações de dados; LOGIN, LOGOUT, MFA_VERIFY para autenticação; APPROVE, REJECT, REVOKE para operações de autorização.
- Sobre o quê: o recurso afetado — tipo de entidade, identificador, e dados relevantes do estado anterior e posterior (para operações de mutação).
- Quando: timestamp em UTC com precisão de milissegundos. Nunca timestamp local — fuso horário introduz ambiguidade especialmente em sistemas distribuídos.
- De onde: IP de origem, user-agent, session_id, e request_id (para correlação com logs de aplicação).
- Resultado: sucesso, falha, e razão da falha. Tentativas de acesso negado são tão importantes de registrar quanto acessos bem-sucedidos.
// Estrutura de evento de audit log — exemplo em JSON
{
"id": "audit_01HXYZ123", // identificador único e imutável do evento
"timestamp": "2026-05-12T14:32:07.841Z", // UTC, milissegundos
"actor": {
"type": "user", // ou "service", "system"
"id": "user_abc123", // identificador estável do auth system
"email": "camila@empresa.com", // snapshot — email no momento da ação
"session_id": "sess_xyz789",
"ip": "177.42.33.101",
"user_agent": "Mozilla/5.0..."
},
"action": "document.delete", // namespace.verbo — consistente e queryável
"resource": {
"type": "document",
"id": "doc_456",
"snapshot": { // estado do recurso antes da ação
"title": "Contrato Q2",
"owner_id": "user_def456",
"status": "published"
}
},
"result": {
"status": "success", // ou "denied", "error"
"reason": null // mensagem de erro se status != success
},
"context": {
"request_id": "req_uvw012", // para correlação com APM/logs
"service": "documents-api",
"version": "2.3.1"
}
}
O snapshot do estado anterior (para deletes e updates) é frequentemente omitido por simplicidade mas é criticamente importante para investigação: "o documento foi deletado" é menos útil que "o documento de título 'Contrato Q2', no status 'published', pertencente a user_def456, foi deletado". Sem o snapshot, reconstruir o que existia antes requer outras fontes que podem não estar disponíveis.
Eventos de negócio que devem sempre gerar entradas no audit log: autenticação (login, logout, falha de login, MFA), gerenciamento de conta (criação, alteração de email/senha/papel, deleção), operações sobre dados sensíveis (PII, financeiro, médico), aprovações e rejeições de fluxos de negócio, e acesso negado a qualquer recurso. Operações de leitura de dados públicos geralmente não requerem audit; operações de leitura de dados sensíveis (prontuário médico, extrato financeiro, dados de outro usuário) sempre requerem.
Proteção contra adulteração — imutabilidade por design
Um audit log que o ator pode modificar não é evidência — é um documento que o réu escreveu. A proteção contra adulteração pode ser implementada em vários níveis:
Append-only storage: o storage do audit log aceita apenas INSERT, nunca UPDATE ou DELETE. Em PostgreSQL, isso é implementado com um trigger que rejeita operações de modificação:
-- Tabela de audit log append-only
CREATE TABLE audit_events (
id TEXT PRIMARY KEY DEFAULT ('audit_' || gen_random_uuid()::text),
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
actor_id TEXT NOT NULL,
actor_type TEXT NOT NULL,
action TEXT NOT NULL,
resource_id TEXT,
resource_type TEXT,
payload JSONB NOT NULL,
ip INET,
session_id TEXT
);
-- Trigger que impede UPDATE e DELETE
CREATE OR REPLACE FUNCTION prevent_audit_modification()
RETURNS TRIGGER AS $$
BEGIN
RAISE EXCEPTION 'Audit logs são imutáveis — modificação negada';
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_immutable
BEFORE UPDATE OR DELETE ON audit_events
FOR EACH ROW EXECUTE FUNCTION prevent_audit_modification();
-- Revoke para evitar contornar via superuser acidental
REVOKE UPDATE, DELETE ON audit_events FROM PUBLIC;
REVOKE TRUNCATE ON audit_events FROM PUBLIC;
Hash chaining: cada entrada inclui o hash da entrada anterior, formando uma cadeia onde qualquer modificação em uma entrada invalida todas as entradas subsequentes — similar a uma blockchain simplificada. O hash chain garante que, mesmo que um ator tenha acesso ao banco de dados, não pode modificar entradas antigas sem que a inconsistência seja detectável.
-- Hash chaining em PostgreSQL
CREATE TABLE audit_events_chained (
id BIGSERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
payload JSONB NOT NULL,
prev_hash TEXT, -- hash da entrada anterior
current_hash TEXT GENERATED ALWAYS AS ( -- hash desta entrada
encode(sha256(
(id::text || timestamp::text || payload::text || coalesce(prev_hash, ''))::bytea
), 'hex')
) STORED
);
-- Verificação da cadeia (detecta adulteração)
SELECT
id,
CASE
WHEN prev_hash IS NULL AND id = 1 THEN 'valid_genesis'
WHEN prev_hash = lag(current_hash) OVER (ORDER BY id) THEN 'valid'
ELSE 'CHAIN_BROKEN'
END as chain_status
FROM audit_events_chained
ORDER BY id;
Storage segregado: o audit log fica em um banco de dados ou sistema de storage separado, com acesso restrito — idealmente write-only para a aplicação (a aplicação pode inserir mas não ler ou modificar), com acesso de leitura apenas para ferramentas de compliance e times autorizados. Um sistema onde o comprometimento da aplicação não comprometeria o audit log é significativamente mais robusto.
LGPD e o direito ao esquecimento — a tensão com audit logs
A Lei Geral de Proteção de Dados (LGPD, Lei 13.709/2018, em vigor desde 2020) estabelece o direito do titular de solicitar a eliminação dos seus dados pessoais. O GDPR europeu tem o mesmo direito no Artigo 17. Mas a imutabilidade do audit log entra em tensão direta com esse direito: se o audit log registra que o usuário X fez a ação Y, e o usuário X solicita que seus dados sejam deletados, o que acontece com as entradas do audit log?
A tensão é resolvida por base legal. Tanto a LGPD (Artigo 16) quanto o GDPR (Artigo 17(3)) estabelecem exceções ao direito de eliminação quando os dados são necessários para: cumprimento de obrigação legal, exercício regular de direitos em processos judiciais, e proteção de legítimos interesses. Audit logs para fins de compliance, investigação de fraude, ou obrigação regulatória têm base legal para retenção mesmo após solicitação de eliminação.
A solução prática em sistemas que precisam respeitar ambos os requisitos:
- Pseudonimização no audit log: em vez de armazenar
email: "camila@empresa.com", armazenaractor_id: "user_abc123". A tabela de mapeamento entreuser_abc123e a identidade real pode ser deletada no esquecimento — o audit log permanece mas fica pseudonimizado (sem referência direta a PII). - Granularidade na retenção: definir diferentes períodos de retenção por tipo de dado — dados de negócio por 5 anos (obrigação fiscal), dados de autenticação por 1 ano, dados de suporte por 2 anos. A política de retenção deve ser documentada na política de privacidade.
- Documentar a base legal: a LGPD exige que toda base legal para tratamento de dados seja documentada. Registrar explicitamente que o audit log tem base legal em "cumprimento de obrigação legal" ou "legítimo interesse" permite justificar a retenção mesmo após solicitação de exclusão.
Armazenar mais dados do que o necessário no audit log, incluindo campos que não são necessários para o propósito de auditoria. Um audit log que registra o conteúdo completo de mensagens privadas "porque pode ser útil investigar" está tratando dados para finalidade diferente da original — violação do princípio da finalidade da LGPD. O dado correto é o mínimo necessário para responder "quem fez o quê sobre qual recurso" — não um dump completo do estado do sistema.
SOC 2 — o que auditores verificam
SOC 2 (Service Organization Control 2) é um framework de auditoria desenvolvido pelo AICPA para empresas de tecnologia que processam dados de clientes. É amplamente exigido por empresas enterprise como pré-requisito para contratar fornecedores SaaS — especialmente nos EUA. SOC 2 Type I avalia os controles documentados em um ponto no tempo; SOC 2 Type II verifica que os controles funcionaram conforme documentado por um período mínimo de 6 meses.
Os cinco Trust Services Criteria (TSC) do SOC 2 são: Security (CC), Availability (A), Processing Integrity (PI), Confidentiality (C), e Privacy (P). Security é obrigatório; os demais são opcionais mas frequentemente incluídos. Para audit logs, o que auditores verificam no critério de Security:
- CC7.2: o sistema monitora para detecção de eventos de segurança. O audit log é evidência de que o monitoramento existe e captura os eventos relevantes.
- CC7.3: eventos de segurança são avaliados para determinar se são incidentes. Evidência: processo de revisão de alerts e entradas de audit log.
- CC6.1: acesso lógico a sistemas e dados é restrito. Evidência: audit log de quem acessou o quê.
- CC6.3: controles de acesso são revisados periodicamente. Evidência: logs de revisão de acesso com timestamps e responsáveis.
Auditores de SOC 2 solicitam evidências concretas: samples de audit logs de períodos específicos, documentação de como o audit log é protegido contra adulteração, e demonstração de que alertas baseados em audit log funcionam. Times que preparam SOC 2 sem ter construído infraestrutura de audit log primeiro frequentemente descobrem que a lacuna é a parte mais trabalhosa de endereçar.
GDPR e PCI DSS — outros frameworks relevantes
GDPR (General Data Protection Regulation) europeu exige logging de todas as atividades de processamento de dados pessoais (Artigo 30) e do exercício de direitos pelos titulares (Artigo 17-22). Para sistemas com usuários europeus, o registro de consentimento (quando o usuário deu consentimento, para qual finalidade, com qual versão da política) deve ser auditável — em caso de disputa, a empresa precisa provar que o consentimento foi dado.
PCI DSS (Payment Card Industry Data Security Standard) — obrigatório para sistemas que processam cartões de crédito — tem requisitos específicos de audit log (Requisito 10):
- 10.2: implementar audit trail para eventos específicos (acesso a dados de portador de cartão, acesso root/admin, trilhas de autenticação, uso de mecanismos de auditoria).
- 10.3: proteger trilhas de auditoria contra modificação (append-only, hash chaining ou similar).
- 10.4: sincronizar relógios de todos os sistemas com NTP (para correlação de logs entre sistemas).
- 10.5: proteger trilhas de auditoria contra acesso não autorizado (segregação, controle de acesso).
- 10.7: reter trilhas de auditoria por pelo menos 1 ano, com os últimos 3 meses disponíveis imediatamente para análise.
Implementação prática — audit logging como cross-cutting concern
O padrão mais robusto para audit logging em aplicações é como cross-cutting concern (tema do módulo 05): um interceptor/middleware que captura automaticamente eventos relevantes sem que o código de negócio precise explicitamente emiti-los.
public class AuditInterceptor : SaveChangesInterceptor
{
private readonly IAuditLogger _audit;
private readonly IHttpContextAccessor _http;
public override async ValueTask<int> SavedChangesAsync(
SaveChangesCompletedEventData data, int result, CancellationToken ct)
{
var context = data.Context!;
var user = _http.HttpContext?.User;
foreach (var entry in context.ChangeTracker.Entries())
{
if (entry.State is EntityState.Unchanged) continue;
var action = entry.State switch {
EntityState.Added => "create",
EntityState.Modified => "update",
EntityState.Deleted => "delete",
_ => "unknown"
};
await _audit.LogAsync(new AuditEvent {
Actor = user?.GetUserId() ?? "system",
Action = $"{entry.Entity.GetType().Name.ToLower()}.{action}",
Resource = new { Type = entry.Entity.GetType().Name,
Id = entry.Property("Id").CurrentValue },
Payload = entry.State == EntityState.Deleted
? entry.OriginalValues.ToObject() // snapshot antes
: entry.CurrentValues.ToObject(),
});
}
return result;
}
}
O interceptor captura todas as mudanças de entidade do EF Core automaticamente. O código de negócio não precisa emitir eventos explicitamente — o audit acontece transparentemente em cada SaveChangesAsync.
from sqlalchemy import event
from sqlalchemy.orm import Session
import contextvars
# Context var para propagar o usuário pelo request
current_user: contextvars.ContextVar[str] = contextvars.ContextVar('current_user')
def setup_audit_listeners(session_factory):
@event.listens_for(Session, "after_bulk_delete")
def receive_after_bulk_delete(delete_context):
# bulk deletes precisam de tratamento especial
pass
@event.listens_for(Session, "after_flush")
def receive_after_flush(session, flush_context):
for obj in session.new:
emit_audit(obj, "create", session)
for obj in session.dirty:
emit_audit(obj, "update", session)
for obj in session.deleted:
emit_audit(obj, "delete", session)
def emit_audit(obj, action: str, session: Session):
actor = current_user.get("system")
AuditEvent = Base.metadata.tables.get("audit_events")
# Inserir diretamente no banco de audit (pode ser conexão diferente)
session.execute(AuditEvent.insert().values(
actor_id=actor,
action=f"{type(obj).__name__.lower()}.{action}",
resource_id=getattr(obj, "id", None),
payload=obj.__dict__.copy(),
timestamp=datetime.utcnow(),
))
O event listener do SQLAlchemy é executado dentro da mesma transação da operação original — garantindo atomicidade. Se a operação de negócio falhar, o audit também não é persistido.
func AuditMiddleware(audit AuditLogger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Capturar informações antes de passar para o handler
start := time.Now()
rw := &responseWriter{ResponseWriter: w, statusCode: 200}
next.ServeHTTP(rw, r)
// Apenas logar operações de mutação e acessos a recursos sensíveis
if r.Method == http.MethodGet && !isSensitivePath(r.URL.Path) {
return
}
user := UserFromContext(r.Context())
audit.Log(r.Context(), AuditEvent{
Actor: user.ID,
Action: methodToAction(r.Method) + "." + resourceFromPath(r.URL.Path),
IP: realIP(r),
SessionID: r.Header.Get("X-Session-ID"),
RequestID: r.Header.Get("X-Request-ID"),
Result: statusToResult(rw.statusCode),
Duration: time.Since(start),
})
})
}
}
O middleware de HTTP captura a camada de API; para audit de banco de dados, é necessária uma camada adicional no repository — o middleware HTTP não tem visibilidade sobre quais dados específicos foram acessados.
Monitoramento de audit logs — alertas e anomalias
Um audit log que ninguém lê é apenas armazenamento caro. O valor real emerge quando o audit log alimenta alertas em tempo real e análises periódicas. Padrões que devem gerar alertas imediatos:
- Múltiplos acessos negados em sequência para o mesmo ator (possível brute force ou comprometimento de conta)
- Acesso a recursos fora do padrão histórico do ator (novo tipo de dados, novo horário, novo volume)
- Operações administrativas fora do horário de expediente ou de IPs não habituais
- Volume anormal de exports ou downloads de dados
- Tentativas de acesso ao próprio audit log por contas não autorizadas
SIEMs (Security Information and Event Management) como Splunk, Elastic SIEM, ou Azure Sentinel centralizam logs de múltiplas fontes e aplicam regras de detecção. Para organizações menores, CloudWatch Logs Insights (AWS), Cloud Logging (GCP), ou Stack Alerts com Elasticsearch são alternativas mais acessíveis.
Decisões de engenharia
Logs operacionais registram eventos para debugging e observabilidade — erros de aplicação, latência de queries, traces de request. Podem ser rotacionados, comprimidos, e deletados após o TTL de troubleshooting (7–30 dias). Audit logs registram ações de negócio para rastreabilidade e compliance — quem fez o quê sobre qual recurso — e têm requisitos de retenção regulatórios (1–7 anos dependendo do framework). Misturar os dois em um único sistema é um erro comum: o volume de logs operacionais obscurece os eventos de compliance, e o TTL de retenção operacional viola as obrigações regulatórias. Use sistemas separados: sua stack de observabilidade (Loki, Elasticsearch, CloudWatch) para logs operacionais, e um sistema dedicado append-only para audit.
Append-only (trigger que bloqueia UPDATE/DELETE + REVOKE de permissões) é suficiente para a maioria dos contextos: protege contra modificação acidental e contra ataques que não têm acesso direto ao banco. É simples de implementar e verificar. Hash chaining adiciona uma camada de prova criptográfica: mesmo que um atacante com acesso de superuser ao banco modifique uma entrada, a inconsistência no hash chain é detectável por qualquer pessoa com os dados. Prefira hash chaining para sistemas com requisito de prova legal (financeiro, saúde, defesa) ou quando a ameaça inclui atacantes com acesso privilegiado ao banco. Para SOC 2 padrão, append-only com storage segregado é suficiente.
Pseudonimização armazena um identificador opaco (user_abc123) em vez de PII direta (email, nome), e mantém a tabela de mapeamento separada — que pode ser deletada no direito ao esquecimento, tornando o audit log não-identificável sem destruir a rastreabilidade comportamental. Tokenização vai além: substitui o dado por um token sem tabela de mapeamento no sistema local (o mapeamento fica em um vault externo), e pode ser irreversível por design. Para audit logs, pseudonimização é suficiente e mais prática — você ainda pode correlacionar eventos do mesmo ator (mesmo que não saiba quem é o ator), que é o que importa para investigação de padrões. Tokenização irreversível quebra a investigabilidade.
Audit log por serviço (cada microserviço tem sua própria tabela de audit) é simples de implementar mas fragmenta a visão: investigar uma ação que cruzou múltiplos serviços requer consultar múltiplos sistemas. Centralizado (todos os serviços emitem para um único sink de audit) é mais poderoso para investigação e compliance, mas cria um single point of failure e um hotspot de escrita. O padrão comum é centralizar com Kafka como buffer: cada serviço produz eventos de audit no Kafka, um consumer persiste em um banco central append-only com acesso controlado. Isso desacopla emissão de persistência e garante que falhas no banco de audit não afetam o serviço principal.
Perguntas de entrevista
Qual a diferença entre logging operacional e audit log, e por que confundi-los é perigoso?
Logging operacional serve à observabilidade: registra erros, traces, métricas de performance, e eventos de sistema para que engenheiros possam debugar e monitorar a saúde da aplicação. Tem TTL curto (dias a semanas), alto volume, e o objetivo é resolveu o problema rapidamente. Audit log serve à rastreabilidade e accountability: registra ações de negócio — quem fez o quê, quando, sobre qual recurso — para que investigações, auditorias externas, e processos legais possam determinar responsabilidades. Tem retenção longa (anos), é focado em eventos discretos de ação humana ou sistêmica, e deve ser imutável.
Confundi-los é perigoso em dois sentidos: (1) tratar audit log como log operacional leva a deletar evidências de compliance quando o TTL expira — descoberto somente quando o auditor solicita logs de 18 meses atrás e eles não existem; (2) armazenar tudo junto obscurece os eventos de compliance em um oceano de ruído operacional e torna a consulta para investigação inviável. O audit log é dado jurídico; o log operacional é dado de engenharia — tratamentos distintos são obrigatórios.
Por que hash chaining oferece garantias mais fortes que apenas append-only?
Append-only com triggers de banco previne modificações via SQL convencional — mas um atacante com acesso direto ao storage (arquivo de dados do PostgreSQL, backup, export) pode modificar dados diretamente no nível de bytes sem passar pelos triggers. Também, um DBA com acesso de superuser pode desabilitar triggers temporariamente, fazer a modificação, e reativá-los.
Hash chaining torna qualquer modificação criptograficamente detectável: cada entrada contém o hash da entrada anterior. Se a entrada N é modificada, seu hash muda, o que invalida o hash armazenado na entrada N+1, que invalida N+2, e assim por diante. Verificar a integridade da cadeia requer apenas recalcular os hashes sequencialmente — qualquer quebra indica adulteração. Isso funciona mesmo se o atacante tiver acesso direto ao banco, pois uma modificação coerente exigiria recalcular e atualizar todos os hashes subsequentes, o que é impossível sem que o processo de verificação detecte a discrepância com algum snapshot anterior da cadeia. É o mesmo princípio de blockchains — sem necessidade de consenso distribuído, apenas de guardar o hash mais recente em um local separado.
Como conciliar o direito ao esquecimento da LGPD com a imutabilidade do audit log?
A aparente contradição é resolvida por base legal: tanto a LGPD (Art. 16) quanto o GDPR (Art. 17(3)) preveem que o direito ao esquecimento não se aplica quando o dado é necessário para cumprimento de obrigação legal ou exercício de direitos em processos judiciais. Audit logs para fins de compliance, investigação de fraude, ou obrigação regulatória têm base legal para retenção — mas essa base deve ser documentada explicitamente.
Na prática, a solução técnica é pseudonimização: o audit log armazena actor_id: "user_abc123", não email: "camila@empresa.com". Uma tabela de mapeamento separada vincula o ID opaco à identidade real. Quando o usuário solicita esquecimento, você deleta a tabela de mapeamento — o audit log continua existindo, imutável, mas as entradas ficam pseudonimizadas (sem referência identificável à pessoa real). A rastreabilidade de comportamento é preservada para investigação; a identificação pessoal é removida conforme solicitado. Documentar essa arquitetura na política de privacidade e no ROPA (Records of Processing Activities) é parte obrigatória da conformidade.
O que auditores de SOC 2 Type II verificam especificamente em audit logs?
SOC 2 Type II avalia que controles funcionaram consistentemente por um período (mínimo 6 meses). Para audit logs, os auditores verificam: (1) Existência e completude — solicitam samples de audit logs de períodos específicos dentro do período de auditoria; precisam ver que eventos relevantes (login, acesso a dados sensíveis, mudanças administrativas) foram capturados de forma consistente; (2) Integridade — verificam como o audit log é protegido contra modificação (triggers, políticas de acesso, storage segregado); (3) Cobertura — verificam que os critérios CC6.1 (controle de acesso lógico) e CC7.2 (monitoramento de segurança) são satisfeitos pelos eventos capturados; (4) Retenção — verificam que logs são retidos conforme a política documentada; (5) Revisão periódica — evidência de que alguém revisa os audit logs regularmente (tickets de revisão, relatórios de anomalia). O gap mais comum: times têm logging mas não têm processo documentado de revisão — que para o auditor é equivalente a não ter logging.
Por que registrar tentativas de acesso negado é tão importante quanto acessos bem-sucedidos?
Acessos negados são frequentemente o sinal mais valioso de um ataque em andamento. Um login bem-sucedido pode ser legítimo ou comprometimento de credencial — difícil distinguir sem contexto. Uma série de acessos negados para o mesmo ator, especialmente em sequência rápida ou para recursos que o ator nunca acessou antes, é o padrão de reconhecimento (reconnaissance) ou brute force.
Sem o log de acessos negados, você detecta ataques somente após comprometimento — quando um acesso bem-sucedido não deveria ter acontecido. Com o log de acessos negados, você detecta tentativas enquanto ainda estão falhando, permitindo resposta antes do comprometimento. Em termos concretos: PCI DSS requisito 10.2.4 exige explicitamente log de tentativas de acesso inválidas. Para SOC 2, a ausência de log de acessos negados é uma lacuna na cobertura de CC7.2 (monitoramento para detecção de eventos de segurança). Além disso, em investigações pós-incidente, o log de acessos negados reconstrói a linha do tempo do ataque — mostrando quais sistemas foram tentados antes do comprometimento bem-sucedido.
Como praticar
-
Implementar audit log append-only com trigger de proteção. Em PostgreSQL, crie a tabela de audit events com o trigger que bloqueia UPDATE e DELETE. Implemente a função de inserção no seu ORM favorito. Teste que operações normais geram entradas corretas, e que tentativas de modificar ou deletar entradas do audit são bloqueadas com erro claro.
Critério:UPDATE audit_events SET action = 'modified'deve retornar exceção "Audit logs são imutáveis".DELETE FROM audit_eventsdeve ser igualmente bloqueado. Inserir um evento de teste e verificar que todos os campos obrigatórios (actor_id, action, timestamp, resource_id, payload) estão presentes e corretos. -
Definir a política de retenção e base legal para um sistema existente. Para um sistema que você conhece, mapeie: quais dados o audit log registra, qual é a base legal para cada tipo de dado (LGPD/GDPR), e qual deve ser o período de retenção por tipo. Documente a política em um arquivo que poderia ser entregue a um auditor. Identifique dados que o audit log coleta mas que não têm base legal clara — esses devem ser removidos.
Critério: Produzir um documento com: lista de tipos de evento auditados, base legal para cada tipo (obrigação legal, legítimo interesse, etc.), período de retenção por tipo, e processo de pseudonimização para direito ao esquecimento. O documento deve ser compreensível por um auditor externo sem contexto adicional. -
Criar um dashboard de monitoramento de audit. Com qualquer stack de observabilidade disponível (Grafana + Loki, Kibana, ou CloudWatch), crie um dashboard com: volume de eventos por tipo por hora (para detectar anomalias), top 10 ações por ator, e taxa de acessos negados. Configure um alerta para quando a taxa de acessos negados superar 3x a média das últimas 24 horas.
Critério: O dashboard deve carregar em menos de 5s com dados das últimas 24h. O alerta de taxa de acessos negados deve ser testado injetando eventos de teste deresult.status: "denied"e verificando que o alerta dispara dentro de 5 minutos após ultrapassar o limiar configurado. -
Implementar hash chaining e verificação de integridade. Adicione hash chaining à tabela de audit usando a coluna gerada do PostgreSQL ou equivalente. Implemente um job de verificação que percorre a cadeia e detecta quebras. Teste a detecção corrompendo manualmente (via acesso direto ao banco em ambiente de dev) uma entrada no meio da cadeia e verificando que o job reporta a inconsistência com o ID da entrada corrompida.
Critério: O job de verificação deve retornar "chain_valid: true" para uma cadeia intacta e "chain_broken at id: N" com o ID correto ao simular adulteração. A verificação de uma cadeia de 10.000 entradas deve completar em menos de 30 segundos. -
Conduzir um exercício de investigação com o audit log. Com um sistema que tem audit log implementado (pode ser o exercício 1), simule um cenário de investigação: um ator fez uma série de ações suspeitas (acesse recursos de outro usuário, exporte dados em volume anormal, tente modificar registros não autorizados). Sem saber de antemão quais ações foram feitas, use apenas o audit log para reconstruir a linha do tempo completa do ator suspeito.
Critério: A investigação deve identificar corretamente todas as ações do ator suspeito, na ordem cronológica correta, apenas com queries no audit log. O tempo de investigação (da suspeita à linha do tempo completa) deve ser documentado — este é o MTTI (Mean Time to Investigate) baseline do sistema.
Referências para aprofundar
- docs LGPD — Lei Geral de Proteção de Dados (Lei 13.709/2018).
- docs SOC 2 Trust Services Criteria — AICPA.
- article What is SOC 2 and How to Prepare — Vanta (vanta.com).
- docs PCI DSS v4.0 — Requirement 10: Log and Monitor All Access.
- article GDPR Article 30 — Records of Processing Activities — European Commission.
- article Audit Logging Best Practices — OWASP Logging Cheat Sheet.
- article Immutable Audit Logs in PostgreSQL — pganalyze Blog.
- book Database Reliability Engineering — Campbell e Majors (O'Reilly, 2017).
- video Building Audit Trails That Lawyers Love — PyCon US 2019.
- article AWS CloudTrail — Audit Logging for AWS.
- article LGPD na Prática — Guia para Desenvolvedores — Serpro.
- book Security Engineering — Ross Anderson (Wiley, 3rd ed. 2020).