Como implementar o princípio da necessidade ao consultar dados de CPF via API

Saiba como aplicar o princípio da necessidade da LGPD ao consultar dados de CPF via API, minimizando dados coletados e processados.

Redação CPFHub.io
Redação CPFHub.io
··9 min de leitura
Como implementar o princípio da necessidade ao consultar dados de CPF via API

O princípio da necessidade, previsto no artigo 6°, inciso III da LGPD, exige que sua aplicação solicite, processe e armazene apenas os campos de CPF estritamente necessários para cada finalidade declarada — nada além disso. A CPFHub.io retorna um objeto JSON completo com CPF, nome, gênero e data de nascimento, mas cabe à sua arquitetura filtrar e descartar os campos desnecessários antes de qualquer persistência. Implementar esse controle reduz o risco regulatório e demonstra conformidade ativa à ANPD.

Introdução

O princípio da necessidade, previsto no artigo 6, inciso III da LGPD, determina que o tratamento de dados pessoais deve se limitar ao mínimo necessário para a realização de suas finalidades. Na prática, isso significa que, ao consultar dados de CPF via API, sua aplicação deve solicitar, armazenar e processar apenas os campos estritamente indispensáveis para a finalidade declarada.


O que é o princípio da necessidade

A LGPD define o princípio da necessidade como a "limitação do tratamento ao mínimo necessário para a realização de suas finalidades, com abrangência dos dados pertinentes, proporcionais e não excessivos em relação às finalidades do tratamento de dados".

Na prática, isso significa

  • Não coletar dados "por precaução" ou "para uso futuro".
  • Filtrar campos desnecessários antes de armazenar.
  • Limitar o acesso a dados conforme a função do usuário.
  • Definir regras claras de retenção por finalidade.
  • Documentar a justificativa para cada campo utilizado.

Mapeamento de finalidade vs. campos necessários

Antes de integrar qualquer API de dados de CPF, mapeie quais campos são realmente necessários para cada caso de uso.

FinalidadeCampos necessáriosCampos desnecessários
Validação de CPFcpfname, birthDate, gender
Verificação de identidadecpf, namebirthDate, gender
Análise de créditocpf, name, birthDategender
Onboarding completocpf, name, birthDate, gender--

Implementação de filtro de necessidade

Proxy de minimização de dados

import requests
import json
import logging
from flask import Flask, request, jsonify
from functools import wraps
from datetime import datetime, timezone

app = Flask(__name__)

logging.basicConfig(
    filename="necessidade_audit.log",
    level=logging.INFO,
    format="%(asctime)s | %(message)s"
)

# Mapeamento de finalidade para campos permitidos
POLITICA_NECESSIDADE = {
    "validacao_cpf": {
    "campos_permitidos": ["cpf"],
    "retencao_horas": 0,
    "descricao": "Apenas validar se o CPF existe"
    },
    "verificacao_identidade": {
    "campos_permitidos": ["cpf", "name"],
    "retencao_horas": 24,
    "descricao": "Verificar identidade do titular"
    },
    "analise_credito": {
    "campos_permitidos": ["cpf", "name", "birthDate"],
    "retencao_horas": 720,
    "descricao": "Análise de crédito para contratação"
    },
    "onboarding": {
    "campos_permitidos": ["cpf", "name", "birthDate", "gender"],
    "retencao_horas": 8760,
    "descricao": "Cadastro completo do cliente"
    }
}

