# RAG sobre ServiceNow: o conector que apaga o user criteria

O conector nativo de ServiceNow do Amazon Bedrock Managed Knowledge Base chegou em 4 de setembro de 2026 e tira semanas de pipeline artesanal do caminho. Ele também instrui você a usar uma conta de serviço com knowledge_admin, que ignora o user criteria por knowledge base — e o conector não ingere ACL de documento. Este é o retro do piloto em que essas duas linhas de documentação se encontraram.

- URL: https://fernando.moretes.com/blog/rag-sobre-servicenow-o-conector-que-apaga-o-user-criteria-amazon-bedro

- Markdown: https://fernando.moretes.com/blog/rag-sobre-servicenow-o-conector-que-apaga-o-user-criteria-amazon-bedro/article.md?lang=pt

- Published: 2026-09-06T10:16:58.083Z

- Category: IA & Agentes

- Tags: bedrock, rag, servicenow, seguranca, iam, knowledge-base, governanca, finops

- Reading time: 8 min

- Source: [Amazon Bedrock Managed Knowledge Base now supports ServiceNow as a native data source connector](https://aws.amazon.com/about-aws/whats-new/2026/09/amazon-bedrock-managed-knowledge-base-servicenow-native-data-source-connector/)

---

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_admin` e `catalog_admin` atribuí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.do` com `grant_type=client_credentials`, depois `GET /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`, `crawlServiceCatalogs` e os dois campos de anexo em `true`; `filterConfiguration` omitido. 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.

### 🏢 ServiceNow — origem do conteúdo

- kb_knowledge ~12k artigos, user criteria por KB (external)
- sc_cat_item ~40k itens ativos + anexos (external)
- svc account (2LO) knowledge_admin + catalog_admin (security)

### 🟧 AWS — Ingestão

- Secrets Manager clientId / clientSecret / instanceUrl (security)
- ServiceNow connector v1 incremental por sys_updated_on (compute)
- Managed Knowledge Base chunks + embeddings, sem ACL (ai)

### 🟧 AWS — Recuperação

- Retrieve / AgenticRetrieveStream userContext sem efeito aqui (ai)
- Assistente de TI autentica no IdP corporativo (compute)

### 🔐 Fronteira que sobra depois do retro

- KB 'publica' crawlPublicKnowledgeArticlesOnly = true (storage)
- KB 'restrita' sys IDs isolados + IAM por grupo (storage)
- IAM na chamada Retrieve Condition por tag de audiência (security)

### Fluxos

- svc -> kb: 1. knowledge_admin ignora o user criteria
- svc -> cat: 2. catalog_admin ignora restrição de catálogo
- sm -> conn: segredo na mesma Region da base
- conn -> svc: token 2LO + Table API /now/table
- conn -> mkb: 3. ingere texto e metadado — permissão não
- mkb -> ret: busca híbrida, top-k sobre tudo
- emp -> app: pergunta em linguagem natural
- app -> ret: 4. consulta sem fronteira por documento
- ret -> app: trecho + citação de qualquer artigo crawleado
- conn -> kbpub: correção: só artigos públicos
- conn -> kbres: correção: sys IDs de audiência única
- app -> iam: correção: role por audiência, não por app
- iam -> kbres: bedrock:Retrieve condicionado por tag

## 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
| Critério | 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

- **security**: 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.
- **reliability**: 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 `userContext` na chamada.
- **Tratar `userContext` como 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 `filterConfiguration` em 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 debugar `401` no 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_admin` nã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.

> **Nota de curadoria:** 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

- [AWS What's New — Amazon Bedrock Managed Knowledge Base now supports ServiceNow as a native data source connector (Sep 4,](https://aws.amazon.com/about-aws/whats-new/2026/09/amazon-bedrock-managed-knowledge-base-servicenow-native-data-source-connector/)
- [Amazon Bedrock User Guide — ServiceNow data source (supported features, ACL warning)](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-ds-servicenow.html)
- [Amazon Bedrock User Guide — Set up OAuth 2.0 Client Credentials authentication for ServiceNow](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-servicenow-oauth2-setup.html)
- [Amazon Bedrock User Guide — Connect a ServiceNow data source (connector parameters, sys ID filters)](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-ds-servicenow-connect.html)
- [Amazon Bedrock User Guide — Access Control Lists awareness enablement (connector support matrix)](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-acl.html)
- [Amazon Bedrock User Guide — Sync a data source and set a sync schedule](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-sync.html)
- [Amazon Bedrock User Guide — Service quotas for managed knowledge bases](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-managed-quotas.html)
- [AWS Machine Learning Blog — Build enterprise search for agents with Amazon Bedrock Managed Knowledge Base](https://aws.amazon.com/blogs/machine-learning/build-enterprise-search-for-agents-with-amazon-bedrock-managed-knowledge-base/)

## 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ê.

**Rating:** Adotar com escopo explícito / Adopt with
