Engenheiros

Recuperação híbrida e permissões por usuário no índice: como não vazar dados no RAG

Busca léxica mais vetorial, fusão de resultados, ACL herdada da origem aplicada em tempo de consulta, revogação, multi-tenancy e testes automatizados de vazamento.

Equipe e.works LabsTechnology · Innovation · Automation5 min de leitura

A maior parte dos incidentes de segurança em sistemas de RAG não vem de prompt injection sofisticada. Vem de algo mais banal: o índice de busca devolve um documento que o usuário não tinha permissão de ver na origem. A causa raiz quase sempre é a mesma — permissões foram tratadas como detalhe de implementação, não como parte do desenho da recuperação.

Este artigo cobre como montar recuperação híbrida (léxica + vetorial) com controle de acesso correto: onde aplicar o filtro, como sincronizar revogações, como isolar tenants e como testar que nada disso está furado.

Por que híbrida, não só vetorial

Busca puramente vetorial erra em dois cenários comuns: termos exatos (códigos de produto, IDs, siglas) e negações ou filtros estruturados. Busca léxica (BM25 ou equivalente) cobre exatamente esses casos.

A arquitetura híbrida roda as duas em paralelo e funde os resultados:

Consulta do usuário
   │
   ├─→ Busca léxica (BM25)        ──┐
   │                                 ├─→ Fusão (RRF ou score ponderado) → Top-K final
   └─→ Busca vetorial (embeddings) ──┘

Reciprocal Rank Fusion (RRF) é a escolha mais robusta quando as duas listas têm escalas de score incomparáveis: em vez de normalizar scores, soma-se 1 / (k + rank) para cada documento nas duas listas e reordena pelo total. Isso evita ter que calibrar pesos toda vez que um dos motores muda de versão.

Alternativa mais simples — e mais frágil — é normalizar os scores (min-max) e combinar com peso fixo (ex.: 0.6 vetorial + 0.4 léxico). Funciona, mas exige recalibração cada vez que a distribuição de scores muda.

Onde aplicar a ACL: pré-filtro vs. pós-filtro

Este é o ponto onde a maioria dos sistemas de RAG erra.

Pós-filtro — buscar primeiro, filtrar depois por permissão — é a abordagem mais comum porque é mais simples de implementar. O problema: se o usuário não tem acesso a nenhum dos top-K documentos retornados, a resposta final fica vazia ou pobre, mesmo havendo documentos permitidos mais abaixo no ranking. Pior, dependendo da implementação, contagens e agregações podem vazar a existência de documentos (a IA menciona "há 3 documentos sobre X" mesmo que o usuário não possa ver nenhum).

Pré-filtro — restringir o espaço de busca à permissão do usuário antes de rankear — é a abordagem correta para dados sensíveis. O filtro de ACL entra como parte da query ao motor de busca (filtro de metadado), não como etapa posterior em memória:

Consulta + ACL do usuário (grupos, tenant, papéis)
   │
   ▼
Motor de busca filtra por ACL ANTES de rankear
   │
   ▼
Top-K já é 100% dentro do que o usuário pode ver

A maioria dos bancos vetoriais modernos (Pinecone, Weaviate, Qdrant, pgvector com RLS) suporta filtro de metadado nativo o suficiente rápido para isso não virar gargalo, desde que o campo de ACL seja indexado.

Modelando a ACL herdada da origem

O índice não deve reinventar permissões — ele deve espelhar as da fonte (SharePoint, Google Drive, Confluence, banco de dados). Cada chunk indexado carrega metadados de controle de acesso:

CampoExemplo
tenant_idempresa-123
acl_groups[grupo-financeiro, grupo-diretoria]
acl_users[user-456] (para overrides pontuais)
visibilityrestricted \internal \public
source_updated_attimestamp da última sincronização de ACL

Na hora da consulta, resolve-se a identidade do usuário (grupos, papéis, tenant) e compõe-se o filtro: tenant_id = X AND (acl_groups INTERSECTS user_groups OR acl_users CONTAINS user_id).

