# Como implementar logs de auditoria para acesso a dados de CPF

> Aprenda a implementar logs de auditoria completos para rastrear todo acesso a dados de CPF, garantindo conformidade com a LGPD.

**Publicado:** 27/05/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/implementar-logs-auditoria-acesso-dados-cpf

---


Rastrear quem acessou dados de CPF, quando e por qual motivo é uma obrigação legal sob a LGPD — não uma boa prática opcional. Logs de auditoria imutáveis são a principal evidência que controladores precisam apresentar à ANPD em fiscalizações e incidentes de segurança.

## Introdução

Em um cenário regulatório exigente, rastrear quem acessou dados de CPF, quando e por qual motivo deixou de ser opcional — é uma obrigação legal e uma prática essencial de segurança. A [LGPD](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm) exige que controladores e operadores demonstrem conformidade, e logs de auditoria são a principal ferramenta para isso.

---

## Por que logs de auditoria são essenciais

### Conformidade regulatória

A LGPD, em seu artigo 6, inciso X, estabelece o princípio da responsabilização e prestação de contas. Isso significa que o controlador deve ser capaz de demonstrar a adoção de medidas eficazes para cumprir a lei. Logs de auditoria são a evidência concreta dessa conformidade.

### Detecção de acessos não autorizados

Logs permitem identificar padrões anormais de acesso -- como consultas em horários incomuns, volumes excessivos ou acessos por usuários que não deveriam ter permissão.

### Investigação de incidentes

Em caso de vazamento ou uso indevido de dados de CPF, os logs são fundamentais para reconstruir a linha do tempo do incidente e identificar os responsáveis.

### Resposta à ANPD

Quando a Autoridade Nacional de Proteção de Dados solicita informações sobre o tratamento de dados, logs detalhados demonstram transparência e controle.

---

## Arquitetura de um sistema de auditoria

### Componentes principais

1. **Interceptor de requisições**: captura todas as chamadas que envolvem dados de CPF.
2. **Gerador de logs**: formata e enriquece as informações de cada acesso.
3. **Armazenamento imutável**: persiste os logs de forma que não possam ser alterados.
4. **Sistema de alertas**: notifica sobre acessos suspeitos em tempo real.
5. **Painel de consulta**: interface para pesquisa e análise de logs.

---

## Implementação completa em Python

### Middleware de auditoria

