3LO in Bedrock Managed KB: 5-minute setup, 1 irreversible decision
Listen to article
generated on playGenerated only on first play
Powered by Amazon Polly + OmniVoice
On September 4, 2026 AWS shipped user-managed setup (3LO) for SharePoint, OneDrive and Confluence in Amazon Bedrock Managed Knowledge Base: you sign in with your own account and the data source is live in minutes. What the docs say in fine print is that this path does not support document-level access control, and that the ACL flag cannot be changed after CreateDataSource. This is the story of the migration that forces — from a 3LO prototype to a production knowledge base on ENTRA_ID_APP_ONLY, certificate and userContext.
The question that matters in this announcement isn't "how long does it take to connect SharePoint?" — it's "who can read what you indexed once it's connected?". The user-managed setup (3LO) AWS shipped on September 4, 2026 for SharePoint, OneDrive and Confluence in Amazon Bedrock Managed Knowledge Base answers the first question very well: you click Sign in, authorize with your corporate account, and Bedrock creates the Secrets Manager secret with the refresh token for you. The second question is where I spent three weeks.
What the five-minute path actually trades away
The SharePoint setup page is explicit and worth reading twice: user-managed setup does not support document-level access control (ACL). All indexed content is accessible to anyone who can query the knowledge base, and individual SharePoint permissions are not enforced. The same sentence shows up on the Confluence page, word for word.
This isn't a bug or a temporary gap — it follows directly from the flow. In 3LO, Bedrock stores a delegated refresh token, issued to you, carrying four permissions: Sites.Read.All and User.Read on Microsoft Graph, offline_access to renew the token, and AllSites.Read on the SharePoint Online API. These are delegated permissions, inherited from what your account can see. The crawler walks into the tenant wearing your identity and copies everything it can reach into an index that has no notion of who is who.
The path that does support ACL is a different one: ENTRA_ID_APP_ONLY for SharePoint, ENTRA_APP_ID for OneDrive, SERVICE_ACCOUNT for Google Drive, BASIC for Confluence. Those are application permissions, with admin consent, and for SharePoint with ACLs they require Sites.FullControl.All — or Sites.Selected with a per-site fullcontrol grant — because Sites.Read.All is not enough to read item-level permissions.
The trade, stated plainly: 3LO swaps a two-week ticket with the identity team for an index with no internal border. For a prototype over a public engineering wiki, that's a good deal. For the credit policy repository, it's an incident waiting for a date.
The journey: from a 3LO prototype to a production knowledge base
- 1
Week 0 — the prototype is born in the console, asking nobody
An analyst holding
bedrock:GetDataSourceAuthorizationUrl,bedrock:CreateDataSourceTokenandsecretsmanager:CreateSecretcompletes the flow alone. Bedrock creates the secret atarn:aws:secretsmanager:{region}:{account}:secret:bedrock-managedkb-oauth/{prefix}/{connector}/{uuid}and the data source comes up withauthType=MANAGED_OAUTH2. No ticket, no tenant ID, no review. - 2
Week 1 — the gate nobody read
The Entra App-Only page states what locks the whole journey: the decision to enable ACLs cannot be changed after the data source is created. And 3LO doesn't offer the option at all. Meaning: there is no in-place upgrade from
MANAGED_OAUTH2to ACL — there is a new data source and a full re-ingestion. - 3
Week 2 — inventory of what was already copied
Before building the new path, answer what the old one already indexed. The crawl followed the identity of whoever signed in; if that person is senior, the reach is theirs. List the included sites and spaces, cross them against your data classification, and treat the current index as a copy repository — because that's what it is.
- 4
Week 3 — app registration and certificate
Here the ticket 3LO had eliminated comes back. A Global Administrator or Privileged Role Administrator registers the single-tenant application with no redirect URI, adds the application permissions and grants admin consent. You generate a pair with
openssl req -x509 -newkey rsa:2048, upload the.certo Entra and the.p12bundle to S3 with SSE. The.p12is mandatory when ACLs are on. - 5
Week 4 — secret, service role and the new data source
The secret carries
clientIdandcertificatePassword— always set the password explicitly; if you omit it, Bedrock opens the bundle using the client ID as the password. The service role getss3:GetObjecton the certificate object with anaws:ResourceAccountcondition, pluskms:Decryptif you used a CMK. The data source is created withcertificateS3Path, whichENTRA_ID_APP_ONLYrequires even with ACLs off. - 6
Week 5 — the application starts proving who is asking
RetrievegainsuserContext.userIdwith the user's universal email. Without it, ACL-enabled data sources return zero results — excellent as a fail-safe, terrible as a production surprise. Authentication stays yours: Bedrock filters by the identity you assert, it does not verify that the assertion is true. - 7
Week 6 — delete the old path, including the secret
Delete the
MANAGED_OAUTH2data source and the orphanedbedrock-managedkb-oauth/secret — it still holds a valid refresh token. On the Microsoft side, revoke by disabling or deleting the service principal under Enterprise applications; on Atlassian the grant is per site, so every.atlassian.netneeds its own revocation.
The two phases and the immutable gate between them
3LO is fast because it ends in a delegated refresh token; production is slow because it starts from a certificate and admin consent. The gate in the middle isn't a step — it's a decision you can only make once per data source.
- Console Bedrock KB · GetDataSourceAuthorizationUrl
- Secrets Manager · bedrock-managedkb-oauth/.../uuid
- Data source · authType=MANAGED_OAUTH2
- Consentimento delegado · Sites.Read.All + offline_access
- Admin consent do tenant · obrigatório se o tenant restringe apps
- aclEnabled · não muda após CreateDataSource
- Entra app registration · application perms + Sites.FullControl.All
- Amazon S3 · certificate.p12 (SSE)
- Data source · ENTRA_ID_APP_ONLY + ACL
- Managed KB · conteúdo + permissões crawladas
- Retrieve · userContext.userId = e-mail
- App corporativa · OIDC valida o usuário final
Before and after, in numbers the docs confirm
Sites.Read.All, User.Read, offline_access and AllSites.Read — read access to everything the signing account can see, renewable indefinitely.userContext: whoever queries the knowledge base reads the entire index, regardless of their SharePoint access.Identity: email is the key, and there is no translation
Getting to the ACL path solves less than it looks, and it solves it in a very specific way. Bedrock Managed Knowledge Base uses email as the universal identifier — there is no alias resolution and no cross-identity-provider mapping. The userId you pass to Retrieve must match exactly the email associated with that user in each connected data source. If your corporate IdP issues fernando.azevedo@company.com and Confluence stores fazevedo@company.com, the match fails silently and the user simply gets no results from that source. Silence is the worst failure mode a search system can have: nobody files a ticket over an incomplete answer, they file over a wrong one.
Groups run on a different ruler. They're identified however the source represents them — name, ID, whatever — and user→group membership comes from the crawl. The docs are blunt: group memberships are as fresh as the last sync. If a permission changed between syncs, the pre-retrieval filter doesn't know. The saving grace is the second layer: for SharePoint, OneDrive, Google Drive and Confluence there's real-time verification against the source, which catches exactly that window. S3 and Custom have no such net, because their ACLs come from a metadata file you supply.
Two notes that change your application design: third-party IdP credentials are cached for up to 1 hour, and permission changes are eventually consistent, typically within a few minutes. So "I revoked access now" and "the RAG stopped showing it" are not the same instant. In a BACEN- or LGPD-bound environment, that gap belongs in the design document, not in the audit findings.
The two paths, side by side
| Prototype — `MANAGED_OAUTH2` (3LO) | Production — `ENTRA_ID_APP_ONLY` (2LO) | |
|---|---|---|
| Who authorizes | The user, in the popup — unless the tenant restricts third-party apps, in which case admin consent is required again | Global Administrator or Privileged Role Administrator, with explicit admin consent |
| Stored credential | Delegated refresh token, in a secret Bedrock creates itself | A .p12 certificate in S3 plus clientId/certificatePassword in a secret you create |
| Document-level access control | Not supported — and the flag can't change afterwards | Supported, with pre-retrieval filtering and real-time verification |
| Crawl reach | Whatever the signing account can see — variable, invisible from the AWS console | The whole tenant with Sites.Read.All/Sites.FullControl.All, or site by site with Sites.Selected |
| What breaks | The offboarding of whoever authorized; a token revoked in Entra; content shared after the sync, which needs a resync | An expired certificate (every sync fails); a forgotten per-site grant for a new site, which is not retroactive |
The failure modes that only show up later
The token has an owner, and owners resign. The 3LO refresh token belongs to a person. When they leave and the account is disabled, the sync stops — and the index stays right there, holding whatever content they could reach. The production path has no such coupling: the application authenticates with a certificate, with no human sign-in at crawl time or query time.
Fail-closed is good, but it looks like a bug. ACL-aware retrieval fails closed: a group-resolution error, a real-time verification timeout or an internal error means the document is not returned. The response may carry fewer results than the requested maxResults, and Bedrock does not backfill. Your application must treat partial responses as normal, and tell "zero because of ACL" apart from "zero because of relevance" — the API signals resolution failures precisely for that.
A document without an ACL is an invisible document. In an ACL-enabled data source, a document whose permissions weren't extracted goes to nobody. Absence is treated as restricted, not public. After the migration, expect a recall drop and investigate that before blaming the embedding model.
The secret prefix is your only IAM lever, and the default is ambiguous. The 3LO IAM page says that without a prefix Bedrock uses default; the connector pages say the created secret uses the bedrock-managedkb-oauth prefix. Don't build a policy on that assumption: supply an explicit secret name prefix at sign-in and write the policy with Resource scoped to it before anyone runs the flow. That's the difference between secretsmanager:CreateSecret on a predictable path and a Resource: "*" nobody will review later.
The risk isn't 3LO — it's the 3LO nobody planned for
Two Bedrock permissions (GetDataSourceAuthorizationUrl and CreateDataSourceToken) plus secretsmanager:CreateSecret are enough for anyone with console access to index the corporate SharePoint into a knowledge base with no internal border, without touching a single identity process. If your production account already grants those actions by wildcard in some "Bedrock developer" policy, you don't have a new feature — you have a new path to accidentally authorized exfiltration. Deny bedrock:CreateDataSourceToken outside sandbox accounts before you discuss RAG architecture.
Anti-patterns I've watched grow out of this flow
- Promoting the prototype by switching
authType: it doesn't exist. The ACL flag is immutable per data source, so promoting means creating a new data source and re-ingesting — plan the re-ingestion cost and the duplicate-index window. - Authorizing 3LO with the architect's account: the more senior the authorizer, the wider the crawl. If you're going to use 3LO, use an account with deliberately narrow access to the in-scope sites.
- Treating ACL awareness as authorization: the docs themselves say it's filtering, not a security boundary. Bedrock does not authenticate end users — it trusts the
userIdyour application asserts. - Unblocking user-installed apps in Atlassian "just for a minute": while that toggle is open, any user can authorize any OAuth app across the entire site. Have the admin authorize directly instead.
- Leaving the 3LO secret behind during cleanup: deleting the data source doesn't delete the secret, and it holds a refresh token that still renews.
Well-Architected lens on the decision
Security
Deny bedrock:CreateDataSourceToken in production accounts via SCP; require a secret name prefix and scope Resource to it; prefer Sites.Selected over Sites.FullControl.All whenever the site list is known; store the .p12 with SSE-KMS and kms:Decrypt restricted to the service role.
Reliability
A certificate with the default 365-day validity takes every sync down when it expires — alarm 45 days ahead. Per-site grants are not retroactive: a new site without a grant simply isn't crawled, with no visible error on the data source.
Let the prototype exist — in an account where it can't grow up
The obvious temptation after reading all this is to block 3LO and be done. I wouldn't. The friction it removes is real: without it, every RAG experiment over the internal wiki turns into a two-week ticket with the identity team, and the practical outcome is that nobody experiments — or worse, somebody exports the wiki into a bucket and builds RAG on the side, with no crawler, no sync and none of the checks we just discussed.
The design I recommend is topological, not political. One sandbox account where bedrock:GetDataSourceAuthorizationUrl and bedrock:CreateDataSourceToken are allowed, with no classified data and a short lifecycle — the whole index dies in N days by process, not by memory. Production accounts with those two actions denied by SCP, which makes 3LO disappear from the menu without a case-by-case argument.
What crosses that border isn't the data source; it's the learning. The prototype answers the genuinely expensive questions: which Confluence spaces hold content that resolves real doubts, which chunking strategy survives an 80-page policy document, whether agentic retrieval with maxAgentIteration above the default of 5 changes the answer enough to justify the cost. None of that depends on ACLs. When the answer is "worth it", then you open the ticket with the Entra team knowing exactly which sites to request under Sites.Selected — and the ticket is shorter because you arrive with a scope, not an intention.
Before enabling anything, I'd grep the production account's policies for bedrock:* — the odds that the two new actions are already granted by wildcard are high, and no IAM review done before September 2026 could have accounted for them. Then I'd create the sandbox account with the inverted SCP, because blocking production without offering the right place just pushes the problem outside my field of view. I learned that the expensive way on a financial platform: the architecture decision that looks like security is almost always about ergonomics — people route around inconvenient controls with a creativity no policy anticipates. And I'd keep the rule I apply to every new connector: if the flag can't be changed later, it isn't configuration, it's design — and design goes into an ADR, with the trade-off written and signed before CreateDataSource.
Verdict
Use user-managed setup (3LO) when all three conditions hold together: the content is already readable by the knowledge base's entire audience, the index lives in an account with no classified data, and it has an agreed expiration date. Outside that, go straight to ENTRA_ID_APP_ONLY for SharePoint, ENTRA_APP_ID for OneDrive or BASIC for Confluence — not because 3LO is poorly built, but because the ACL flag can't change after CreateDataSource, and today's five-minute shortcut costs a full re-ingestion plus an Entra-team ticket later. This announcement isn't about authentication; it's about where your organization's access boundary exists — and 3LO answers that it stops existing inside the index. That's a legitimate choice for a prototype and an audit finding for everything else.
References
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