Revogação e sincronização de permissões

Permissão herdada da origem só é confiável se o índice for atualizado quando a origem muda. Duas estratégias, combináveis:

  1. 1.Sincronização por eventos: a origem emite webhook ou evento (ex.: usuário removido de um grupo no SharePoint) e o índice reprocessa os documentos afetados quase em tempo real.
  2. 2.Reconciliação periódica: um job roda em cadência fixa (ex.: a cada 15–30 minutos para dados sensíveis, horária para o resto) e recomputa ACLs a partir da origem, corrigindo drift que os eventos não capturaram.

Trate a reconciliação periódica como rede de segurança obrigatória, não como opcional — sistemas de eventos falham silenciosamente, e é nela que revogações perdidas são pegas antes de virar incidente.

Multi-tenancy

Multi-tenancy é permissão em escala máxima: um bug de isolamento entre tenants é o pior tipo de vazamento, porque cruza fronteiras organizacionais.

  • Prefira isolamento físico ou de namespace (índice ou coleção por tenant) quando o volume permitir — elimina uma classe inteira de bugs de filtro.
  • Quando o índice é compartilhado, o tenant_id deve ser um filtro obrigatório, aplicado no nível de infraestrutura (política de banco, não só em código de aplicação) — para que um bug de aplicação não vire vazamento entre clientes.
  • Nunca confie em um filtro de tenant que pode ser omitido por engano em uma query específica; use row-level security ou equivalente que rejeite consultas sem o filtro.

Testes automatizados de vazamento

ACL sem teste automatizado é ACL que vai vazar, é questão de tempo. O conjunto mínimo de testes:

  • Teste de isolamento de tenant: usuário do tenant A nunca deve ver, em nenhuma consulta, documento do tenant B — rodar com um dataset de fixtures cobrindo múltiplos tenants.
  • Teste de revogação: remover permissão de um usuário e verificar que uma consulta imediatamente após deixa de retornar o documento (dentro da janela de sincronização aceita).
  • Teste de vazamento por agregação: verificar que contagens, resumos e sugestões da IA não revelam a existência de documentos fora do escopo do usuário.
  • Teste de escalonamento de privilégio: simular usuário sem grupo nenhum e confirmar que zero documentos restritos retornam.

Rode esse conjunto no CI, contra um índice de teste com dados sintéticos representando múltiplos tenants e níveis de permissão — não apenas manualmente antes de um release grande.

O que fazer na segunda-feira

  • Audite se seu pipeline de RAG aplica ACL como pré-filtro ou pós-filtro na busca, e migre para pré-filtro se ainda não for o caso.
  • Verifique se existe reconciliação periódica de permissões, não só sincronização por eventos, e defina a cadência para dados sensíveis.
  • Escreva o primeiro teste automatizado de isolamento entre tenants e rode-o no CI antes do próximo deploy.
  • Se o índice for compartilhado entre tenants, confirme que o filtro de tenant_id está no nível de infraestrutura, não apenas no código da aplicação.

Leitura complementar

Trilha executiva:

CompartilharLinkedInX

Leia também

Coloque em prática

Do artigo à prática: use isso na sua empresa

Os recursos descritos neste artigo estão disponíveis na plataforma e.works, em eworks.cloud. Você escolhe onde os dados da sua empresa ficam: na infraestrutura da e.works, gerenciada e protegida na AWS, ou no seu próprio ambiente on-premises.

  • Infraestrutura e.works na AWS

    Ambiente gerenciado e protegido pela e.works sobre a AWS, com criptografia, isolamento por empresa, backup e alta disponibilidade.

  • On-premises, no seu ambiente

    A mesma plataforma rodando no data center ou na nuvem privada da sua empresa, quando a soberania dos dados exige que nada saia do seu perímetro.

Em qualquer um dos modelos: seus dados continuam seus — com controle de acesso, registro de auditoria, retenção configurável e disponibilidade garantida.

Newsletter

Conteúdo técnico e estratégico, uma vez por mês

Análises de automação, dados industriais e adoção de tecnologia. Sem spam.