```python
import json
import hashlib
import logging
from datetime import datetime, timezone
from functools import wraps
from flask import Flask, request, g
import requests

app = Flask(__name__)

# Configuração do logger de auditoria
audit_logger = logging.getLogger("cpf_audit")
audit_logger.setLevel(logging.INFO)

handler = logging.FileHandler("cpf_audit.log")
handler.setFormatter(logging.Formatter("%(message)s"))
audit_logger.addHandler(handler)

def mascarar_cpf(cpf: str) -> str:
 """Mascara o CPF para registro em logs."""
 cpf_limpo = cpf.replace(".", "").replace("-", "")
 if len(cpf_limpo) == 11:
 return f"***.{cpf_limpo[3:6]}.***-{cpf_limpo[-2:]}"
 return "***CPF_INVALIDO***"

def gerar_hash_log(log_entry: dict) -> str:
 """Gera hash para garantir integridade do log."""
 conteudo = json.dumps(log_entry, sort_keys=True)
 return hashlib.sha256(conteudo.encode()).hexdigest()

def audit_log(acao: str):
 """Decorator para registrar acessos a dados de CPF."""
 def decorator(func):
 @wraps(func)
 def wrapper(*args, **kwargs):
 inicio = datetime.now(timezone.utc)

 # Executar a função original
 resultado = func(*args, **kwargs)

 fim = datetime.now(timezone.utc)

 # Construir entrada de log
 log_entry = {
 "timestamp": inicio.isoformat(),
 "acao": acao,
 "usuario": getattr(g, "usuario_id", "anonimo"),
 "ip_origem": request.remote_addr,
 "user_agent": request.headers.get("User-Agent", ""),
 "cpf_consultado": mascarar_cpf(kwargs.get("cpf", "")),
 "endpoint": request.path,
 "metodo": request.method,
 "status_code": resultado[1] if isinstance(resultado, tuple) else 200,
 "duracao_ms": (fim - inicio).total_seconds() * 1000,
 "base_legal": request.headers.get("X-Base-Legal", "nao_informada"),
 "finalidade": request.headers.get("X-Finalidade", "nao_informada")
 }

 # Adicionar hash de integridade
 log_entry["hash"] = gerar_hash_log(log_entry)

 # Registrar no log
 audit_logger.info(json.dumps(log_entry, ensure_ascii=False))

 # Verificar acessos suspeitos
 verificar_acesso_suspeito(log_entry)

 return resultado

 return wrapper
 return decorator

def verificar_acesso_suspeito(log_entry: dict):
 """Verifica se o acesso apresenta padrões suspeitos."""
 hora_atual = datetime.fromisoformat(log_entry["timestamp"]).hour

 alertas = []

 # Acesso fora do horário comercial
 if hora_atual < 6 or hora_atual > 22:
 alertas.append("acesso_fora_horario")

 # Finalidade não informada
 if log_entry["finalidade"] == "nao_informada":
 alertas.append("finalidade_ausente")

 if alertas:
 alerta = {
 "timestamp": log_entry["timestamp"],
 "tipo": "acesso_suspeito",
 "alertas": alertas,
 "detalhes": log_entry
 }
 audit_logger.warning(json.dumps(alerta, ensure_ascii=False))

@app.route("/api/cpf/<cpf>")
@audit_log(acao="consulta_cpf")
def consultar_cpf(cpf: str):
 """Endpoint de consulta de CPF com auditoria."""

 try:
 response = requests.get(
 f"https://api.cpfhub.io/cpf/{cpf}",
 headers={
 "x-api-key": "SUA_API_KEY",
 "Accept": "application/json"
 },
 timeout=30
 )

 if response.status_code == 200:
 return response.json(), 200
 return {"error": "CPF não encontrado"}, 404

 except requests.exceptions.Timeout:
 return {"error": "Timeout na consulta"}, 504
```

### Consulta de teste via cURL

```bash
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Base-Legal: consentimento" \
 -H "X-Finalidade: verificacao_cadastral" \
 --max-time 30
```

---

## Formato do log de auditoria

Cada entrada de log deve conter informações suficientes para responder as perguntas: quem, o que, quando, onde, como e por que.

```json
{
 "timestamp": "2025-05-27T14:32:15.123Z",
 "acao": "consulta_cpf",
 "usuario": "usr_abc123",
 "ip_origem": "192.168.1.100",
 "user_agent": "Mozilla/5.0...",
 "cpf_consultado": "***.456.***-01",
 "endpoint": "/api/cpf/12345678901",
 "metodo": "GET",
 "status_code": 200,
 "duracao_ms": 892.5,
 "base_legal": "consentimento",
 "finalidade": "verificacao_cadastral",
 "hash": "a1b2c3d4e5f6..."
}
```

---

## Armazenamento imutável

Logs de auditoria devem ser armazenados de forma que não possam ser alterados ou excluídos. Algumas estratégias incluem:

### Write-Once Storage

Utilize serviços de armazenamento com políticas WORM (Write Once, Read Many), como Amazon S3 Object Lock ou Azure Immutable Blob Storage.

### Encadeamento de hashes

Implemente um encadeamento de hashes semelhante ao blockchain, onde cada log referência o hash do log anterior:

```python
class AuditChain:
 """Cadeia de logs com integridade por hash encadeado."""

 def __init__(self):
 self.last_hash = "0" * 64 # Hash inicial

 def adicionar_log(self, log_entry: dict) -> dict:
 log_entry["hash_anterior"] = self.last_hash
 log_entry["hash"] = hashlib.sha256(
 json.dumps(log_entry, sort_keys=True).encode()
 ).hexdigest()
 self.last_hash = log_entry["hash"]
 return log_entry

 def verificar_integridade(self, logs: list) -> bool:
 """Verifica se a cadeia de logs está íntegra."""
 hash_anterior = "0" * 64
 for log in logs:
 if log["hash_anterior"] != hash_anterior:
 return False
 hash_anterior = log["hash"]
 return True
```

