RAG on ServiceNow: the connector that erases user criteria
Listen to article
generated on playGenerated only on first play
Powered by Amazon Polly + OmniVoice
Amazon Bedrock Managed Knowledge Base got a native ServiceNow connector on September 4, 2026, and it removes weeks of hand-rolled pipeline. It also tells you to use a service account with knowledge_admin, which bypasses per-knowledge-base user criteria — and the connector ingests no document-level ACL. This is the retro of the pilot where those two lines of documentation met.
The documentation for Amazon Bedrock Managed Knowledge Base's ServiceNow connector carries two sentences that look like implementation detail when read apart. The first tells you to grant knowledge_admin to the service account, and explains why: the role bypasses per-knowledge-base user criteria restrictions. The second warns that ServiceNow data sources don't support document-level ACLs — every authenticated user who can query the knowledge base sees every crawled document. Together they describe an enterprise assistant that answers anything for anyone. This is the retro of the pilot where I found that out the cheap way: in staging, four hours after the first sync.
What happened
What happened
I stood the connector up the day it shipped, September 4, 2026, against a staging instance loaded with a real export: roughly 12,000 knowledge articles spread across six separate knowledge bases, and 40,000 active catalog items. The goal was to measure sync time and retrieval quality for an internal IT assistant — the exact use case AWS names in the announcement.
I followed the documentation line by line. The glide.oauth.inbound.client.credential.grant_type.enabled property set to true. A service account flagged Web service access only, no interactive sign-in. The OAuth application registered through the interceptor page — not by inserting straight into oauth_entity, as the guide itself warns. An Inbound Authentication Profile wired to a REST API Access Policy over now/table, because without it the token is valid and the Table API still returns 401. Step 3 asks for exactly two roles: knowledge_admin and catalog_admin. I assigned both, and ServiceNow inherited around fourteen contained roles.
The sync finished. Then I asked the question I ask of every enterprise RAG before anything ships: I queried the assistant about a subject I knew was restricted to one group on the source instance. The answer came back whole, citing the article, for an identity that held no role there at all. It wasn't a hallucination — it was correct retrieval of a document ServiceNow would never have rendered for that user.
The pilot stopped there. What follows is the retro, blameless: the configuration was right per the documentation, and that is precisely the point.
Timeline
- 1
T+0h — service account created with the roles from the guide
knowledge_adminandcatalog_adminassigned per step 3. The documentation note says, in plain letters, that these roles bypass per-KB and per-catalog user criteria restrictions. I read it and complied. - 2
T+0h20 — OAuth verified with curl
POST /oauth_token.dowithgrant_type=client_credentials, thenGET /api/now/table/kb_knowledge?sysparm_limit=1. HTTP 200 with data. AWS's verification table reads an empty array as a symptom of an insufficient role — meaning success here is already success with bypass. - 3
T+0h35 — data source created with no filter
crawlKnowledgeArticles,crawlServiceCatalogsand both attachment fields set totrue;filterConfigurationomitted. With no filter the connector crawls every published article and every active item the account can see — which is now everything. - 4
T+3h50 — sync completes slower than planned
The troubleshooting page explains it: without
inclusionServiceCatalogSysIds, the crawl sweeps the 100,000-plus active items of an enterprise instance. I had 40,000 and it still took hours. - 5
T+4h05 — the control query returns restricted content
A natural-language question, no
userContext, about an article restricted to one group. Chunk and citation came back normally. Nothing in the trace flags an anomaly, because nothing anomalous happened. - 6
T+4h15 — data source deleted, retro opened
Index destroyed in staging, with no end-user exposure. The real cost of the incident was one day of work and a few dollars of storage — the design, not so much.
Root cause: two controls removed at different points of the path
ServiceNow's user criteria isn't ignored at query time — it is ignored at ingestion, by a role the documentation instructs you to assign, and never rebuilt afterwards, because the ServiceNow connector isn't in Managed Knowledge Base's ACL matrix. SharePoint, OneDrive, Google Drive and Confluence support pre-retrieval filtering plus real-time verification; S3 and Custom support pre-retrieval filtering from metadata you supply; Web Crawler and ServiceNow support neither. The rule that seals the hole is unforgiving: non-ACL data sources in a mixed knowledge base return results to every user, with or without userContext on the Retrieve call. This is not a connector bug — it is its published contract, and designing around it is your job.
Where user criteria dies
The path of a restricted article, from the kb_knowledge table to the assistant's answer. The two red points in the drawing aren't failures: they are documented behaviors that, added together, remove the only access control the source ever had.
- 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
The fix: scope at ingestion, because there is none at query time
The fix: scope at ingestion, because there is none at query time
When the access boundary doesn't exist at retrieval time, it has to exist earlier — in what enters the index. Four concrete changes.
One knowledge base per audience, not one per system. Retrieve takes a knowledgeBaseId; that is the only unit IAM can see. I split into two bases: one fed with crawlPublicKnowledgeArticlesOnly set to true, another with inclusionKnowledgeBaseSysIds listing only the sys IDs whose audience matches an IdP group. The 10,000-knowledge-bases-per-account-per-Region quota isn't the constraint here; the constraint is operational, which is why granularity stopped at audience rather than group.
Authorization moves back into the application. The bedrock:Retrieve permission is now granted through a distinct role per audience, with a Condition on the knowledge base's resource tag. The service answering the user resolves the group from the IdP token and assumes the matching role. That is more code than I would like — and it is the price of using a source with no ACL.
sys ID filtering stopped being an optimization. inclusionServiceCatalogSysIds and inclusionKnowledgeArticleCategorySysIds are scope control and sync-time control at once: the troubleshooting page attributes hours-long syncs precisely to their absence.
Protected deletion. I enabled deletionProtectionConfiguration with deletionProtectionThreshold at 15. If a sync tries to remove more than 15% of the index — which a user criteria mistake at the source triggers easily — the delete phase is skipped instead of emptying the assistant in production.
ACL support by connector — what it changes in the design
| Pre-retrieval ACL filter | Real-time verification | What it forces on you | |
|---|---|---|---|
| ServiceNow | Not supported | Not supported | Segregate per knowledge base and authorize in IAM/the application; never mix audiences in one index. |
| SharePoint / OneDrive | Supported | Supported | Requires app-only auth (ENTRA_ID_APP_ONLY / ENTRA_APP_ID) and an email identical to the source's. |
| Google Drive | Supported | Supported | Domain-wide delegation with SERVICE_ACCOUNT; permission changes between syncs are caught at verification. |
| Confluence | Supported | Supported | Admin token for the real-time check, with BASIC auth — rotation becomes a runbook item. |
| Amazon S3 / Custom | Supported | Not supported | The ACL is your own file/metadata: permission freshness becomes your pipeline's responsibility. |
| Web Crawler | Not supported | Not applicable | Public content only; anything else is a leak by construction. |
Identity: the detail that decides whether the mitigation works
Identity: the detail that decides whether the mitigation works
Even on connectors that do carry ACLs, Managed Knowledge Base's identity model is narrower than most enterprise designs assume — worth knowing before you promise fine-grained segregation to the risk team.
The universal identifier is email. userContext.userId on Retrieve is always the user's email, and it must match exactly the email associated with that user in each connected data source. There is no alias resolution and no cross-identity-provider mapping. If the company carries two domains from an acquisition, half the people get zero results — silently, which is the worst failure mode available.
Groups come from the last sync. User-to-group membership is crawled at ingestion and resolved at query time from that snapshot. Real-time verification covers the window between syncs on the four connectors that support it; third-party IdP credentials are cached for up to one hour, and permission changes are eventually consistent, typically within minutes. For a termination, that is exposure time — treat revocation as an IdP and application event, not a knowledge base one.
Missing ACL means inaccessible, not public. A document with no extracted permissions in an ACL-enabled source is returned to nobody, and evaluation fails closed: a group-resolution error yields fewer results, never more. That is the correct behavior, and it is also the most common explanation for "the assistant got dumber after the deploy".
And the sentence the documentation insists on repeating: ACL-aware is filtering, not authorization. Authentication is yours.
Reading it through the pillars
Security
The connector concentrates power in one service account holding knowledge_admin and catalog_admin — the documentation explicitly asks you not to add admin, itil or snc_read_only, and that restriction is the little least-privilege you get. The Secrets Manager secret holds clientId, clientSecret and instanceUrl in the same Region as the knowledge base; rotating means regenerating the client secret in the Application Registry, which is shown only once. Treat knowledgeBaseId as a security boundary and condition bedrock:Retrieve by tag.
Reliability
Incremental sync keys on sys_updated_on, so an article restored from backup at the source may never return to the index if the timestamp doesn't move. deletionProtectionThreshold (default 15%) keeps a bad sync from emptying the index. The ceilings that matter on a bad day: 200 data sources per knowledge base, 50 concurrent ingestion jobs, 10 TB of raw data per knowledge base, 600 RPM of Retrieve with a 25 RPS burst, and 300 RPM of AgenticRetrieveStream per account.
Anti-patterns this retro put in writing
- One knowledge base for the whole company: mixing ServiceNow (no ACL) with SharePoint (ACL) in the same index lets the weakest source set the access level — non-ACL documents return to everyone, even with
userContexton the call. - Treating
userContextas access control: it filters by the identity you assert, verifying nothing. Without upstream authentication it is a query parameter, not a boundary. - Crawling with no
filterConfigurationon an enterprise instance: it turns into an hours-long sync over 100,000-plus catalog items and fills the index with content nobody will ask about — at US$ 5.00 per GB per month to keep it. - Registering the OAuth application by inserting straight into
oauth_entity: the documentation requires the interceptor page; the shortcut yields a record that authenticates and then fails at the Table API, and you debug401in the wrong place. - Trusting source-side user criteria as an outbound control: it is evaluated per user session inside ServiceNow. An integration account with
knowledge_admindoesn't violate it — it is simply never subjected to it.
What now gets measured before any release
What now gets measured before any release
The retro doesn't end at a configuration fix; it ends at a signal. A RAG leak throws no error, shows no latency anomaly and never lands on an availability dashboard — it shows up as a useful answer for the wrong person. Three things joined the release checklist.
A canary query suite. A small set of questions whose correct answer is silence, one per audience, run against each knowledge base after every sync. It is access regression testing, it runs in seconds and it costs US$ 1.00 per thousand calls. The alternative is learning about it from the ombudsman.
Document counts per sync, with an expected band. The statistics object from GetIngestionJob reports how many documents were added, failed and removed. A sharp swing usually means a scope change at the source — a category moved, a catalog reactivated — before it means a platform problem. With deletionProtectionThreshold enabled, the sync that would skip its delete phase is exactly the event you want alarming.
The origin of cited chunks. Because the assistant returns citations, the dataSourceId of each retrieved chunk is free telemetry. If a restricted-audience knowledge base shows up in an open-channel answer, the alarm fires without anyone having to read the answer.
The connector saves weeks of hand-rolled pipeline — what it does not save is the design of who may see what. That part was never outsourceable.
If I were putting this into production in a financial-grade environment tomorrow, I'd start with a single knowledge base fed by crawlPublicKnowledgeArticlesOnly set to true and nothing else — the set of articles already public to every employee — and only then open additional bases per audience, each with its own role and tag. The hard-won lesson this pilot reinforced: when a connector erases the source's permission model, the damage doesn't surface as a failure, it surfaces as quality. The assistant gets better when it leaks, because it has more context, and that is why nobody files a ticket. I learned to read the ACL support matrix before the connector's feature list, and to treat the sentence "all authenticated users who can query the knowledge base can see all crawled content" as an architecture requirement, not a footnote.
References
Verdict
Adopt the connector when the ServiceNow content you want indexed is already visible to the assistant's entire audience — public IT knowledge bases, an open service catalog, unrestricted HR FAQs — and when the cost of maintaining your own Table API pipeline, pagination, attachments and sys_updated_on incremental sync is real for your team. In that slice it is a good deal: weeks less code, native scheduling, and bulk-deletion protection by configuration. Don't adopt it as-is when the instance uses user criteria to separate audiences, when risk, legal or fraud runbook articles live in the same kb_knowledge, or when a regulatory requirement forces you to trace who could see what — because then the boundary isn't in the connector, it's in your knowledge base layout and the IAM around Retrieve. What AWS shipped is not outsourced access control — it is outsourced ingestion, and those two keep charging their maintenance cost to whoever always paid it: you.
Architecture, AWS, AI and market deep dives — straight to your inbox. Free.
No spam · unsubscribe anytime
Ask Fernando about this
Get a focused answer about this article from my AI assistant, grounded in my work.
Join the conversation
Sign in to comment
Verify your email to join in — you'll also get the newsletter. No password.
Keep reading
Architecture intelligence, in your inbox
Curated signals and original analysis on AWS, AI, distributed systems and the market — the way a solutions architect reads them.
- Curated AWS · AI · architecture · market signals
- New architecture studies & deep-dives when they ship
- Sharp summaries — depth without the noise
- No spam · double opt-in · unsubscribe anytime