UpuaiUpuai

LGPD para times técnicos: checklist prático além do banner de cookies

LGPD para dev/CTO em 2026: além do banner. Direitos do titular, logs com PII, backups, transferência internacional, base legal por campo — checklist técnico real.

Equipe Upuai · Upuai Cloud 13 min de leitura

A primeira vaga de panic sobre LGPD foi em 2020. Empresas instalaram banner de cookies, contrataram DPO, publicaram política de privacidade, e seguiram em frente. Acharam que tinham resolvido.

Em 2024-2025, a ANPD começou a aplicar multas significativas. Setor financeiro, healthtech, e-commerce. Multas de centenas de milhares a milhões de reais. E aí a empresa percebe: o banner não resolve nada. LGPD é trabalho de engenharia contínuo.

Esse post é o checklist técnico que ninguém entrega no curso de uma tarde de compliance. Direitos do titular, PII em logs, backups, transferência internacional, base legal por campo. Itens concretos, com código exemplo, prontos pra você levar pro PR.

Complementa o nosso post inaugural LGPD na sua PaaS — que cobriu o “porque” estratégico. Aqui vai o “como” operacional.

Por que LGPD virou rotina do time de engenharia

Em 2020, LGPD era exercício jurídico. Em 2026, é rotina de engenharia. O que mudou:

Multas reais aplicadas (2024-2025):

  • Telecom: R$ 14M (vazamento massivo)
  • Healthtech: R$ 4M (consentimento inadequado)
  • E-commerce: R$ 2M (logs com PII expostos)
  • Diversos casos menores documentados publicamente

Clientes B2B exigindo DPA:

  • Vendor risk assessment formal antes de assinar contrato grande
  • DPA (Data Processing Agreement) com cláusulas específicas
  • Auditoria de subcontratados (vocês usam AWS? Salesforce? Mailgun? Quem mais?)

ANPD ativa:

  • Decisões públicas sobre práticas inadequadas
  • Guias técnicos publicados (relatórios de impacto, transferência internacional, etc.)
  • Notificações administrativas regulares

Marco Civil + LGPD + Decreto setorial:

  • Bancos: Bacen 8.681 + LGPD
  • Saúde: CFM + LGPD + Marco Civil
  • Setor público: LAI + LGPD

A combinação dessas pressões transformou compliance de “responsabilidade do jurídico” pra “responsabilidade compartilhada com engenharia”. Sem código alinhado, jurídico não consegue cumprir.

Direitos do titular (Art. 18) — checklist técnico completo

O Art. 18 da LGPD dá ao titular dos dados (a pessoa física a quem os dados se referem) nove direitos. Cinco têm impacto direto em engenharia:

Direito 1: Confirmação e acesso

“Quais dados meus vocês têm?”

Precisa ter:

  • Endpoint autenticado que retorna todos os dados pessoais do titular
  • Resposta em formato estruturado (JSON estruturado preferido)
  • Tempo máximo de resposta: 15 dias (Art. 19)

Exemplo (Postgres + Node.js Express):

// GET /api/me/personal-data
app.get('/api/me/personal-data', authMiddleware, async (req, res) => {
  const userId = req.user.id
  
  const data = {
    profile: await db.users.findOne({ id: userId }),
    orders: await db.orders.find({ user_id: userId }),
    events: await db.analytics_events.find({ user_id: userId }),
    payments: await db.payments.find({ user_id: userId }),
    consents: await db.consents.find({ user_id: userId }),
    // Inclua TODAS as tabelas com PII desse usuário
  }
  
  res.json({ 
    generatedAt: new Date().toISOString(),
    titular: data 
  })
})

Pegadinha: muitos times esquecem das fontes secundárias — logs de aplicação, eventos analíticos, backups, CDP/CRM externo. Esses também são dados pessoais e contam pro Art. 18.

Direito 2: Correção de dados incompletos ou inexatos

“Corrija meu CPF, está errado.”

Precisa ter:

  • Endpoint pra atualização: PATCH /api/me
  • Propagação para fontes secundárias (CRM externo, mailing list, data warehouse)
  • Auditoria de cada correção (quem mudou, quando, valor antigo + novo)