def aplicar_necessidade(func):
    """Middleware que filtra campos de acordo com a finalidade."""
    @wraps(func)
    def wrapper(*args, **kwargs):
    finalidade = request.headers.get("X-Finalidade")

    if not finalidade:
    return jsonify({
    "error": "Header X-Finalidade é obrigatório",
    "finalidades_validas": list(POLITICA_NECESSIDADE.keys())
    }), 400

    if finalidade not in POLITICA_NECESSIDADE:
    return jsonify({
    "error": f"Finalidade '{finalidade}' não reconhecida",
    "finalidades_validas": list(POLITICA_NECESSIDADE.keys())
    }), 400

    # Executar consulta
    resultado = func(*args, **kwargs)

    if isinstance(resultado, tuple):
    dados, status = resultado
    else:
    dados, status = resultado, 200

    # Filtrar campos conforme política de necessidade
    if isinstance(dados, dict) and "data" in dados:
    politica = POLITICA_NECESSIDADE[finalidade]
    campos_permitidos = politica["campos_permitidos"]

    dados_originais = dados["data"]
    dados_filtrados = {
    k: v for k, v in dados_originais.items()
    if k in campos_permitidos
    }

    campos_removidos = [
    k for k in dados_originais.keys()
    if k not in campos_permitidos
    ]

    # Log de auditoria
    logging.info(json.dumps({
    "timestamp": datetime.now(timezone.utc).isoformat(),
    "finalidade": finalidade,
    "campos_retornados": list(dados_filtrados.keys()),
    "campos_removidos": campos_removidos,
    "retencao_horas": politica["retencao_horas"],
    "usuario": request.headers.get("X-User-ID", "anonimo")
    }))

    dados["data"] = dados_filtrados
    dados["_necessidade"] = {
    "finalidade": finalidade,
    "campos_filtrados": campos_removidos,
    "retencao_max_horas": politica["retencao_horas"]
    }

    return jsonify(dados), status

    return wrapper

@app.route("/api/cpf/<cpf>")
@aplicar_necessidade
def consultar_cpf(cpf: str):
    """Consulta CPF com filtro de necessidade aplicado."""

    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

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

    return {"error": "CPF não encontrado"}, 404

Testes via cURL com diferentes finalidades

# Validação simples -- retorna apenas cpf
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
    -H "x-api-key: SUA_API_KEY" \
    -H "Accept: application/json" \
    -H "X-Finalidade: validacao_cpf" \
    --max-time 30

# Verificação de identidade -- 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_identidade" \
    --max-time 30

# Análise de crédito -- retorna cpf, name e birthDate
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
    -H "x-api-key: SUA_API_KEY" \
    -H "Accept: application/json" \
    -H "X-Finalidade: analise_credito" \
    --max-time 30

Controle de retenção por finalidade

Cada finalidade possui um tempo máximo de retenção diferente. Implemente limpeza automática:

from datetime import datetime, timezone, timedelta
import sqlite3

class ControladorRetencao:
    """Controla a retenção de dados de CPF por finalidade."""

    def __init__(self, db_path: str = "retencao.db"):
    self.conn = sqlite3.connect(db_path)
    self._criar_tabela()

    def _criar_tabela(self):
    self.conn.execute("""
    CREATE TABLE IF NOT EXISTS dados_cpf (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    cpf_hash TEXT NOT NULL,
    finalidade TEXT NOT NULL,
    dados TEXT NOT NULL,
    criado_em TEXT NOT NULL,
    expira_em TEXT NOT NULL
    )
    """)
    self.conn.commit()

    def armazenar(self, cpf_hash: str, finalidade: str, dados: dict, retencao_horas: int):
    """Armazena dados com prazo de expiração automático."""

    agora = datetime.now(timezone.utc)
    expiracao = agora + timedelta(hours=retencao_horas)

    self.conn.execute(
    "INSERT INTO dados_cpf (cpf_hash, finalidade, dados, criado_em, expira_em) VALUES (?, ?, ?, ?, ?)",
    (cpf_hash, finalidade, json.dumps(dados), agora.isoformat(), expiracao.isoformat())
    )
    self.conn.commit()

    def limpar_expirados(self) -> int:
    """Remove dados que ultrapassaram o prazo de retenção."""

    agora = datetime.now(timezone.utc).isoformat()
    cursor = self.conn.execute(
    "DELETE FROM dados_cpf WHERE expira_em < ?",
    (agora,)
    )
    self.conn.commit()
    return cursor.rowcount

    def relatorio_retencao(self) -> list:
    """Gera relatório de dados armazenados por finalidade."""

    cursor = self.conn.execute("""
    SELECT finalidade, COUNT(*) as total,
    MIN(criado_em) as mais_antigo,
    MAX(expira_em) as ultima_expiracao
    FROM dados_cpf
    GROUP BY finalidade
    """)
    return [
    {"finalidade": row[0], "total": row[1],
    "mais_antigo": row[2], "ultima_expiracao": row[3]}
    for row in cursor.fetchall()
    ]

Documentação de justificativa

Para cada campo de CPF utilizado, mantenha documentação que justifique a necessidade:

