RAG sobre ServiceNow: o conector que apaga o user criteria
A documentação do conector de ServiceNow do Amazon Bedrock Managed Knowledge Base tem duas frases que, lidas separadamente, parecem detalhe de implementação. A primeira manda dar knowledge_admin à conta de serviço, e explica: o papel ignora as restrições de user criteria por knowledge base. A segunda avisa que fontes ServiceNow não suportam ACL em nível de documento, todo usuário autenticado que consulta a base vê todo o conteúdo crawleado. Juntas, elas descrevem um assistente corporativo que responde qualquer coisa para qualquer um. Este é o retro do piloto em que eu descobri isso da forma barata: em homologação, quatro horas depois do primeiro sync.
O que aconteceu
O que aconteceu
Subi o conector no dia em que ele saiu, 4 de setembro de 2026, contra uma instância de homologação carregada com um export real: cerca de 12 mil artigos espalhados por seis knowledge bases distintas e 40 mil itens de catálogo ativos. O objetivo era medir tempo de sync e qualidade de recuperação para um assistente interno de TI, o caso de uso que a própria AWS cita no anúncio.
Segui a documentação linha a linha. Propriedade glide.oauth.inbound.client.credential.grant_type.enabled em true. Conta de serviço marcada como Web service access only, sem senha interativa. Aplicação OAuth registrada pela página do interceptor, não por insert direto em oauth_entity, como o próprio guia avisa. Inbound Authentication Profile amarrado a uma REST API Access Policy sobre now/table, porque sem isso o token nasce válido e a Table API devolve 401. O passo 3 pede exatamente dois papéis: knowledge_admin e catalog_admin. Atribuí os dois, e o ServiceNow herdou por volta de quatorze papéis contidos.
O sync terminou. Fiz então a pergunta que faço em todo RAG corporativo antes de liberar qualquer coisa: perguntei ao assistente sobre um assunto que eu sabia estar restrito a um grupo específico na instância de origem. A resposta veio inteira, com citação do artigo, para uma identidade que não tinha papel nenhum lá. Não foi alucinação, foi recuperação correta de um documento que o ServiceNow jamais teria renderizado para aquele usuário.
O piloto parou ali. O que segue é o retro, sem culpado: a configuração estava certa segundo a documentação, e é exatamente esse o ponto.
Linha do tempo
- 1
T+0h, conta de serviço criada com os papéis do guia
knowledge_adminecatalog_adminatribuídos conforme o passo 3. A nota da documentação diz, em letras claras, que esses papéis passam por cima das restrições de user criteria por KB e por catálogo. Li e segui. - 2
T+0h20, verificação do OAuth com curl
POST /oauth_token.docomgrant_type=client_credentials, depoisGET /api/now/table/kb_knowledge?sysparm_limit=1. HTTP 200 com dados. A tabela de verificação da AWS trata array vazio como sintoma de papel insuficiente, ou seja, o sucesso aqui já é sucesso com bypass. - 3
T+0h35, data source criado sem filtro
crawlKnowledgeArticles,crawlServiceCatalogse os dois campos de anexo emtrue;filterConfigurationomitido. Sem filtro, o conector crawleia todo artigo publicado e todo item ativo que a conta enxerga, que agora é tudo. - 4
T+3h50, sync conclui mais devagar que o previsto
A própria página de troubleshooting explica: sem
inclusionServiceCatalogSysIds, o crawl varre os 100 mil ou mais itens ativos de uma instância enterprise. Eu tinha 40 mil e ainda assim levei horas. - 5
T+4h05, a consulta de controle devolve conteúdo restrito
Uma pergunta em linguagem natural, sem
userContext, sobre um artigo restrito a um grupo. Trecho e citação vieram normalmente. Nada no traço indica anomalia, porque nada anômalo aconteceu. - 6
T+4h15, data source deletado, retro aberto
Índice destruído em homologação, sem exposição a usuário final. O custo real do incidente foi um dia de trabalho e alguns dólares de storage, o desenho, não.
Causa raiz: dois controles removidos em pontos diferentes do caminho
O user criteria do ServiceNow não é ignorado no momento da consulta, ele é ignorado na ingestão, por um papel que a documentação manda atribuir, e nunca é reconstruído depois, porque o conector ServiceNow não está na matriz de ACL do Managed Knowledge Base. SharePoint, OneDrive, Google Drive e Confluence suportam pré-filtro e verificação em tempo real; S3 e Custom suportam pré-filtro por metadado fornecido por você; Web Crawler e ServiceNow não suportam nada. A regra que fecha o buraco é implacável: fontes sem ACL numa base mista devolvem resultado para todos os usuários, com ou sem userContext na chamada Retrieve. Não é um bug do conector, é o contrato dele, publicado, e é você quem precisa desenhar em volta.
Onde o user criteria morre
O caminho do artigo restrito, da tabela kb_knowledge até a resposta do assistente. Os dois pontos vermelhos do desenho não são falhas: são comportamentos documentados que, somados, removem o único controle de acesso que existia na origem.
- kb_knowledge · ~12k artigos, user criteria por KB
- sc_cat_item · ~40k itens ativos + anexos
- svc account (2LO) · knowledge_admin + catalog_admin
- Secrets Manager · clientId / clientSecret / instanceUrl
- ServiceNow connector v1 · incremental por sys_updated_on
- Managed Knowledge Base · chunks + embeddings, sem ACL
- Retrieve / AgenticRetrieveStream · userContext sem efeito aqui
- Assistente de TI · autentica no IdP corporativo
- KB 'publica' · crawlPublicKnowledgeArticlesOnly = true
- KB 'restrita' · sys IDs isolados + IAM por grupo
- IAM na chamada Retrieve · Condition por tag de audiência
A correção: escopo na ingestão, porque não há escopo na consulta
A correção: escopo na ingestão, porque não há escopo na consulta
Quando a fronteira de acesso não existe no momento da recuperação, ela precisa existir antes, no que entra no índice. Foram quatro mudanças concretas.
Uma knowledge base por audiência, não uma por sistema. O Retrieve recebe um knowledgeBaseId; é a única unidade que o IAM enxerga. Separei em duas bases: uma alimentada com crawlPublicKnowledgeArticlesOnly em true, outra com inclusionKnowledgeBaseSysIds listando apenas os sys IDs cujo público coincide com um grupo do IdP. O limite de 10.000 bases por conta e por Region não é o gargalo aqui; o gargalo é operacional, e por isso a granularidade parou em audiência, não em grupo.
Autorização volta para a aplicação. A permissão bedrock:Retrieve passou a ser concedida por role distinta por audiência, com Condition sobre a tag de recurso da base. Quem responde ao usuário resolve o grupo no token do IdP e assume a role correspondente. É mais código do que eu gostaria, e é o preço de usar uma fonte sem ACL.
Filtro por sys ID deixou de ser otimização. inclusionServiceCatalogSysIds e inclusionKnowledgeArticleCategorySysIds são, ao mesmo tempo, controle de escopo e controle de tempo de sync: a documentação de troubleshooting atribui o sync de horas exatamente à ausência deles.
Deleção protegida. Liguei deletionProtectionConfiguration com deletionProtectionThreshold em 15. Se um sync tentar apagar mais de 15% do índice, o que um erro de user criteria na origem provoca com facilidade, a fase de deleção é pulada em vez de esvaziar o assistente em produção.
Suporte a ACL por conector, o que muda no desenho
| Pré-filtro por ACL | Verificação em tempo real | O que isso obriga | |
|---|---|---|---|
| ServiceNow | Não suportado | Não suportado | Segregar por knowledge base e autorizar no IAM/aplicação; nunca misturar audiências no mesmo índice. |
| SharePoint / OneDrive | Suportado | Suportado | Exige auth de aplicação (ENTRA_ID_APP_ONLY / ENTRA_APP_ID) e e-mail idêntico ao da origem. |
| Google Drive | Suportado | Suportado | Domain-wide delegation com SERVICE_ACCOUNT; mudança de permissão entre syncs é pega na verificação. |
| Confluence | Suportado | Suportado | Token de admin para a checagem em tempo real, com auth BASIC, rotação vira item de runbook. |
| Amazon S3 / Custom | Suportado | Não suportado | A ACL é um arquivo/metadado seu: a frescor da permissão passa a ser responsabilidade do seu pipeline. |
| Web Crawler | Não suportado | Não aplicável | Só conteúdo já público; qualquer outra coisa vira vazamento por construção. |
Identidade: o detalhe que decide se a mitigação funciona
Identidade: o detalhe que decide se a mitigação funciona
Mesmo nos conectores que têm ACL, o modelo de identidade do Managed Knowledge Base é mais estreito do que a maioria dos desenhos corporativos assume, e vale conhecer antes de prometer segregação fina para o time de risco.
O identificador universal é o e-mail. O userContext.userId do Retrieve é sempre o e-mail do usuário, e ele precisa bater exatamente com o e-mail associado àquele usuário em cada fonte conectada. Não há resolução de alias nem mapeamento entre provedores de identidade. Se a empresa carrega dois domínios por causa de uma aquisição, metade das pessoas recebe zero resultado, e recebe em silêncio, que é o pior modo de falha possível.
Grupos vêm do último sync. A associação usuário-grupo é crawleada na ingestão e resolvida na consulta a partir desse retrato. A verificação em tempo real cobre a janela entre syncs nos quatro conectores que a suportam; credenciais de IdP terceiro ficam em cache por até uma hora, e mudanças de permissão são eventualmente consistentes, tipicamente em minutos. Para um desligamento, isso é tempo de exposição, trate a revogação como evento do IdP e do app, não da base de conhecimento.
Ausência de ACL significa inacessível, não público. Documento sem permissão extraída numa fonte com ACL habilitada não volta para ninguém, e a avaliação falha fechada: erro de resolução de grupo devolve menos resultados, nunca mais. É o comportamento certo, e é também a explicação mais comum para o chamado "o assistente ficou burro depois do deploy".
E a frase que a documentação faz questão de repetir: ACL-aware é filtragem, não autorização. Quem autentica é você.
Leitura pelos pilares
Segurança
O conector concentra o poder numa conta de serviço com knowledge_admin e catalog_admin, a documentação pede explicitamente que você não adicione admin, itil ou snc_read_only, e essa restrição é o pouco de menor privilégio que sobra. O segredo do Secrets Manager guarda clientId, clientSecret e instanceUrl na mesma Region da base; rotacionar exige regenerar o client secret no Application Registry, que só é exibido uma vez. Trate o knowledgeBaseId como fronteira de segurança e condicione bedrock:Retrieve por tag.
Confiabilidade
O sync incremental usa sys_updated_on, então artigo restaurado por backup na origem pode não voltar ao índice se o timestamp não mudar. deletionProtectionThreshold (padrão 15%) evita que um sync ruim esvazie o índice. Os tetos que importam no dia mau: 200 data sources por base, 50 jobs de ingestão concorrentes, 10 TB de dado bruto por base, 600 RPM de Retrieve com burst de 25 RPS e 300 RPM de AgenticRetrieveStream por conta.
Anti-padrões que este retro deixou por escrito
- Uma base de conhecimento para a empresa inteira: juntar ServiceNow (sem ACL) com SharePoint (com ACL) no mesmo índice faz a fonte mais fraca definir o nível de acesso, documento sem ACL volta para todo mundo, mesmo com
userContextna chamada. - Tratar
userContextcomo controle de acesso: ele filtra pela identidade que você afirma, sem verificar nada. Sem autenticação a montante, é um parâmetro de consulta, não uma fronteira. - Crawl sem
filterConfigurationem instância enterprise: vira sync de horas sobre mais de 100 mil itens de catálogo e enche o índice de conteúdo que ninguém vai perguntar, pagando US$ 5,00 por GB por mês para guardá-lo. - Registrar a aplicação OAuth por insert direto em
oauth_entity: a documentação exige a página do interceptor; o atalho produz um registro que autentica e depois falha na Table API, e você vai debugar401no lugar errado. - Confiar no user criteria da origem como controle de saída: ele é avaliado por sessão de usuário no ServiceNow. Uma conta de integração com
knowledge_adminnão o viola, ela simplesmente nunca é submetida a ele.
O que passou a ser medido antes de qualquer liberação
O que passou a ser medido antes de qualquer liberação
O retro não termina em correção de configuração; termina em sinal. Um vazamento de RAG não gera erro, não gera latência anômala e não aparece em dashboard de disponibilidade, ele aparece como uma resposta útil para a pessoa errada. Três coisas entraram no checklist de release.
Suíte de consultas-canário. Um conjunto pequeno de perguntas cujas respostas corretas são silêncio, uma por audiência, executada contra cada base após todo sync. É teste de regressão de acesso, roda em segundos e custa US$ 1,00 por mil chamadas. A alternativa é descobrir pela ouvidoria.
Contagem de documentos por sync, com faixa esperada. O statistics do GetIngestionJob diz quantos documentos entraram, falharam e saíram. Uma variação brusca costuma significar mudança de escopo na origem, categoria movida, catálogo reativado, antes de significar problema de plataforma. Com deletionProtectionThreshold ligado, o sync que pularia a fase de deleção é exatamente o evento que você quer ver no alarme.
Origem dos trechos citados. Como o assistente devolve citações, o dataSourceId de cada trecho recuperado é telemetria de graça. Se uma base de audiência restrita aparece em resposta de canal aberto, o alarme dispara sem depender de alguém ler a resposta.
O conector economiza semanas de pipeline artesanal, o que ele não economiza é o desenho de quem pode ver o quê. Essa parte nunca foi terceirizável.
Se eu fosse colocar isso em produção num ambiente financeiro amanhã, começaria com uma única base alimentada por crawlPublicKnowledgeArticlesOnly em true e nada mais, o conjunto de artigos que já é público para todo funcionário, e só depois abriria bases adicionais por audiência, cada uma com sua role e sua tag. A lição dura que este piloto reforçou: quando um conector some com o modelo de permissão da origem, o dano não aparece como falha, aparece como qualidade. O assistente fica melhor quando vaza, porque tem mais contexto, e por isso ninguém abre chamado. Eu aprendi a ler a matriz de suporte a ACL antes de ler a lista de features do conector, e a tratar a frase "todos os usuários autenticados veem todo o conteúdo crawleado" como requisito de arquitetura, não como nota de rodapé.
Referências
Veredito
Adote o conector quando o conteúdo do ServiceNow que você quer indexar já for visível para toda a audiência do assistente, knowledge bases públicas de TI, catálogo de serviços aberto, FAQ de RH sem restrição, e quando o custo de manter um pipeline próprio de Table API, paginação, anexos e sync incremental por sys_updated_on for real para o seu time. Nesse recorte ele é um bom negócio: semanas de código a menos, agendamento nativo e proteção contra deleção em massa por configuração. Não o adote como está quando a instância usa user criteria para separar audiências, quando há artigo de risco, jurídico ou runbook de fraude no mesmo kb_knowledge, ou quando a exigência regulatória obriga rastrear quem podia ver o quê, porque nesse caso a fronteira não está no conector, está no seu desenho de bases e no IAM em volta do Retrieve. O que a AWS entregou não foi controle de acesso terceirizado, foi ingestão terceirizada, e essas duas coisas continuam custando de manutenção quem sempre pagou por elas: você.
Continue lendo
Deep dives de arquitetura, AWS, IA e mercado: direto no seu email. Grátis.
Sem spam · cancele quando quiser
Pergunte ao Fernando sobre isto
Uma resposta focada sobre este artigo, do meu assistente de IA, baseada no meu trabalho.
Participe da conversa
Entre para comentar
Confirme seu e-mail para participar, você também recebe a newsletter. Sem senha.