Integrações22 min leitura

LGPD para desenvolvedores: o que você precisa implementar no código

Guia técnico e prático da Lei Geral de Proteção de Dados para devs — com checklist de implementação, exemplos de código e as multas que você precisa evitar.

NuPtechs

Engenharia de Software

Principais pontos
  • LGPD exige base legal para cada dado coletado — consentimento é só uma das 10 bases legais
  • Direitos do titular que o sistema deve implementar: acesso, correção, exclusão, portabilidade
  • Dados sensíveis (saúde, biometria, orientação sexual) têm proteção reforçada — base legal explícita obrigatória
  • Pseudonimização e criptografia em repouso não são opcionais para dados pessoais em produção
  • Multa máxima: 2% do faturamento, até R$ 50 milhões por infração — a conformidade é mais barata
  • Privacy by Design é a abordagem mais eficiente: projetar o sistema com LGPD desde o início

O que a LGPD exige de um sistema de software

A LGPD (Lei 13.709/2018) estabelece regras para como dados pessoais de cidadãos brasileiros são coletados, armazenados e processados — em qualquer software, independente de onde a empresa está sediada. Se o seu sistema processa dados de pessoas no Brasil, a LGPD se aplica.

Do ponto de vista de engenharia, a LGPD exige que o sistema:

  1. Colete apenas o necessário (princípio da minimização) — cada campo no formulário de cadastro deve ter uma justificativa documentada.
  2. Tenha base legal documentada para cada dado coletado — não basta coletar, precisa registrar por quê.
  3. Implemente os direitos do titular (acesso, correção, exclusão, portabilidade, revogação de consentimento, entre outros).
  4. Proteja os dados com controles técnicos (criptografia, pseudonimização, controle de acesso, auditoria).
  5. Notifique violações à ANPD e aos titulares afetados em prazo razoável (a prática recomendada é 72 horas).
  6. Mantenha registro de atividades de tratamento (ROPA — Record of Processing Activities) atualizado.

O erro mais comum: tratar LGPD como um "projeto do jurídico" que o dev só implementa quando alguém pede. Na prática, 90% da conformidade com LGPD é engenharia — queries de exportação, criptografia, controle de acesso, TTL de dados, pipeline de anonimização. O jurídico define as regras; o dev as implementa no código.

Quem fiscaliza e qual o risco real

A ANPD (Autoridade Nacional de Proteção de Dados) é o órgão fiscalizador. Desde 2023, sanções administrativas estão sendo aplicadas:

  • Advertência: Para infrações de cadastro e registro (ROPA incompleto, política de privacidade inadequada).
  • Multa simples: Até 2% do faturamento no Brasil, limitado a R$ 50 milhões por infração.
  • Multa diária: Para descumprimento de determinações — R$ 50 milhões de teto acumulado.
  • Publicização da infração: A ANPD publica o nome da empresa — dano reputacional frequentemente supera a multa.
  • Bloqueio/eliminação dos dados: A ANPD pode determinar que você pare de usar os dados até se conformar.

Para PMEs, o risco mais real não é a multa de R$ 50 milhões (que se aplica a empresas grandes), mas sim a publicização da infração e a perda de contratos B2B — empresas grandes cada vez mais exigem conformidade LGPD de fornecedores.

Multas reais da ANPD

A ANPD já aplicou sanções desde 2023. Multa máxima: 2% do faturamento bruto no Brasil, limitado a R$ 50 milhões por infração. Para PMEs, o risco reputacional de uma violação pública é frequentemente maior que a multa financeira.

As 10 bases legais: quando usar cada uma no código

A LGPD define 10 bases legais para processar dados pessoais. O erro mais comum é usar consentimento para tudo — quando outras bases são mais simples e robustas.