---

## Retenção e descarte de logs

### Política de retenção

Defina por quanto tempo os logs devem ser mantidos, considerando:

- **Requisitos legais**: a LGPD não define prazo específico, mas recomenda-se manter logs por pelo menos 5 anos.
- **Necessidade operacional**: logs mais antigos podem ser arquivados em cold storage.
- **Minimização**: após o prazo de retenção, os logs devem ser descartados de forma segura.

### Anonimização após retenção

Após o prazo de retenção obrigatório, anonimize os logs removendo identificadores pessoais, mantendo apenas dados agregados para fins estatísticos.

---

## Alertas e monitoramento em tempo real

Configure alertas para os seguintes cenários:

- Volume de consultas por usuário acima do normal.
- Consultas a CPFs em horários fora do padrão.
- Múltiplas consultas ao mesmo CPF em curto intervalo.
- Acessos de IPs não reconhecidos.
- Tentativas de consulta sem base legal informada.

---

## Perguntas frequentes

### A LGPD exige explicitamente logs de auditoria para acesso a CPF?

A LGPD não usa o termo "log de auditoria" literalmente, mas o artigo 6º, inciso X (responsabilização e prestação de contas) e o artigo 48º (notificação de incidentes) criam essa obrigação na prática. Para demonstrar conformidade e investigar incidentes, logs de acesso a dados pessoais como CPF são o instrumento mais direto — e a [ANPD](https://www.gov.br/anpd) os considera evidência central em fiscalizações.

### Por quanto tempo devo manter os logs de acesso a dados de CPF?

A LGPD não fixa prazo, mas a prática recomendada é de 5 anos — alinhada ao prazo prescricional de ações civis relacionadas a danos por uso indevido de dados. Após esse período, os logs devem ser descartados de forma segura (sobrescrita ou destruição certificada) ou anonimizados, mantendo apenas dados agregados para fins estatísticos.

### Como evitar que os próprios logs se tornem um risco de privacidade?

Nunca armazene o CPF em claro nos logs — use sempre uma versão mascarada (ex: `***.456.***-01`) ou um hash SHA-256. Controle o acesso aos logs com as mesmas restrições aplicadas aos dados originais: autenticação, autorização por função e registros de quem consultou os próprios logs. Logs de auditoria são dados pessoais e também caem sob a LGPD.

### O que fazer quando a API de CPF retorna timeout durante uma consulta auditada?

Registre o timeout no log com o status adequado (`status_code: 504`) e o tempo decorrido. A CPFHub.io cobra R$0,15 por consulta adicional ao limite mensal e nunca bloqueia chamadas por limite de uso — portanto timeouts são eventos de infraestrutura, não de throttling. Implemente uma política de retry com backoff exponencial e registre cada tentativa separadamente no log de auditoria.

### Leia também

- [LGPD: CPF é dado pessoal sensível ou não? Entenda a classificação correta](https://cpfhub.io/blog/lgpd-cpf-e-dado-pessoal-sensivel-ou-nao-entenda-a-classificacao-correta)
- [Como manter registros de auditoria para consultas de CPF](https://cpfhub.io/blog/como-manter-registros-de-auditoria-para-consultas-de-cpf)
- [Como responder a incidentes de vazamento de dados de CPF](https://cpfhub.io/blog/como-responder-a-incidentes-de-vazamento-de-dados-de-cpf)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

Logs de auditoria são a espinha dorsal da conformidade com a LGPD quando se trata de acesso a dados de CPF. Um sistema bem implementado protege sua empresa em caso de fiscalização e permite detectar e responder rapidamente a acessos não autorizados. Invista em logs imutáveis, alertas inteligentes e políticas claras de retenção para manter sua operação segura e em conformidade.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito.

