- 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:
- Colete apenas o necessário (princípio da minimização) — cada campo no formulário de cadastro deve ter uma justificativa documentada.
- Tenha base legal documentada para cada dado coletado — não basta coletar, precisa registrar por quê.
- Implemente os direitos do titular (acesso, correção, exclusão, portabilidade, revogação de consentimento, entre outros).
- Proteja os dados com controles técnicos (criptografia, pseudonimização, controle de acesso, auditoria).
- Notifique violações à ANPD e aos titulares afetados em prazo razoável (a prática recomendada é 72 horas).
- 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.
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.
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_reviewe uma fila para revisão.
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;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.
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();
}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:
| Aspecto | LGPD (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áxima | 2% faturamento / R$ 50M | 4% faturamento global / € 20M |
| Bases legais | 10 bases | 6 bases (sem crédito, sem saúde separada) |
| Transferência internacional | Permitida com cláusulas contratuais | Mais 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ário3. 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_consentscom 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
Use ← → para navegar · Espaço para expandir