As 4 bases legais mais usadas em software

  • Consentimento (Art. 7°, I): O titular autoriza explicitamente. Requer opt-in ativo (sem checkboxes pré-marcados), finalidade específica, e opt-out fácil a qualquer momento. Use para: newsletters, marketing, analytics, compartilhamento com terceiros.
  • Execução de contrato (Art. 7°, V): Dados necessários para entregar o serviço contratado. Use para: endereço de entrega, dados de pagamento, e-mail para envio de NF, telefone para suporte do pedido. Não precisa de consentimento separado — o contrato é a base legal.
  • Legítimo interesse (Art. 7°, IX): A base mais flexível — permite processamento quando há interesse legítimo e razoável, sem prejudicar direitos do titular. Use para: prevenção a fraude, personalização de UX, análise de padrões de uso, segurança do sistema. Requer LIA (Legitimate Interest Assessment) documentado.
  • Cumprimento de obrigação legal (Art. 7°, II): Dados exigidos por lei. Use para: CPF em NF, registros contábeis, dados trabalhistas, retenção fiscal. Não precisa de consentimento e o titular não pode pedir exclusão desses dados.

As 6 bases menos comuns (mas que aparecem)

  • Pela administração pública: Para execução de políticas públicas.
  • Para estudos e pesquisa: Dados anonimizados para pesquisa (ex: analytics agregados).
  • Para exercício regular de direitos: Dados necessários para defesa em processo judicial.
  • Para proteção da vida: Em situações de emergência (ex: dados de saúde em UTI).
  • Para tutela da saúde: Processamento por profissionais de saúde.
  • Para proteção do crédito: Dados necessários para análise de crédito (ex: score Serasa).

Como documentar no banco de dados

Crie um registro de atividades de tratamento (ROPA) como tabela no banco. Cada tipo de dado deve ter base legal documentada:

