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, 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 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
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
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
# 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.
// 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:
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:
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
- CPF é mascarado em todas as interfaces de usuário.
- Logs de aplicação nunca contêm CPFs em texto claro.
- Banco de dados utiliza criptografia em nível de coluna.
- Registros expiram automaticamente após o prazo de retenção.
- Acesso a CPF completo requer permissão explícita.
- APIs filtram campos sensíveis com base na finalidade.
- Respostas de erro nunca expõem dados pessoais.
- 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.
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 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 — 50 consultas mensais gratuitas, sem cartão de crédito.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



