# Privacidade por padrão: como configurar sistemas para proteger CPF automaticamente

> Descubra como implementar privacidade por padrão (privacy by default) em sistemas que processam CPF, com exemplos de código e configurações práticas.

**Publicado:** 11/06/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/privacidade-por-padrao-proteger-cpf-automaticamente

---


Privacidade por padrão — ou privacy by default — significa que um sistema que processa CPF deve mascarar, minimizar e expirar esses dados automaticamente, sem depender de configuração manual a cada deploy. A [LGPD](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm), em seu artigo 46, exige que agentes de tratamento adotem medidas de segurança técnicas e administrativas aptas a proteger dados pessoais — e a [ANPD](https://www.gov.br/anpd) considera privacy by default parte dessas medidas.

## Introdução

Privacidade por padrão determina que sistemas devem ser configurados, desde a concepção, para oferecer o maior nível possível de proteção aos dados pessoais. No contexto de dados de CPF, isso significa que qualquer sistema que colete, armazene ou processe esse identificador deve, automaticamente, aplicar medidas de proteção sem depender de ações manuais do usuário ou do desenvolvedor.

A LGPD, em seu artigo 46, exige que agentes de tratamento adotem medidas de segurança, técnicas e administrativas aptas a proteger dados pessoais.

---

## Princípios de privacidade por padrão

### Minimização de dados

Colete e processe apenas os dados estritamente necessários para a finalidade declarada. Se você precisa apenas validar um CPF, não armazene nome, data de nascimento ou gênero.

### Anonimização e pseudonimização automáticas

Sempre que possível, substitua dados identificáveis por versões anonimizadas ou pseudonimizadas antes de armazená-los.

### Retenção limitada

Configure prazos automáticos de expiração para dados de CPF. Após o término da finalidade, os dados devem ser eliminados automaticamente.

### Acesso restrito por padrão

Nenhum usuário deve ter acesso a dados de CPF por padrão. O acesso deve ser concedido explicitamente com base no princípio do menor privilégio.

---

## Configurações automáticas de proteção

### Classe de proteção de CPF

```python
import hashlib
import re
from datetime import datetime, timezone, timedelta
from dataclasses import dataclass, field
from typing import Optional

@dataclass
class CPFProtegido:
 """Classe que implementa privacidade por padrão para dados de CPF."""

 _cpf_raw: str
 _finalidade: str
 _base_legal: str
 _expiracao: datetime = field(default_factory=lambda: datetime.now(timezone.utc) + timedelta(days=30))

 def __post_init__(self):
 self._cpf_limpo = re.sub(r"\D", "", self._cpf_raw)
 if len(self._cpf_limpo) != 11:
 raise ValueError("CPF deve conter 11 dígitos")
 self._hash = hashlib.sha256(self._cpf_limpo.encode()).hexdigest()

 @property
 def mascarado(self) -> str:
 """Retorna CPF mascarado — padrão para exibição."""
 return f"***.{self._cpf_limpo[3:6]}.***-{self._cpf_limpo[-2:]}"

 @property
 def hash_anonimizado(self) -> str:
 """Retorna hash do CPF para comparações sem exposição."""
 return self._hash

 @property
 def completo(self) -> Optional[str]:
 """Retorna CPF completo somente se ainda dentro do prazo de retenção."""
 if datetime.now(timezone.utc) > self._expiracao:
 return None
 return self._cpf_limpo

 @property
 def expirado(self) -> bool:
 """Verifica se o prazo de retenção expirou."""
 return datetime.now(timezone.utc) > self._expiracao

 def __str__(self) -> str:
 """Representação segura — nunca expõe o CPF completo."""
 return self.mascarado

 def __repr__(self) -> str:
 return f"CPFProtegido(mascarado={self.mascarado})"

 def to_dict_seguro(self) -> dict:
 """Serialização segura para logs e APIs."""
 return {
 "cpf_mascarado": self.mascarado,
 "hash": self._hash,
 "finalidade": self._finalidade,
 "base_legal": self._base_legal,
 "expiracao": self._expiracao.isoformat()
 }

# Uso
cpf = CPFProtegido(
 _cpf_raw="123.456.789-01",
 _finalidade="verificacao_cadastral",
 _base_legal="consentimento"
)

print(cpf) # ***.456.***-01
print(cpf.to_dict_seguro()) # Dados seguros para log
```

---

## Middleware de proteção automática

### Interceptor que aplica proteções antes de qualquer processamento

```python
import requests
import json
from flask import Flask, request, jsonify
from functools import wraps

app = Flask(__name__)

CAMPOS_SENSIVEIS = ["cpf", "name", "birthDate"]
CAMPOS_PERMITIDOS_POR_FINALIDADE = {
 "verificacao_cadastral": ["cpf", "name"],
 "analise_credito": ["cpf", "name", "birthDate"],
 "marketing": [] # Nenhum dado pessoal permitido por padrão
}

def privacy_by_default(func):
 """Middleware que aplica privacidade por padrão a toda resposta."""
 @wraps(func)
 def wrapper(*args, **kwargs):
 resultado = func(*args, **kwargs)

 if isinstance(resultado, dict) and "data" in resultado:
 finalidade = request.headers.get("X-Finalidade", "desconhecida")
 campos_permitidos = CAMPOS_PERMITIDOS_POR_FINALIDADE.get(finalidade, [])

 dados_filtrados = {}
 for campo, valor in resultado["data"].items():
 if campo in campos_permitidos:
 dados_filtrados[campo] = valor
 elif campo in CAMPOS_SENSIVEIS:
 dados_filtrados[campo] = "[REDACTED]"
 else:
 dados_filtrados[campo] = valor

 resultado["data"] = dados_filtrados
 resultado["_privacy"] = {
 "finalidade": finalidade,
 "campos_filtrados": [c for c in CAMPOS_SENSIVEIS if c not in campos_permitidos]
 }

 return resultado

 return wrapper

@app.route("/api/cpf/<cpf>")
@privacy_by_default
def consultar_cpf(cpf: str):
 """Consulta CPF com privacidade por padrão."""

 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()

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

 return {"error": "CPF não encontrado"}
```

### Teste com cURL especificando a finalidade

```bash
# Consulta para verificação cadastral — retorna cpf e name
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Finalidade: verificacao_cadastral" \
 --max-time 30

# Consulta para marketing — todos os campos sensíveis são redacted
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Finalidade: marketing" \
 --max-time 30
```

---

## Configurações de banco de dados

### Criptografia transparente

Configure criptografia em nível de coluna para campos de CPF no banco de dados, de forma que os dados sejam automaticamente criptografados ao serem inseridos e descriptografados ao serem lidos por usuários autorizados.

### TTL (Time to Live) automático

Em bancos NoSQL como MongoDB ou DynamoDB, configure TTL indexes para que registros contendo CPF sejam automaticamente eliminados após o prazo de retenção.

```javascript
// MongoDB — criar índice TTL para expiração automática
db.consultas_cpf.createIndex(
 { "data_consulta": 1 },
 { expireAfterSeconds: 2592000 } // 30 dias
)
```

### Mascaramento em views de banco

Crie views que automaticamente mascarem o CPF para usuários sem permissão elevada:

```sql
CREATE VIEW vw_clientes_segura AS
SELECT
 id,
 CONCAT('***.', SUBSTRING(cpf, 4, 3), '.***-', RIGHT(cpf, 2)) AS cpf_mascarado,
 nome,
 data_cadastro
FROM clientes;
```

---

## Proteções em nível de aplicação

### Sanitização automática de logs

Nunca permita que dados de CPF apareçam em logs de aplicação. Implemente um filtro global que detecte e mascare automaticamente padrões de CPF:

```python
import re
import logging

class CPFFilter(logging.Filter):
 """Filtro de log que mascara automaticamente qualquer CPF."""

 CPF_PATTERN = re.compile(r"\b(\d{3})\.?(\d{3})\.?(\d{3})-?(\d{2})\b")

 def filter(self, record):
 if hasattr(record, "msg") and isinstance(record.msg, str):
 record.msg = self.CPF_PATTERN.sub(r"***.\2.***-\4", record.msg)
 return True

# Aplicar filtro a todos os loggers
for handler in logging.root.handlers:
 handler.addFilter(CPFFilter())
```

### Prevenção de exposição em respostas de erro

Configure tratamento global de exceções para nunca incluir dados de CPF em mensagens de erro retornadas ao cliente.

---

## Checklist de privacidade por padrão

1. CPF é mascarado em todas as interfaces de usuário.
2. Logs de aplicação nunca contêm CPFs em texto claro.
3. Banco de dados utiliza criptografia em nível de coluna.
4. Registros expiram automaticamente após o prazo de retenção.
5. Acesso a CPF completo requer permissão explícita.
6. APIs filtram campos sensíveis com base na finalidade.
7. Respostas de erro nunca expõem dados pessoais.
8. Backups seguem as mesmas regras de proteção dos dados originais.

---

## Perguntas frequentes

### O que diferencia privacy by design de privacy by default na prática?

Privacy by design significa incorporar proteções de privacidade desde a arquitetura do sistema — escolhas de modelo de dados, fluxos de autenticação, separação de responsabilidades. Privacy by default vai além: determina que as configurações padrão do sistema já devem ser as mais restritivas possíveis, sem que o usuário ou o desenvolvedor precise ativá-las manualmente. Para dados de CPF, isso significa que mascaramento, TTL e controle de acesso devem estar ativos por padrão, não como opção configurável.

### Como aplicar minimização de dados quando a API retorna mais campos do que minha finalidade exige?

Implemente um middleware ou filtro que, antes de repassar os dados da API para qualquer outra camada do sistema, remova os campos não necessários para a finalidade declarada. Se sua finalidade é apenas confirmar a existência do CPF, descarte nome e data de nascimento imediatamente após a verificação — não os armazene nem os registre em log.

### O TTL automático no banco de dados é suficiente para cumprir o direito de exclusão da LGPD?

O TTL cobre a exclusão por prazo de retenção (art. 16), mas o direito de exclusão a pedido do titular (art. 18, VI) exige um mecanismo ativo: o sistema precisa localizar todos os registros associados ao CPF e removê-los imediatamente, independentemente do prazo configurado. TTL e exclusão por solicitação são complementares, não substitutos.

### Como garantir que CPFs em backups também sejam protegidos?

Backups devem ser criptografados com a mesma chave usada nos dados em produção. Se a chave for rotacionada ou um CPF for excluído por solicitação do titular, o backup correspondente também deve ser tratado — ou re-criptografado com a nova chave, ou com o registro removido na próxima janela de manutenção do backup. Backups sem controle de acesso equivalente aos dados originais são uma vulnerabilidade de conformidade com a LGPD.

### Leia também

- [Como proteger informações sensíveis de CPF ao consumir APIs](https://cpfhub.io/blog/como-proteger-informacoes-sensiveis-de-cpf-ao-consumir-apis)
- [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)
- [APIs de consulta de CPF: segurança para evitar vazamento](https://cpfhub.io/blog/apis-consulta-cpf-seguranca-evitar-vazamento)
- [Como responder a incidentes de vazamento de dados de CPF](https://cpfhub.io/blog/como-responder-a-incidentes-de-vazamento-de-dados-de-cpf)

---

## Conclusão

Privacidade por padrão não é um recurso adicional — é um requisito da LGPD e uma prática que protege tanto os titulares quanto a sua empresa. Ao configurar sistemas para proteger dados de CPF automaticamente, você reduz drasticamente o risco de exposição acidental e simplifica a demonstração de conformidade perante a ANPD. A API do [CPFHub.io](https://www.cpfhub.io/) opera com HTTPS obrigatório e autenticação por chave, fornecendo a base segura sobre a qual você implementa as demais camadas de proteção.

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