CREATE TABLE data_processing_register (
  id SERIAL PRIMARY KEY,
  data_category VARCHAR(100) NOT NULL,  -- ex: "email", "endereço", "CPF"
  purpose VARCHAR(255) NOT NULL,        -- finalidade do processamento
  legal_basis VARCHAR(50) NOT NULL,     -- "consent", "contract", "legal_obligation", "legitimate_interest"
  retention_period INTERVAL NOT NULL,   -- prazo de retenção
  data_controller VARCHAR(100),         -- quem decide o processamento
  data_processor VARCHAR(100),          -- quem processa (se terceirizado)
  international_transfer BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Exemplos de registro
INSERT INTO data_processing_register (data_category, purpose, legal_basis, retention_period) VALUES
('email', 'Comunicação sobre pedidos', 'contract', '5 years'),
('email', 'Newsletter marketing', 'consent', '2 years'),
('cpf', 'Emissão de nota fiscal', 'legal_obligation', '5 years'),
('endereço', 'Entrega de produtos', 'contract', '5 years'),
('histórico de navegação', 'Personalização de UX', 'legitimate_interest', '6 months'),
('biometria facial', 'Autenticação', 'consent', '1 year');

Regra prática: Se o dado é necessário para entregar o serviço contratado → execução de contrato. Se é exigido por lei → obrigação legal. Se é para marketing ou analytics → consentimento. Se é para segurança/fraude → legítimo interesse. Na dúvida, peça opinião do DPO.

Consentimento não é a única base legal

O erro mais comum: coletar consentimento para tudo. Para dados necessários à execução do contrato (endereço de entrega, e-mail para NF), a base é execução de contrato — não consentimento. Para segurança e fraude, use legítimo interesse. Isso simplifica a implementação.

Implementando os 8 direitos do titular no código

O titular pode exercer 8 direitos previstos no Art. 18 da LGPD. Seu sistema precisa implementar endpoints ou interfaces para cada um:

1. Direito de confirmação e acesso (Art. 18, I e II)

O titular pergunta "vocês têm dados sobre mim?" e "quais são?". O sistema deve exportar todos os dados pessoais em formato legível:

-- Query de exportação completa por usuário
SELECT 
  u.name, u.email, u.phone, u.cpf, u.created_at as member_since,
  json_agg(DISTINCT jsonb_build_object('id', o.id, 'date', o.created_at, 'total', o.total)) as orders,
  json_agg(DISTINCT jsonb_build_object('street', a.street, 'city', a.city, 'state', a.state)) as addresses,
  json_agg(DISTINCT jsonb_build_object('type', c.type, 'granted_at', c.created_at, 'revoked_at', c.revoked_at)) as consents
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
LEFT JOIN addresses a ON a.user_id = u.id
LEFT JOIN user_consents c ON c.user_id = u.id
WHERE u.id = $1
GROUP BY u.id;

Dica: Crie um endpoint /api/me/data-export que retorna JSON e oferece download em CSV. O prazo legal para resposta é 15 dias.

2. Direito de correção (Art. 18, III)

Interface para o próprio usuário corrigir dados pessoais (nome, endereço, telefone). Implemente com log de auditoria:

// Middleware de auditoria para correção de dados
async function updateUserData(userId, field, oldValue, newValue) {
  await pool.query(
    'UPDATE users SET $1:name = $2 WHERE id = $3',
    [field, newValue, userId]
  );
  await pool.query(
    `INSERT INTO audit_log (user_id, action, field, old_value, new_value, ip_address)
     VALUES ($1, 'data_correction', $2, $3, $4, $5)`,
    [userId, field, oldValue, newValue, req.ip]
  );
}

3. Direito de anonimização, bloqueio ou eliminação (Art. 18, IV)

Soft delete + anonimização é preferível a DELETE por questões de integridade referencial:

-- Pipeline de anonimização (preferível ao DELETE)
BEGIN;
  UPDATE users SET
    name = 'ANONIMIZADO',
    email = 'anonimizado_' || id || '@removido.invalid',
    phone = NULL,
    cpf = NULL,
    address = NULL,
    anonymized_at = NOW(),
    anonymization_reason = 'titular_request'
  WHERE id = $1;
  
  -- Manter dados com obrigação legal (NF requer CPF por 5 anos)
  -- NÃO anonimizar registros fiscais dentro do prazo de retenção
  
  UPDATE user_consents SET revoked_at = NOW() WHERE user_id = $1 AND revoked_at IS NULL;
  
  INSERT INTO audit_log (user_id, action, details) 
  VALUES ($1, 'anonymization', 'Solicitação do titular via SAC');
COMMIT;

4. Direito de portabilidade (Art. 18, V)

Exportar dados em formato estruturado e interoperável (JSON, CSV). Endpoint dedicado com rate limiting:

router.get('/me/data-export', rateLimiter({ max: 3, windowMs: 24 * 60 * 60 * 1000 }), asyncHandler(async (req, res) => {
  const data = await userRepository.exportUserData(req.user.id);
  res.setHeader('Content-Disposition', 'attachment; filename="meus-dados.json"');
  res.json(data);
}));

5. Direito de revogação de consentimento (Art. 18, IX)

Obrigatório para dados coletados com base em consentimento. Deve ser tão fácil revogar quanto foi consentir:

-- Tabela de gestão de consentimento
CREATE TABLE user_consents (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  consent_type VARCHAR(50) NOT NULL,   -- 'marketing_email', 'analytics', 'data_sharing'
  granted_at TIMESTAMP NOT NULL DEFAULT NOW(),
  revoked_at TIMESTAMP,                -- NULL = ativo
  ip_address INET,
  user_agent TEXT
);

-- Revogar consentimento
UPDATE user_consents 
SET revoked_at = NOW() 
WHERE user_id = $1 AND consent_type = $2 AND revoked_at IS NULL;

6-8. Direitos menos implementados (mas obrigatórios)

  • Informação sobre compartilhamento (Art. 18, VII): O titular pode perguntar com quem você compartilha os dados dele. Mantenha registro de todos os terceiros que recebem dados (sub-processadores, APIs externas).
  • Informação sobre a possibilidade de não consentir (Art. 18, VIII): Antes de coletar consentimento, informe as consequências de não consentir. Ex: "sem consentimento para newsletter, você não receberá ofertas por e-mail, mas poderá usar o serviço normalmente."
  • Revisão de decisões automatizadas (Art. 20): Se o sistema usa IA para decisões que afetam o titular (aprovação de crédito, classificação de risco, precificação), o titular pode pedir revisão humana. Implemente um flag requires_human_review e uma fila para revisão.
Privacy by Design

A forma mais eficiente de conformidade é projetar o sistema já com LGPD em mente — não adicionar compliance depois. Pergunte em todo novo campo: 'Realmente precisamos desse dado?' Dado que não existe não pode vazar.

Controles técnicos obrigatórios: o mínimo que o código precisa ter

Criptografia em repouso

Dados sensíveis (CPF, cartão, senha, dados de saúde, biometria) devem ser criptografados no banco de dados. Para PostgreSQL, use pgcrypto:

-- Habilitar extensão
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- Inserir CPF criptografado (symmetric key - para dados que precisam ser decriptografados)
INSERT INTO users (name, cpf_encrypted) 
VALUES ('João', pgp_sym_encrypt('123.456.789-00', current_setting('app.encryption_key')));

-- Ler CPF decriptografado
SELECT name, pgp_sym_decrypt(cpf_encrypted::bytea, current_setting('app.encryption_key')) as cpf
FROM users WHERE id = 1;

-- Para dados que só precisam ser comparados (ex: busca por CPF), use hash:
INSERT INTO users (name, cpf_hash)
VALUES ('João', crypt('12345678900', gen_salt('bf')));

-- Buscar por CPF sem decriptar:
SELECT * FROM users WHERE cpf_hash = crypt('12345678900', cpf_hash);

Chave de criptografia: Nunca hardcode no código. Use variável de ambiente ou secret manager (AWS Secrets Manager, HashiCorp Vault). Rotacione a chave a cada 90 dias.

Pseudonimização de logs

Logs de aplicação nunca devem conter dados pessoais em texto claro. Se um log vazar, nenhum dado pessoal deve ser exposto:

// ❌ Errado — CPF, e-mail e nome em log
logger.info(`Usuário ${user.name} (${user.email}, CPF ${user.cpf}) fez login`);

// ✅ Correto — usar identificador interno
logger.info(`Usuário #${user.id} fez login, IP ${req.ip}`);

// ✅ Se precisar de mais contexto, use hash truncado
const userHash = crypto.createHash('sha256').update(user.email).digest('hex').slice(0, 8);
logger.info(`Usuário ${userHash} fez login`);

Controle de acesso granular (RBAC + Row-Level Security)

Princípio do mínimo privilégio: cada serviço/usuário acessa apenas os dados que precisa.

-- PostgreSQL Row-Level Security
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Política: vendedores veem apenas pedidos da sua região
CREATE POLICY seller_orders ON orders
  FOR SELECT TO seller_role
  USING (region_id = current_setting('app.user_region')::int);

-- Política: clientes veem apenas seus próprios pedidos
CREATE POLICY customer_orders ON orders
  FOR SELECT TO customer_role
  USING (user_id = current_setting('app.user_id')::int);

TTL automático de dados

Dados com prazo de retenção definido devem ser automaticamente expirados:

-- Job de limpeza (executar diariamente via cron ou pg_cron)
DELETE FROM user_sessions WHERE expires_at < NOW();
DELETE FROM password_reset_tokens WHERE created_at < NOW() - INTERVAL '24 hours';

-- Anonimizar dados de usuários inativos há mais de 2 anos
UPDATE users SET
  name = 'INATIVO', email = 'inativo_' || id || '@expired.invalid',
  phone = NULL, cpf = NULL, anonymized_at = NOW()
WHERE last_login < NOW() - INTERVAL '2 years' AND anonymized_at IS NULL;
Schema separado para PII

Isole dados pessoais em um schema dedicado (personal_data). Para exportação, anonimização e exclusão, o escopo fica claro. Para auditoria, basta monitorar um schema.

Dados sensíveis: tratamento especial obrigatório

A LGPD diferencia "dados pessoais" de "dados pessoais sensíveis" (Art. 5°, II). Dados sensíveis têm proteção reforçada e requerem base legal mais restrita.

O que são dados sensíveis

  • Origem racial ou étnica
  • Convicção religiosa
  • Opinião política
  • Filiação a sindicato ou organização religiosa/filosófica/política
  • Dados de saúde (diagnósticos, exames, medicamentos)
  • Dados genéticos
  • Dados biométricos (reconhecimento facial, impressão digital)
  • Vida sexual ou orientação sexual

Regras específicas para dados sensíveis

Dados sensíveis só podem ser tratados com (Art. 11):

  • Consentimento específico e destacado: Não basta um checkbox genérico. O consentimento para dados sensíveis deve ser separado, com explicação clara de para que serão usados.
  • Sem consentimento, apenas em 7 hipóteses específicas: obrigação legal, política pública, pesquisa (anonimizado), exercício regular de direitos, proteção da vida, tutela da saúde, prevenção à fraude.

Implementação técnica

// Middleware para validar acesso a dados sensíveis
function sensitiveDataGuard(requiredPermission) {
  return (req, res, next) => {
    if (!req.user.permissions.includes(requiredPermission)) {
      // Log de tentativa de acesso não autorizado
      auditLogger.warn({
        userId: req.user.id,
        action: 'sensitive_data_access_denied',
        resource: requiredPermission,
        ip: req.ip
      });
      return res.status(403).json({ error: 'Acesso a dados sensíveis negado' });
    }
    // Log de acesso autorizado (obrigatório para auditoria)
    auditLogger.info({
      userId: req.user.id,
      action: 'sensitive_data_access_granted',
      resource: requiredPermission,
      ip: req.ip
    });
    next();
  };
}

// Uso: apenas médicos acessam dados de saúde
router.get('/patients/:id/health-data', 
  sensitiveDataGuard('health_data.read'),
  asyncHandler(async (req, res) => { /* ... */ })
);

Recomendação: Dados sensíveis devem estar em tabelas separadas com criptografia em repouso obrigatória e log de acesso em cada leitura. Nunca misture dados sensíveis com dados comuns na mesma tabela — isso facilita tanto o controle de acesso quanto a auditoria.

Dados sensíveis ≠ dados pessoais

Saúde, biometria, religião, orientação sexual, opinião política — são dados sensíveis com proteção reforçada. Requerem consentimento específico e destacado, criptografia obrigatória e log de acesso em cada leitura.

Plano de resposta a incidentes de dados

A LGPD exige que incidentes de segurança envolvendo dados pessoais sejam comunicados à ANPD e aos titulares afetados. Não ter um plano é garantia de caos quando (não se) o incidente acontecer.

Prioridade 1: Detecção (horas 0-4)

  • Alertas automáticos para: acesso massivo a dados pessoais, export de dados acima do volume normal, tentativas de login anômalas, queries incomuns no banco
  • Dashboard de segurança com métricas: logins falhados/hora, acessos a dados sensíveis, volume de dados exportados
  • Canais de denúncia interno (para funcionários reportarem incidentes)

Prioridade 2: Contenção (horas 4-24)

  • Isolar o vetor de ataque (bloquear a conta comprometida, revogar tokens, fechar a vulnerabilidade)
  • Preservar evidências (logs, snapshots de banco, registros de acesso)
  • Avaliar o escopo: quantos registros afetados? Quais tipos de dados? Quais titulares?

Prioridade 3: Notificação (até 72h)

Comunicar à ANPD contendo:

  • Descrição da natureza dos dados pessoais afetados
  • Informações sobre os titulares envolvidos (quantidade, categorias)
  • Indicação das medidas técnicas de segurança utilizadas
  • Riscos relacionados ao incidente
  • Medidas tomadas para reverter ou mitigar os efeitos

Implementação técnica: detecção automática

// Middleware de detecção de anomalias em acesso a dados
const THRESHOLD_EXPORTS_PER_HOUR = 5;
const THRESHOLD_RECORDS_PER_QUERY = 1000;

async function dataAccessMonitor(req, res, next) {
  const recentExports = await redis.incr(`exports:${req.user.id}:${currentHour()}`);
  await redis.expire(`exports:${req.user.id}:${currentHour()}`, 3600);
  
  if (recentExports > THRESHOLD_EXPORTS_PER_HOUR) {
    securityAlert.send({
      type: 'anomalous_data_export',
      userId: req.user.id,
      count: recentExports,
      severity: 'high'
    });
  }
  next();
}

Cookies, tracking e analytics: o que muda com a LGPD

Cookies e scripts de tracking são dados pessoais quando permitem identificar o usuário (direta ou indiretamente). A LGPD exige consentimento antes de instalar cookies não essenciais.

Classificação de cookies

TipoExemplosBase legalConsentimento?
EssenciaisSessão, CSRF, carrinhoExecução de contrato / Legítimo interesseNão
FuncionaisIdioma, preferências de UILegítimo interesseRecomendado
AnalyticsGoogle Analytics, Hotjar, MixpanelConsentimentoSim
Marketing/RetargetingFacebook Pixel, Google Ads, LinkedIn InsightConsentimentoSim

Implementação do cookie banner

  • Carregamento bloqueante: Scripts de analytics e marketing só devem ser carregados APÓS o consentimento. Não basta mostrar o banner — se o Google Analytics já estava rodando, não adianta.
  • Granularidade: Ofereça controle por categoria (analytics sim, marketing não). Um botão "aceitar tudo" é permitido desde que haja alternativa granular.
  • Registro: Salve o consentimento no banco (user_id, tipo, data, IP). O ônus da prova do consentimento é do controlador.
  • Revogação: Link acessível em todas as páginas para revogar consentimento de cookies. Geralmente no rodapé.
// Exemplo: carregar Google Analytics apenas com consentimento
function loadAnalytics() {
  const consent = getCookieConsent();
  if (consent?.analytics) {
    const script = document.createElement('script');
    script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_ID}`;
    script.async = true;
    document.head.appendChild(script);
  }
}

// Chamar apenas após consentimento
onConsentGranted('analytics', loadAnalytics);

Google Analytics 4 e LGPD: O GA4 permite configurar coleta sem cookies (consent mode) e anonimização de IP. Configure anonymize_ip: true e ads_storage: 'denied' por padrão. Habilite 'granted' apenas após consentimento explícito.

LGPD vs GDPR: diferenças práticas para quem implementa

Se o sistema atende clientes na Europa, você precisa cumprir GDPR também. As leis são similares, mas há diferenças práticas importantes:

AspectoLGPD (Brasil)GDPR (Europa)
DPO obrigatório?Sim (com exceções para PMEs)Sim (quando processa dados em larga escala)
Notificação de breach"Prazo razoável" (~72h recomendado)72 horas (obrigatório)
Multa máxima2% faturamento / R$ 50M4% faturamento global / € 20M
Bases legais10 bases6 bases (sem crédito, sem saúde separada)
Transferência internacionalPermitida com cláusulas contratuaisMais rígida (SCCs, Binding Corporate Rules)
Consentimento de menores<12 anos: obrigatório dos pais<16 anos: obrigatório dos pais (varia por país)

Dica prática: Se implementar para GDPR (mais rígido), automaticamente cobre a LGPD. A exceção são as 4 bases legais adicionais da LGPD (crédito, saúde, exercício de direitos, políticas públicas) — que raramente afetam software privado.

Transferência internacional de dados

Se o sistema usa APIs que enviam dados para fora do Brasil (OpenAI, AWS, Google Cloud, Stripe), configure:

  • Cláusulas contratuais padrão (SCCs): A maioria dos grandes providers já oferece (AWS DPA, Google DPA, OpenAI DPA). Verifique e documente.
  • Avaliação de impacto: Documente quais dados saem do país, para onde, e quais proteções o provider oferece.
  • Alternativa local: Para dados muito sensíveis, considere providers com data center no Brasil (AWS São Paulo, Azure Brasil, Google São Paulo).

Privacy by Design: padrões arquiteturais que simplificam compliance

A abordagem mais eficiente para LGPD não é "adicionar compliance depois" — é projetar o sistema com privacidade desde o início. Estes padrões arquiteturais tornam a conformidade natural em vez de dolorosa:

1. Separação de dados pessoais em schema dedicado

-- Schema separado para dados pessoais
CREATE SCHEMA personal_data;

-- Dados pessoais isolados
CREATE TABLE personal_data.profiles (
  user_id INTEGER PRIMARY KEY,
  name_encrypted BYTEA,
  email_encrypted BYTEA,
  cpf_hash TEXT,
  phone_encrypted BYTEA
);

-- Dados de negócio referenciando sem conter PII
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL,  -- FK, mas sem dados pessoais nesta tabela
  total DECIMAL, status TEXT, created_at TIMESTAMP
);

Benefício: Para exportação de dados, anonimização e exclusão, o escopo é sempre o schema personal_data — não precisa varrer 50 tabelas.

2. Padrão "data minimization by query"

// ❌ Busca tudo e filtra no código (expõe dados desnecessários)
const user = await db.query('SELECT * FROM users WHERE id = $1', [id]);
res.json(user); // expõe CPF, endereço, telefone — tudo

// ✅ Selecione apenas os campos necessários para a tela
const user = await db.query(
  'SELECT id, name, avatar_url FROM users WHERE id = $1', [id]
);
res.json(user); // expõe apenas o necessário

3. Campos de consentimento como first-class citizen

Ao invés de um cookie banner como gambiarra, trate consentimento como entidade de domínio:

  • Tabela user_consents com tipo, data, IP, user agent
  • Middleware que verifica consentimento antes de processar marketing/analytics
  • API de gestão de consentimento (/me/consents) no frontend

4. Audit trail obrigatório para dados pessoais

Toda leitura, escrita e exclusão de dados pessoais deve ser registrada. Use triggers ou middleware:

-- Trigger de auditoria automática
CREATE OR REPLACE FUNCTION audit_personal_data() RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO audit_log (table_name, record_id, action, old_data, new_data, performed_by, performed_at)
  VALUES (TG_TABLE_NAME, COALESCE(NEW.id, OLD.id), TG_OP, 
    CASE WHEN TG_OP = 'DELETE' THEN row_to_json(OLD) ELSE NULL END,
    CASE WHEN TG_OP != 'DELETE' THEN row_to_json(NEW) ELSE NULL END,
    current_setting('app.user_id', true),
    NOW());
  RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER audit_users AFTER INSERT OR UPDATE OR DELETE ON personal_data.profiles
FOR EACH ROW EXECUTE FUNCTION audit_personal_data();

5. Perguntas de design review para cada nova feature

  • Quais dados pessoais essa feature coleta ou processa?
  • Qual a base legal para cada um? Está documentado no ROPA?
  • Os dados são o mínimo necessário? Podemos funcionar com menos?
  • Onde os dados são armazenados? Estão criptografados?
  • Qual o prazo de retenção? Tem TTL automático?
  • O titular consegue acessar, corrigir e excluir esses dados?

Checklist completo de conformidade LGPD para devs

Documentação e governança

  • ☐ Mapeamento de dados pessoais (quais dados, onde armazenados, por que, por quanto tempo)
  • ☐ Registro de atividades de tratamento (ROPA) no banco — tabela data_processing_register
  • ☐ Política de privacidade clara e acessível no frontend (link em todas as páginas)
  • ☐ DPO (Data Protection Officer) designado — pode ser interno ou terceirizado
  • ☐ Avaliação de impacto (DPIA) para processamentos de alto risco

Consentimento e direitos

  • ☐ Formulário de consentimento com finalidade específica (sem checkboxes pré-marcados)
  • ☐ Mecanismo de opt-out funcional e tão fácil quanto o opt-in
  • ☐ Cookie banner com carregamento bloqueante (scripts só após consentimento)
  • ☐ API/interface de exportação de dados (portabilidade) — /me/data-export
  • ☐ Processo de exclusão/anonimização documentado e testado
  • ☐ Interface de gestão de consentimentos (/me/consents) no frontend
  • ☐ Fluxo de revisão de decisões automatizadas (se usa IA para decisões)

Segurança técnica

  • ☐ Criptografia em repouso para dados sensíveis (pgcrypto, AES-256)
  • ☐ Criptografia em trânsito (HTTPS obrigatório, TLS 1.2+)
  • ☐ Pseudonimização em logs e ambientes de dev/staging
  • ☐ Row-Level Security no PostgreSQL para controle de acesso granular
  • ☐ Controle de acesso baseado em roles com princípio do menor privilégio
  • ☐ Política de retenção de dados com TTL automatizado (cron/pg_cron)
  • ☐ Chaves de criptografia em secret manager (não em variáveis de ambiente)
  • ☐ Rotação de chaves a cada 90 dias

Monitoramento e incidentes

  • ☐ Audit trail para toda operação em dados pessoais (trigger no banco)
  • ☐ Alertas de anomalia (export massivo, tentativas de acesso, queries incomuns)
  • ☐ Plano de resposta a incidentes documentado e testado
  • ☐ Template de notificação à ANPD pré-preenchido
  • ☐ Simulação de incidente a cada 6 meses (tabletop exercise)

Ambiente de desenvolvimento

  • ☐ Banco de dev/staging com dados anonimizados (nunca usar dump de produção sem anonimizar)
  • ☐ .env e secrets fora do controle de versão (.gitignore)
  • ☐ CI/CD com scan de secrets (git-secrets, truffleHog)
  • ☐ Testes automatizados para endpoints de direitos do titular (exportação, anonimização)

Mapa Mental

5 ramos · 28 conceitos · Ferramenta de revisão

LGPD para Devs
Técnica mnemônica

Use para navegar · Espaço para expandir