Repository navigation
Restauração segura contra injeção de prompt, avaliação com dados de terceiros e muito mais cobertura. Como o provedor de IA só vê marcadores, o dado real só reaparece na restauração; agora ela segue regras fixas, que não dependem de o modelo obedecer. Também: nomes do Censo 2022, documentos de mais 21 países, detector opcional com um modelo em português, cache para agentes, kit de conformidade (LGPD), gateway com login único e SIEM, nó do n8n, filtro do Open WebUI, site de documentação e página em português e inglês.
Segurança
- Os dados reais não voltam dentro de links, imagens e URLs. Uma página ou um e-mail lido pela IA pode induzi-la a escrever
; antes, a restauração trocava o marcador e o navegador enviava o CPF real ao site. Vale para markdown (inclusive links por referência e com<...>), autolinks, URLs soltas (inclusivedominio.com/...semhttps://),mailto:, atributos HTML (src,href,srcset,url(...)), argumentos de ferramentas em JSON (inclusive\/e\u002f) e streaming com o link cortado entre pedaços. Domínios confiáveis podem ser liberados em[restauracao] dominios_links. - Chaves de API, tokens e senhas não são restaurados nos argumentos de ferramentas de agentes (
segredos_em_ferramentas = truevolta ao comportamento antigo).ferramentas = falsedesliga a restauração de todos os argumentos. - Marcadores forjados são desarmados: um
[CPF_1]que já chega no texto (escrito numa página, num e-mail ou num documento) vira[CPF#1]antes do envio e nunca é restaurado. - MCP:
restaurar_texto, que devolve os dados reais para a conversa, vem desligada (veu mcp --com-restauracaoliga). A novarestaurar_para_arquivograva a resposta com os dados reais num arquivo local novo (nunca sobrescreve) e devolve só o caminho. - Operador
hash: HMAC-SHA256 com chave derivada só para esse uso e 64 bits na saída ([CPF_3fa2c1d9e07b4a12]); uma colisão gera erro em vez de trocar uma pessoa por outra.VEU_SEGREDOeVEU_SEGREDO_AUDITORIAprecisam ter pelo menos 32 caracteres. - Um teste garante a falha fechada: se a detecção quebrar, a requisição não é enviada ao provedor.
- Gancho de comando:
env | grep KEY,cd x && env,/usr/bin/env,set | grep,export -pedeclare -xtambém são bloqueados (antes, sóenvsozinho).env FOO=1 pytest, que roda um programa, continua liberado. - Marcadores forjados sem colchetes: um
CPF_1escrito por uma página ou um e-mail não vira mais o CPF real quando a IA o repete. O texto não é reescrito (pode ser um nome no código), mas a forma solta deixa de ser restaurada na sessão (Python e JavaScript). - Ferramentas de arquivo do MCP (
restaurar_para_arquivo,anonimizar_arquivo,restaurar_arquivoesalvar_cofre): só criam documentos novos, nunca scripts nem arquivos em pastas ocultas, e nunca sobrescrevem (a criação é exclusiva). Um modelo manipulado não consegue mais gravar um.batna inicialização do Windows nem apagar uma planilha. - Perfis:
--perfileVEU_PERFILnão afrouxam mais o que está escrito noveu.tomlou emVEU_*(antes,--perfil juridicoapagava umbloquear = ["CPF"]do arquivo). veu servir --workers N --perfil X: os processos recebem o perfil (antes, só o principal o aplicava).ler_protegidodo MCP sem SSRF: o modelo escolhe o link, então ele só pode levar a endereços públicos, por https, como na expansão de links do proxy (antes, uma injeção podia mandar ler 169.254.169.254 ou a rede interna). As ferramentas do MCP também não leem mais pastas e arquivos ocultos (.ssh,.aws).- DNS rebinding: a leitura de links confere o endereço a que a conexão chegou de fato, e não só a resposta do DNS na checagem.
- Site sem Google Fonts (quem visita não manda o IP para terceiros), e a página abre a documentação em outra aba, que não compartilha o cofre guardado na aba.
Adicionado
-
Seção
[restauracao]noveu.toml(links,dominios_links,ferramentas,segredos_em_ferramentas) e opçãorestorena biblioteca JavaScript. -
veu restaurar --restaurar-links. -
Modelo de ameaças: fronteiras de confiança, ameaças, defesas e o que o Véu não protege.
-
Casos de restauração compartilhados entre Python e JavaScript (
js/test/restauracao.json), testados inteiros e cortados em qualquer ponto. -
Avaliação com dados de terceiros:
veu avaliar --externo br-agentic|privacy-filter-br|todosbaixa uma vez (versão fixa, conferida pelo sha256) dois conjuntos públicos em português e mede o vazamento, com intervalo de confiança de 95% e a lista dos tipos que estão fora do escopo do Véu. -
Conjunto de desafio congelado (41 textos escritos à mão), incluído no
veu avaliar. Um teste impede editá-lo. -
Comparação com o Microsoft Presidio nos mesmos textos (
scripts/comparar_presidio.py): 2,6% de vazamento do Véu contra 52,0% do Presidio no privacy-filter-br, e 23,3% contra 53,1% no BR-Agentic. -
veu demonstrartesta também ataques à restauração (CPF na URL de uma imagem, chave num link e num comando, marcador forjado) e tem um controle negativo: sai com 3 se o envio direto não vazar, porque nesse caso a demonstração não estaria medindo nada. -
Documentos já mascarados pela metade (
529.982.***-**,***.982.247-**,11.222.333/****-**, e RG, CNH e título com contexto), CNPJ, RG e CEP com espaços e CNH com hífen. No holdout do privacy-filter-br, o vazamento caiu de 20,2% para 6,4%. -
Cache de detecção para agentes que reenviam a conversa inteira a cada turno (Python e JavaScript): textos longos já analisados não são analisados de novo. Guarda só posições e tipos, nunca o texto, com chave BLAKE2 e sal aleatório; no proxy, cada credencial tem o seu espaço.
[deteccao] cache = 0desliga. Acertos e falhas aparecem em/veu/estatisticase/veu/metricas. -
Nomes do Censo 2022 do IBGE: cerca de 5 mil prenomes e 2 mil sobrenomes (
scripts/gerar_nomes_ibge.py). Prenomes que também são palavras comuns no dicionário pt_BR ("Rosa", "Natal") só contam com contexto, e quem é muito mais comum como sobrenome ("Silva") não conta como prenome. No privacy-filter-br, o vazamento de nomes caiu de 15,4% para 1,4%. -
Propagação de nomes confirmados: depois de "Rayane Souza", as menções a "rayane", "RAYANE SOUZA" ou "Jose" (sem acento) no mesmo texto recebem o mesmo marcador.
-
Municípios do IBGE que não começam com um prenome ("Belo Jardim", mas não "Paulo Afonso"), sequências que começam com tipo de logradouro ("Avenida Paulista") ou com São, Santo e Santa e rótulos de formulário ("Razão Social", "Certidão de Nascimento") não são mais lidos como nomes de pessoas.
-
veu gancho comando(PreToolUse de Bash e Grep, ebeforeShellExecutiondo Cursor): o terminal e a busca deixam de ser um atalho para ler segredos. Bloqueia comandos que leem arquivos com segredos (cat .env), que mostram variáveis de ambiente (printenv,echo $OPENAI_API_KEY) e buscas com conteúdo que passariam por.env, chaves oucredentials.json. O plugin do Claude Code já vem com ele. -
veu gancho prompt --exigir-proxybloqueia o prompt quando o agente não está apontado para o proxy do Véu. -
Codex CLI pelo proxy: a Responses API passa a esconder
custom_tool_call(como oapply_patch),local_shell_calle saídas de ferramentas em lista, e a restaurar em streaming a entrada de ferramentas de texto livre, com a mesma política (chaves não voltam, links não recebem dados reais). -
Normalização para a detecção: caracteres invisíveis (largura zero, hífen invisível), hífens tipográficos (
529.982.247‑25copiado do Word) e dígitos e letras de largura total não escondem mais dados do detector. O texto enviado e o restaurado continuam como estavam. Em JavaScript, a máscara de CPF passa a aceitar dígitos de largura total, como em Python. -
Cofre cifrado no Redis (AES-256-GCM, chave em
VEU_CHAVE_COFRE, fora do Redis). O nome da sessão entra como dado autenticado: um cofre não pode ser copiado para outra sessão, e um cofre alterado ou em texto puro é ignorado. -
Restaurações contadas: a auditoria registra quantos valores reais voltaram em cada resposta (
restaurados, por tipo, sem os valores), e/veu/estatisticase/veu/metricastambém.[restauracao] max_por_respostalimita esse número por resposta. -
Âncora da auditoria:
veu auditoria ancorarmostra o último hash da cadeia para guardar fora do servidor, eveu auditoria verificar --ancorafalha se ele sumir (linhas apagadas no fim ou log trocado). -
Leitura de links sem SSRF: na expansão de links do proxy, o link e cada redirecionamento precisam ser https e apontar para endereços públicos (nada de 169.254.169.254, localhost ou rede interna).
-
Extensão para Firefox (128 ou mais novo): o empacotamento gera também
veu-extensao-firefox-<versão>.zip, com o manifesto que o Firefox espera. -
veu servir --workers Nabre vários processos (exige sessões no Redis; uma cadeia de auditoria por processo). -
Página web: textos grandes (20 mil caracteres ou mais) são analisados num Web Worker, sem travar a página, e as instâncias do Véu são reaproveitadas entre as teclas.
-
Testes de propriedade (hypothesis): anonimizar e restaurar devolve o texto original; o streaming dá o mesmo resultado que o lote, cortado em qualquer ponto; o leitor de SSE remonta os eventos cortados em qualquer byte (inclusive no meio de um caractere UTF-8 e com CRLF); bytes aleatórios não derrubam os leitores de SSE e NDJSON.
VEU_HIPOTESES=5000faz uma busca longa. -
Kit de conformidade (docs/conformidade.md): o que o Véu é em termos da LGPD e do GDPR (pseudonimização no modo reversível; o perfil
anonimizacaopode sustentar o art. 12), um mapeamento controle a controle e um modelo de RIPD para o uso de IA externa com o Véu. -
Perfis prontos (
veu perfis,--perfil,VEU_PERFILou[politica] perfil):anonimizacao(irreversível, sem cofre),judiciario(CNJ 615/2025),juridico(OAB),saude(CFM 2.454/2026),financeiro(cartões e contas removidos) esetor-publico(guia do TCU: recusa qualquer dado pessoal). As opções escritas noveu.tomlvalem mais que as do perfil. -
veu auditoria relatorio: o registro das operações (LGPD, art. 37) a partir da auditoria, só com metadados, em Markdown ou JSON, com período e conferência da cadeia. -
Documentos de Portugal e da América Latina, com dígito verificador (algoritmos conferidos com o python-stdnum): NIF, Cartão de Cidadão e NISS (Portugal), CUIT/CUIL e DNI (Argentina), CURP e RFC (México), RUT (Chile e Uruguai), cédulas (Uruguai, Equador, Colômbia e Venezuela), NIT (Colômbia), RUC (Peru, Equador e Paraguai) e RIF (Venezuela). Três níveis de confiança: formatos estruturados valem sozinhos; números puros, que um CPF ou um protocolo poderiam imitar, só com contexto; num formato ambíguo sem contexto, vence o rótulo brasileiro. Nova categoria no painel.
-
Padrões que só valem com contexto não são nem procurados quando nenhuma palavra de contexto aparece no texto, e a normalização de texto (fold) ficou em cache: a detecção ficou mais rápida mesmo com os novos documentos (de cerca de 357 mil para 393 mil caracteres por segundo).
-
Painel: a tela de atividade mostra os pedidos recentes (destino, tipos e quantidades escondidos e devolvidos, resultado), também em
/veu/estatisticas; e uma caixinha manda os textos com dados pessoais para um modelo local do Ollama, sem sair do computador. -
Filtro do Open WebUI (beta):
examples/open-webui/veu.pyinstala o Véu como função do Open WebUI, que esconde os dados das mensagens e devolve os dados reais nas respostas, com um cofre por conversa (pedaços de streaming sem a conversa identificada nunca são restaurados). -
Nó do n8n (
n8n/, pacote@guhttps/n8n-nodes-veu): operações "Esconder dados" e "Restaurar dados", sem dependências em tempo de execução (a biblioteca do Véu vai embutida), e um modelo pronto de atendimento por WhatsApp com a Evolution API. -
Operador
generalizar(Python e JavaScript): guarda só o que serve para análise e identifica menos (ano de nascimento, região do CEP, DDD, rede /24 do IP) e troca o resto pelo tipo. Não é reversível. -
veu risco: conta os dados diretos que sobraram num texto e as pistas indiretas (datas, idades, cidades, cargos) e dá um nível de risco de identificação pelo contexto. -
Detector
ml(opcional,pip install "veu[ml]"): um modelo BERT de nomes treinado em português do Brasil, rodando na máquina, somado às regras. Um nome do modelo só conta com confiança alta ou confirmado pelas listas do IBGE ou pelo contexto. No desafio, o vazamento caiu de 22,0% para 8,0% (nomes: de 35% para 0%), com a mesma precisão; no privacy-filter-br, de 0,4% para 0,2%. Custa velocidade (2 a 7 mil caracteres por segundo).[deteccao] modelo_mltroca o modelo. -
Documentos de mais 11 países (Python e JavaScript, algoritmos conferidos com o python-stdnum): NUIT e BI (Moçambique e Angola), SSN, ITIN e Medicare (EUA), DNI e NIE (Espanha), codice fiscale (Itália), NIR (França), Steuer-ID (Alemanha), National Insurance e NHS (Reino Unido), BSN (Países Baixos), SIN (Canadá), Aadhaar e PAN (Índia). Também a zona de leitura do passaporte (MRZ, com os dígitos da ICAO 9303), o chassi (VIN) e carteiras de Bitcoin (Base58Check e bech32) e Ethereum. Seguem os mesmos três níveis de confiança; o BI de Moçambique e o NIR sem espaços só valem com contexto, porque imitam datas de certificados e números de protocolo. Nenhuma detecção nova em 20 mil textos brasileiros da parte de treino do privacy-filter-br.
-
Detecção mais rápida: as expressões que começam com um limite de palavra passam a começar pela classe de caracteres, o que deixa o motor de regex do Python pular direto para as posições candidatas (as mesmas correspondências, em menos da metade do tempo). Isso compensa a maior parte do custo dos 22 padrões novos.
-
SIEM:
[siem] syslog(RFC 5424 por UDP, TCP ou TLS) e[siem] hec_url(Splunk HTTP Event Collector) mandam cada linha da auditoria, com o hash da cadeia, para o SIEM, numa fila separada que nunca segura as requisições. Envios, falhas e descartes aparecem em/veu/metricas. -
Login único (OIDC) no gateway (
[oidc],pip install "veu[oidc]"): JWTs do Entra ID, Google, Keycloak ou Okta valem como token, com a assinatura conferida pelas chaves públicas do emissor (RS, PS e ES; nuncanonenem HMAC), o emissor, o público e a validade.[equipes.X] grupos_oidcescolhe a equipe pelos grupos, eclaim_usuarioregistra quem fez a requisição na auditoria. -
Extensão: a política da empresa pode mostrar uma orientação nos avisos (
orientacao, com um linkhttpsemlinkOrientacao), como "Dados de clientes só no assistente interno". -
Site de documentação em guhttps.github.io/veu/docs, com busca e um menu por perfil (sem programar, programadores, empresas, conformidade). É montado a partir do README e de
docs/(scripts/gerar_site.py, com o Zensical), sem duplicar texto, e um teste confere que todo link interno aponta para uma página e uma âncora que existem. -
Homebrew e Scoop: fórmula e manifesto prontos em
packaging/, gerados com os hashes do PyPI (scripts/atualizar_manifestos.py) e testados (a fórmula no Homebrew para Linux, combrew test). Falta criar o tap e o bucket; o winget fica para quando houver um executável assinado. -
README em inglês (README.en.md) e demonstração animada da página no topo dos dois (
docs/demo.gifedocs/demo-en.gif, gravados porscripts/gravar_demo.mjs). -
Página em português e em inglês: o idioma segue o navegador (ou
?lang=en,?lang=pt), com um link para trocar; os nomes dos tipos também são traduzidos. Os marcadores continuam em português ([PESSOA_1]). -
O nó do n8n ganhou instruções em inglês, e o
server.json(validado com o esquema oficial) e a linhamcp-nameno README preparam a publicação no MCP Registry.
Corrigido
- Restauração em tempo linear: uma linha longa sem espaços antes de um marcador (base64 num argumento de ferramenta, por exemplo) levava segundos para restaurar; agora leva milissegundos. Um trecho sem espaços com mais de 2.048 caracteres logo antes do marcador não é analisado, e o marcador fica como está.
- Open WebUI: o fim retido da resposta se perdia quando o último pedaço do streaming vinha com
"delta": {}. - OIDC: a busca das chaves do emissor não trava mais o servidor; roda no início e depois numa thread.
- SIEM: com o SIEM fora do ar e a fila cheia, o servidor não fica mais preso no encerramento.
veu auditoria ancorarnum log vazio explica que não há o que ancorar, em vez de gerar uma âncora que nunca conferia.- Sessões isoladas por equipe: com as chaves do provedor injetadas pelo gateway, duas equipes (ou dois usuários do OIDC) que usassem o mesmo
X-Veu-Sessaocaíam no mesmo cofre, e a resposta de uma podia restaurar um dado da outra. O cofre passa a considerar também a equipe ou o usuário. - Nomes ambíguos que o dicionário marca como palavras (sobrenomes como Costa e Nascimento) só se propagam com inicial maiúscula: "data de nascimento" não vira mais nome de pessoa. O gerador de listas passou a ler também as regras de sufixo do dicionário.
- Restauração em streaming: um marcador solto colado a uma palavra (
_CPF_1,xCPF_1) era restaurado quando chegava num pedaço separado, embora no texto inteiro não fosse. Achado pelos testes de propriedade.
Alterado
- Incompatível: os marcadores do operador
hashmudaram (16 caracteres hexadecimais, chave derivada). Pseudônimos gerados com versões anteriores não batem com os novos. - Incompatível: um
VEU_SEGREDOcom menos de 32 caracteres impede o Véu de iniciar, com uma mensagem que ensina a gerar um novo. - README, banner, descrições do PyPI e do npm, GitHub Action, hook de pre-commit e servidor MCP passam a apresentar o Véu como proteção de dados pessoais e segredos em geral, com suporte completo a documentos brasileiros (e não só para dados brasileiros).
- Extensão: mostrar os dados reais direto na página passa a ser opcional (desligado por padrão), porque o código do site de IA também consegue ler a página. Os dados reais continuam a um clique: copiar a seleção, o campo Restaurar do ícone ou a opção no popup.
- Extensão: o script roda antes da página (
document_start), para tratar o colar antes do código do site, e reconhece os marcadores do operadorhashcom 16 caracteres. - Incompatível: sessões no Redis exigem
VEU_CHAVE_COFRE(oupermitir_cofre_sem_cifra = true). O extraveu[redis]passa a instalar ocryptography. veu avaliar --max-vazamentovale para a validação (e para o conjunto escolhido), não para o desafio, que existe para mostrar onde o Véu ainda erra.