JUSTIFICATIVAS = {
    "cpf": {
    "campo": "CPF (número)",
    "justificativa": "Identificador único necessário para consulta cadastral",
    "base_legal": "execucao_contrato",
    "alternativas_avaliadas": "Nenhuma -- CPF é o único identificador aceito",
    "aprovado_por": "DPO",
    "data_aprovacao": "2025-01-15"
    },
    "name": {
    "campo": "Nome completo",
    "justificativa": "Necessário para verificação de identidade cruzada",
    "base_legal": "execucao_contrato",
    "alternativas_avaliadas": "Iniciais do nome -- insuficiente para verificação",
    "aprovado_por": "DPO",
    "data_aprovacao": "2025-01-15"
    },
    "birthDate": {
    "campo": "Data de nascimento",
    "justificativa": "Necessário para cálculo de elegibilidade em análise de crédito",
    "base_legal": "execucao_contrato",
    "alternativas_avaliadas": "Apenas faixa etária -- insuficiente para scoring",
    "aprovado_por": "DPO",
    "data_aprovacao": "2025-01-15"
    },
    "gender": {
    "campo": "Gênero",
    "justificativa": "Necessário apenas para personalização de comunicação no onboarding",
    "base_legal": "consentimento",
    "alternativas_avaliadas": "Comunicação neutra -- avaliada e descartada por pesquisa UX",
    "aprovado_por": "DPO",
    "data_aprovacao": "2025-01-15"
    }
}

Auditoria de conformidade com o princípio

Realize auditorias periódicas para verificar se a política de necessidade está sendo respeitada:

  • Compare os campos efetivamente acessados com os campos autorizados por finalidade.
  • Identifique padrões de consulta que possam indicar coleta excessiva.
  • Revise as justificativas documentadas com o DPO.
  • Atualize o mapeamento sempre que novas funcionalidades forem implementadas.

Perguntas frequentes

O que é o princípio da necessidade na LGPD e por que ele se aplica a consultas de CPF via API?

O princípio da necessidade está previsto no artigo 6°, inciso III da LGPD e limita o tratamento de dados pessoais ao mínimo indispensável para a finalidade declarada. Ao consultar CPF via API, a resposta pode conter nome, data de nascimento e gênero — mas se sua finalidade é apenas validar a existência do CPF, armazenar os demais campos viola o princípio. Cada campo extra aumenta o escopo de risco regulatório.

Como implementar o filtro de necessidade sem modificar a API que consome?

A abordagem recomendada é criar um proxy interno que intercepta a resposta da API de CPF e remove os campos não autorizados antes de retornar ao sistema consumidor. O middleware aplicar_necessidade mostrado neste artigo faz exatamente isso: lê o header X-Finalidade, aplica a política correspondente e descarta os campos desnecessários, registrando tudo em log de auditoria.

Como documentar o cumprimento do princípio da necessidade para uma auditoria da ANPD?

Mantenha três artefatos: (1) o mapeamento de finalidade vs. campos permitidos, aprovado pelo DPO; (2) os logs de auditoria com timestamp, finalidade, campos retornados e campos descartados por consulta; (3) as justificativas documentadas para cada campo utilizado, com base legal e alternativas avaliadas. Esses documentos são a evidência concreta de conformidade ativa em caso de inspeção.

A API CPFHub.io retorna todos os campos sempre, ou é possível solicitar apenas os necessários?

A CPFHub.io retorna o objeto completo {"cpf","name","nameUpper","gender","birthDate","day","month","year"} em toda consulta. O filtro de necessidade deve ser aplicado na sua camada de aplicação, descartando os campos que não são necessários para a finalidade declarada antes de qualquer persistência. O plano gratuito oferece 50 consultas mensais sem cartão de crédito; se o limite for ultrapassado, a API cobra R$0,15 por consulta adicional sem bloquear o serviço.


Conclusão

O princípio da necessidade é um dos pilares mais práticos da LGPD e tem impacto direto na forma como sistemas consomem APIs de dados de CPF. Ao implementar filtros de necessidade por finalidade, controles de retenção automáticos e documentação de justificativas, sua empresa demonstra conformidade ativa e reduz significativamente os riscos associados ao tratamento de dados pessoais.

A API do CPFHub.io entrega os dados necessários em ~900ms e você controla o que sua aplicação armazena — exatamente o que o princípio da necessidade exige.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

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.

WhatsAppFale conosco via WhatsApp