app.patch('/api/me', authMiddleware, async (req, res) => {
  const userId = req.user.id
  const updates = sanitize(req.body)
  
  const old = await db.users.findOne({ id: userId })
  await db.users.update({ id: userId }, updates)
  
  // Audit log
  await db.audit.create({
    actor: userId,
    action: 'self_update',
    before: old,
    after: { ...old, ...updates },
    timestamp: new Date(),
  })
  
  // Propagação assíncrona
  await queue.push('propagate_user_update', { userId, fields: Object.keys(updates) })
  
  res.json({ ok: true })
})

Direito 3: Anonimização, bloqueio ou eliminação

“Delete tudo.”

Esse é o mais complexo. Não basta UPDATE users SET email = 'deleted@x.com' WHERE id = :id — você precisa:

Eliminação técnica:

  • Deletar registros principais (users, orders, events)
  • Deletar registros derivados (analytics, recommendations baseadas no user)
  • Deletar fontes secundárias (CRM externo, mailing, data warehouse)
  • Deletar do backup recente (ou marcar pra não restaurar)

Anonimização (quando manter dado agregado é base legal):

  • Substituir PII por valores anônimos (user_42 em vez de email real)
  • Atenção a re-identificação por inferência (CEP + data nascimento + gênero re-identifica)
  • Generalizar campos (CEP → estado, data → ano)

Workflow recomendado:

async function deleteUserData(userId) {
  // 1. Soft delete imediato (impede acesso, preserva integridade referencial)
  await db.users.update({ id: userId }, { 
    deleted_at: new Date(),
    email: `deleted-${userId}@deleted.local`,
    name: 'Deleted User',
    cpf: null,
    phone: null,
  })
  
  // 2. Disparar workflow assíncrono de eliminação completa
  await queue.push('full_deletion', { userId, requestedAt: new Date() })
  
  // O workflow vai:
  // - Marcar registros derivados pra deleção
  // - Notificar sistemas externos (CRM, mailing)
  // - Aguardar período legal de retenção (se aplicável — ex: dados fiscais 5 anos)
  // - Eliminar definitivamente após retenção
  // - Gerar audit trail completo
}

Direito 4: Portabilidade dos dados

“Exporta tudo em formato que eu consiga importar em outro lugar.”

Precisa ter:

  • Export em formato estruturado e interoperável (JSON estruturado + esquema documentado)
  • Tabular onde aplicável (CSV pra dados estruturados em colunas)
  • Sem dependência de tecnologia proprietária (dump SQL puro não conta — fornecer modelo em JSON ou Parquet)
app.post('/api/me/export', authMiddleware, async (req, res) => {
  const userId = req.user.id
  
  const exportPackage = {
    schemaVersion: '1.0',
    exportedAt: new Date().toISOString(),
    titular: { id: userId },
    sections: {
      profile: await db.users.findOne({ id: userId }),
      orders: await db.orders.find({ user_id: userId }),
      // ...
    }
  }
  
  // Pra exports grandes, gera arquivo e envia link via email
  const filename = `export-${userId}-${Date.now()}.json`
  await storage.save(filename, JSON.stringify(exportPackage))
  await sendEmail(req.user.email, 'export_ready', { filename })
  
  res.json({ status: 'queued', emailSent: true })
})

Direito 5: Eliminação dos dados tratados com consentimento

Diferente do Direito 3 (delete tudo): aqui o titular revogou consentimento específico e quer só os dados consentidos eliminados. Logs de auditoria que justifiquem base legal diferente (cumprimento de obrigação regulatória, por exemplo) podem ser mantidos.

A engenharia disso exige base legal por campo — discutimos abaixo.

PII em logs: o vazamento mais comum

Em auditoria média de empresa BR, logs de aplicação são a fonte número um de vazamento de PII. Cenário típico:

// ERRADO — vaza CPF nos logs
app.post('/checkout', (req, res) => {
  console.log('Checkout request:', req.body)
  // req.body.cpf agora foi pro Loki, pro S3 de backup, pro DataDog...
})

Os logs vão pra serviço de observabilidade que tipicamente:

  • Roda em outra região (transferência internacional não-documentada)
  • Tem retenção de 30+ dias (sem alinhamento com base legal)
  • É acessível por toda a equipe (sem RBAC por classificação)
  • Não tem masking automático de PII

Solução técnica simples — middleware de sanitização:

const SENSITIVE_FIELDS = [
  'cpf', 'cnpj', 'rg', 'cnh', 
  'password', 'token', 'refreshToken',
  'cardNumber', 'cvv', 'pin',
  'fullAddress', 'phone',
]

