Segurança & LGPD · Inventário de dados

Segurança e dados pessoais

O que o app trata, qual a base legal sob a LGPD e como cada dado é protegido. Princípio de fundo: minimização — só guardamos o que um recurso realmente exige, pelo menor tempo possível, e nunca em texto claro quando dá para evitar.

← Voltar à documentação

Mantenha este documento verdadeiro conforme o código evolui. Ele é o inventário de tratamento de dados do projeto.

Inventário de dados

DadoOnde / por quêBase legalProteção
Token de dispositivo (credencial pseudônima, sem login) Identifica o aparelho para salvar listas na nuvem e registrar consentimento. Consentimento (toggle "Salvar listas na nuvem"). No app: secure storage/Keystore. No servidor: nunca armazenado em texto — as chaves do Redis usam um hash SHA-256 salgado do token (como um hash de senha). Um dump do Redis não revela token utilizável nem liga um token conhecido aos seus dados. Nunca é logado.
Id anônimo de medição Estimar usuários únicos (audiência). Legítimo interesse, com opt-out. Só entra salgado em um HyperLogLog (cardinalidade agregada, irreversível). Sem registro por dispositivo. Detalhes na LIA.
Localização (lat/lon) Buscar preços perto do usuário (raio). Execução do serviço pedido pelo usuário. Não é armazenada. Usada de forma transitória na chamada à SEFAZ e arredondada (~11 m) só na chave de cache. Não vai para logs (a busca é POST). Nenhum evento de analytics guarda coordenada.
Listas de compras Links compartilháveis e histórico na nuvem (quando há consentimento). Consentimento (nuvem) / execução do serviço (link). Guardadas sob UUID, ligadas ao dispositivo só via o hash acima. Apagáveis (direito de eliminação). TTL ocioso de 30/90 dias.
Endereço IP Limite diário de buscas (anti-abuso). Legítimo interesse (segurança/abuso). Nunca em texto: a chave do limite guarda apenas um hash salgado do IP, com TTL de 24 h. Bucketiza o cliente sem manter endereços em disco.
Texto de feedback (👍/👎, "item errado", nota livre) Detectar erros de normalização da IA. Legítimo interesse. Anônimo (o token de dispositivo não é gravado junto). Fica em um stream limitado (1000 itens) visível só no painel admin.
Termos buscados Ranking de itens mais buscados / não encontrados. Legítimo interesse. Agregados por contagem (sorted set), sem ligação a usuário. O feed de eventos guarda só nº de itens, taxa de acerto e fonte — sem os termos por usuário, sem token, sem IP.

Segredos de terceiros (token SEFAZ, chaves)

Credenciais que o backend usa para falar com terceiros (o AppToken da SEFAZ é o caso atual) não ficam no repositório, no .env, em logs nem em nenhuma resposta de API. Elas são informadas uma vez pelo painel admin (Configurações), criptografadas com Fernet (AES-128-CBC + HMAC) e guardadas no Redis. O painel só mostra uma impressão digital curta para o operador confirmar qual valor está ativo — o valor em si nunca é devolvido. A troca (rotação) vale na hora, sem reiniciar.

Modelo de ameaça honesto

O backend precisa enviar o token à SEFAZ em texto claro, então o processo precisa ter o valor em memória. Nenhum esquema esconde um segredo de quem tem root na mesma máquina (é possível ler a memória do processo ou a chave de descriptografia). Hashear também não serve: é via única, e precisamos do valor de volta. O que esta arquitetura garante de fato:

A única chave residual é a SECRET_ENCRYPTION_KEY (chave Fernet), no .env do servidor. Texto cifrado (Redis) e chave (env) ficam em locais separados — nenhum deles sozinho vaza o segredo. Esconder de root de verdade exigiria um KMS/HSM externo, que esta VPS única não tem.

Direitos do titular

Referências