function sanitizeForLogs(obj, depth = 0) {
  if (depth > 5) return '[max_depth_reached]'
  if (obj === null || obj === undefined) return obj
  if (typeof obj !== 'object') return obj
  if (Array.isArray(obj)) return obj.map(item => sanitizeForLogs(item, depth + 1))
  
  const clone = {}
  for (const key in obj) {
    if (SENSITIVE_FIELDS.includes(key.toLowerCase())) {
      clone[key] = '[REDACTED]'
    } else if (typeof obj[key] === 'object') {
      clone[key] = sanitizeForLogs(obj[key], depth + 1)
    } else {
      clone[key] = obj[key]
    }
  }
  return clone
}

// Wrapper do logger
function safeLog(message, payload) {
  console.log(message, sanitizeForLogs(payload))
}

// Uso
safeLog('Checkout request:', req.body)  // CPF vai como [REDACTED]

Ainda melhor: estruture logs como objetos (não strings concatenadas), use logger estruturado (pino, winston, bunyan) com hook de sanitização global.

Backups, retenção e o “direito ao esquecimento”

Pegadinha clássica: titular pediu deleção, você deletou do banco principal. Mas o backup de ontem ainda tem os dados. Backup de uma semana atrás também. Replica de standby também.

Tecnicamente, dados nesses backups ainda são “dados pessoais armazenados” sob LGPD. Multas têm sido aplicadas por isso.

Estratégias práticas:

  1. Janela de retenção declarada e curta: documente que backups duram, p.ex., 7 dias. Após 7 dias do delete, o backup mais antigo cai naturalmente. Cliente concorda com a janela.

  2. Restore com filtro de deleções: se você restaurar do backup antigo, aplique a tabela de “deletions pendentes” pra re-deletar registros já solicitados.

  3. Marcação durante backup: registre “deletions pendentes” separadamente, propague pro próximo backup, garanta que restore considere.

  4. Documentação para o titular: quando o titular pede deleção, responda com “deleção imediata aplicada; eliminação completa de backups em até X dias conforme política de retenção”.

Aceitável legalmente — desde que documentado e limitado em tempo.

Transferência internacional (Art. 33)

Você usa PostgreSQL gerenciado da AWS RDS sa-east-1? Tecnicamente o dado está em São Paulo. Mas:

  • A AWS é empresa US.
  • O control plane fica em região US.
  • CLOUD Act se aplica.

ANPD ainda não tem regulação 100% clara sobre se isso conta como “transferência internacional” no sentido do Art. 33. Mas auditores conservadores tratam como sim.

Soluções:

  1. DPA com cláusulas contratuais padrão: AWS, GCP, Azure têm DPAs assináveis com cláusulas standard de transferência internacional. Você assina, documenta.

  2. Localização real no Brasil: provider brasileiro com infra brasileira (Upuai por exemplo) — Art. 33 não se aplica porque não há transferência. Discutimos isso em Soberania digital.

  3. Consentimento específico: inviável em escala. Pra casos especiais.

Pra time pequeno otimizando burocracia, ir direto pra opção 2 (provider BR) simplifica o cumprimento.

LGPD lista 10 bases legais pra tratamento (Art. 7): consentimento, cumprimento de obrigação legal, execução de contrato, exercício regular de direitos, proteção da vida, tutela da saúde, legítimo interesse, etc.

A maioria das empresas registra base legal por usuário (“user X consentiu”). Insuficiente. O correto é base legal por campo:

-- Tabela tradicional (insuficiente)
CREATE TABLE users (
  id UUID PRIMARY KEY,
  email VARCHAR,
  cpf VARCHAR,
  phone VARCHAR,
  consent_marketing BOOLEAN
);

-- Tabela com base legal por campo (correto)
CREATE TABLE user_fields (
  user_id UUID,
  field_name VARCHAR,
  field_value VARCHAR,
  legal_basis ENUM('consent', 'contract', 'legal_obligation', 'legitimate_interest', ...),
  consent_id UUID NULL,  -- se base for consent
  collected_at TIMESTAMP,
  PRIMARY KEY (user_id, field_name)
);

Por que importa: quando o titular revoga consentimento de marketing, você precisa saber quais campos estavam sob consent. Email coletado pra contrato (execute de contrato) continua válido; mesmo email coletado pra newsletter (consent) vai pra fora.

Sem granularidade, você fica em decisão binária: ou mantém tudo, ou deleta tudo. Ambos errados.

Como Upuai já te dá compliance LGPD por design

Pra times rodando na Upuai, vários itens do checklist são resolvidos automaticamente:

Datacenter no Brasil:

  • Não há transferência internacional. Art. 33 não se aplica.

DPA padrão LGPD-ready:

  • Cláusulas alinhadas com LGPD desde o template
  • Foro brasileiro, lei brasileira

Subcontratados restritos:

  • Não usamos serviços US que processam dados de cliente (sem CDN US tipo Cloudflare pra cache de PII; sem analytics US tipo GA4 sem configuração de IP anonimization)
  • Auditoria de subcontratados pública

Suporte BR:

  • Comunicação com o time em português (sem repassar PII de cliente pra suporte estrangeiro durante troubleshooting)

Segurança em repouso e em trânsito:

  • Criptografia ativada por padrão pra databases e storage
  • TLS obrigatório pra todos endpoints

O que continua sendo sua responsabilidade:

  • Implementar os endpoints de direitos do titular (Art. 18)
  • Sanitizar PII em logs da sua aplicação
  • Manter base legal documentada
  • Política de privacidade clara pro seu cliente final

Mas a camada de infra (50% do trabalho) está coberta.

Comparativo: o que cada provider ajuda em LGPD

Aspecto LGPD AWS sa-east-1 Vercel Railway Upuai
Datacenter no Brasil Sim (São Paulo) Edge sim, DB não Não Sim (BH/MG)
Empresa BR Subsidiária Não Não Sim
CLOUD Act se aplica Sim Sim Sim Não
DPA padrão BR-ready Requer addendum GDPR + addendum LGPD GDPR + addendum LGPD Padrão LGPD
Foro brasileiro Negociável Enterprise Não (foro EUA) Não (foro EUA) Sim (foro BR)
Suporte ANPD direto Sim (via subsidiária) Não direto Não direto Sim (jurisdição BR)

Comparativo em mai/2026. AWS sa-east-1 ajuda parcialmente; provider 100% BR simplifica significativamente.

Perguntas frequentes

Quanto tempo eu tenho pra responder pedido de acesso/eliminação? LGPD Art. 19 estabelece 15 dias. Pra eliminação completa de backups, podem ser mais alguns dias documentados em política. Sempre comunique ao titular o prazo realista.

Preciso ter DPO mesmo sendo startup pequena? ANPD ainda está definindo critérios de obrigatoriedade. Setores regulados (saúde, financeiro) sim. Pra startup pequena B2B, pode ser função acumulada (CTO + DPO designado em ata). Vale consulta jurídica setorial.

Como tratar dados de menores de idade? LGPD Art. 14 trata especificamente. Consentimento de um dos pais ou responsáveis. Apps que coletam de menores precisam de fluxo separado de consentimento parental. Plataformas voltadas a crianças têm regras específicas adicionais.

Posso usar Google Analytics e ferramentas US? GA4 com IP anonimization + DPA com cláusulas padrão pode ser usado, mas auditores conservadores recomendam alternativa BR ou self-hosted (Matomo, Plausible self-hosted). Pra setor regulado, definitivamente trocar.

O que faço com dados que já tenho que claramente foram coletados sem base legal adequada? Avalie regularização (obter consentimento agora, com clareza) ou eliminação. Não deixe “dorme em produção”. ANPD costuma ser benevolente com empresas que regularizam proativamente vs encontrar em fiscalização.

Preciso documentar TIDA / DPIA? TIDA (Relatório de Impacto à Proteção de Dados Pessoais) é exigido quando tratamento implica risco alto ao titular. Setores regulados, dados sensíveis (saúde, financeiro), tratamento em larga escala. Pra app B2B comum, documentação simplificada de bases legais geralmente basta.


LGPD é trabalho de engenharia contínuo, não checklist de uma sprint. Pra ver as outras dimensões do tema, leia LGPD na sua PaaS, Soberania digital não é ideologia e Bare metal próprio vs cloud terceirizada.

Faça deploy no Brasil em 5 minutos

PaaS brasileira, preços em Real, infraestrutura LGPD-native.

Ver planos

Artigos relacionados