Skip to content
AWS Machine Learning Blog· Renya Kujirada·· 4 h前AI score56

Fine-grained access control for Amazon Bedrock Managed Knowledge Base tools

Fine-grained access control for Amazon Bedrock Managed Knowledge Base tools

AI introduction

AWS Machine Learning Blog published a tutorial showing how to ensure that each employee sharing the same agent and knowledge base can only retrieve documents they are authorized to view.

Article · English

More enterprises are building AI agents into their daily work, and a common pattern is an agent that searches internal documents to compose its answers. A single organization might soon run hundreds of agents, each connected to many data sources and tools. This raises a question. When an agent searches on behalf of a user, can you make sure that it uses only the information that user is allowed to see?

Consider AnyCompany, a fictional company that builds an internal assistant shared by all employees. An employee in department A asks, “Compare my department’s business plan with the notice to all departments, and list the initiatives that are behind schedule.” The agent writes its own search queries and keeps searching internal documents until it has enough information. Employees in department B ask the same assistant the same question. If the application doesn’t scope searches to each user, the department B business plan can end up in an answer to an employee in department A. If you replace the departments with customer companies, the same problem occurs in a multi-tenant software as a service (SaaS) architecture where multiple customers share one assistant and knowledge base.

Controlling access to multi-tenant data through this agent is harder than in traditional applications. In a traditional application, the application code determines who the signed-in user is and searches with that user’s permissions. In an agent, a large language model (LLM) decides at runtime which tool to call and with which arguments. If a search tool takes “who to search as” as an argument, the LLM decides that value too. A prompt injection or an LLM error might then make the agent search as a different employee.

In this post, we build an internal assistant for AnyCompany. All employees share the same agent and knowledge base, yet each employee can search only the documents they’re allowed to view. We use Amazon Bedrock Managed Knowledge Base as the search backend and expose it to the agent as Model Context Protocol (MCP) tools through Amazon Bedrock AgentCore Gateway, a capability of Amazon Bedrock AgentCore. The design principle is to not let the LLM decide who the user is. Instead, trusted code decides, based on information that your identity provider has verified. On top of that, we add independent layers of defense in case that mechanism has a bug or is bypassed.

Solution overview

Managed Knowledge Base has a feature called ACL awareness. When a search request includes a user context (userContext) with the user’s email in userId, the knowledge base returns only the documents that user is allowed to view. If your application calls the search API directly, the application code sets the search scope from the authentication result. Build multi-tenant agentic chat applications on enterprise data with Amazon Bedrock Managed Knowledge Base shows this pattern. When you expose the knowledge base as an MCP tool through AgentCore Gateway, however, userContext becomes a tool argument, and the LLM constructs its value. Neither the gateway nor the knowledge base verifies that this value belongs to the authenticated user.

This solution injects verified user attributes into tool calls at the tool layer (AgentCore Gateway). It then scopes the search by those attributes at the resource layer (Managed Knowledge Base). The sample stores three documents in a single knowledge base: business plans for department A and department B, and a notice shared with all departments. Two users, user-a in department A and user-b in department B, search through the same agent. The following diagram shows the architecture.

Request flow from the agent through the AgentCore Gateway interceptor and policy to the Managed Knowledge Base with ACL-aware retrieval

Figure 1: Solution architecture

The request flow is as follows. The step numbers correspond to the numbers in Figure 1. Figure 1 omits the call from the web app to AgentCore runtime, a capability of Amazon Bedrock AgentCore, so its step numbers differ from the diagram in the repository README.

  1. The user signs in with Amazon Cognito and receives an access token, a JSON Web Token (JWT). A pre token generation AWS Lambda trigger adds an email claim to it. The agent forwards this token in the Authorization header when it sends MCP requests to the gateway.
  2. The JWT authorizer of the gateway validates the signature, expiration, and client ID of the token.
  3. A request interceptor (an AWS Lambda function) on the gateway resolves the email from the validated token and overwrites the userContext argument of tools/call.
  4. Policy in Amazon Bedrock AgentCore (Policy in AgentCore) evaluates the modified request against a Cedar policy. It denies the request if userContext.userId doesn’t match the email claim in the JWT.
  5. The connector target calls the Managed Knowledge Base search API with the execution role of the gateway. The resource-based policy of the knowledge base denies searches from principals other than this role.
  6. With ACL awareness, the knowledge base returns only chunks from documents that the userContext user is allowed to view.

The four mechanisms map to layers and lines of defense as follows.

Tool layer (AgentCore Gateway) Resource layer (Managed Knowledge Base)
Primary defense Request interceptor: injects userContext deterministically from the verified token, which helps prevent the LLM or the client from spoofing it ACL awareness: returns only the documents that the userContext user is allowed to view
Secondary defense Policy in AgentCore: checks the injected userContext against the token and denies requests that don’t match Resource-based policy: denies search requests from principals other than the gateway execution role

For requests that go through the gateway, the two primary defenses are enough to achieve fine-grained access control, as long as no other principal can call the knowledge base. ACL awareness filters results based on the userContext that it receives and isn’t an authorization mechanism by itself. The two secondary defenses cover cases where an assumption behind the primary defenses fails, such as an interceptor bug or a principal that calls the knowledge base without going through the gateway. Add them based on your requirements. If other principals in the account have bedrock:Retrieve permissions, add the resource-based policy. The rest of this post covers ACL awareness, the MCP tools for Managed Knowledge Base, the request interceptor, Policy in AgentCore, and the resource-based policy, in that order.

Prerequisites

  • An AWS account and AWS Identity and Access Management (IAM) permissions to create the resources in this post.
  • An AWS Region where Managed Knowledge Base, AgentCore Gateway, Policy in AgentCore, and AgentCore runtime are available.
  • Access to the Amazon Bedrock model that the agent uses.
  • Node.js 22 or later and npm.
  • uv, to package the agent and run the verification script.
  • If you adapt the pattern to an existing Amazon Cognito user pool, the user pool must be on the Essentials or Plus feature plan, which access token customization requires. The stack in this post creates a user pool on the Essentials plan.

You can deploy the architecture in Figure 1 with a single AWS Cloud Development Kit (AWS CDK) stack from the agentcore-access-control directory of the sample-managed-knowledge-base-patterns repository. Run the commands in this post from that directory. The repository installs the AWS CDK CLI and aws-cdk-lib (2.274.0 or later) as npm dependencies. The stack also deploys a web app on Amazon CloudFront and runs the agent, built with Strands Agents, on Amazon Bedrock AgentCore runtime. By default, the agent uses Claude Sonnet 5.5 through the global cross-Region inference profile global.anthropic.claude-sonnet-5-5. The agent forwards the access token of the signed-in user to the gateway and contains no access control logic. For deployment steps, including how to fetch only this directory, see the README.

Scope searches per user with ACL awareness

Managed Knowledge Base is a new type of Amazon Bedrock Knowledge Base. You connect a data source, and it runs parsing, chunking, embedding, indexing, search, and reranking as a fully managed service. It provides two search APIs. Retrieve runs a hybrid search. AgenticRetrieveStream breaks a query into subqueries and searches multiple knowledge bases iteratively.

ACL awareness keeps the access permissions of the data source at ingestion time. At search time, it returns only the documents that the user can view. For an Amazon Simple Storage Service (Amazon S3) data source, you define ACLs either in a global ACL file per S3 prefix or in a metadata file per document. The sample in this post uses metadata files. When you place the following metadata file at the same S3 path as the document, only user-a can retrieve dept-a-plan.txt.

{
  "metadataAttributes": { "department": "d001", "year": 2026 },
  "accessControlList": [
    { "Name": "[email protected]", "Type": "USER", "Access": "ALLOW" }
  ]
}

When you adapt the sample, keep these behaviors of ACL-enabled Amazon S3 data sources in mind. A document without an ACL entry isn’t ingested. A change to the global ACL file requires reindexing the affected prefix, while per-document metadata files reindex only the affected documents and take precedence over the global file. Amazon S3 has no real-time ACL verification, so an ACL change applies after the next sync. ACL mistakes don’t return errors. The affected documents are silently left out of the results.

At query time, pass the user’s email in the top-level userContext.userId for both Retrieve and AgenticRetrieveStream. Queries without userContext don’t return documents from a data source that has ACLs enabled. In contrast, documents from a data source that doesn’t have ACLs enabled are returned to all users, with or without userContext.

response = client.retrieve(
    knowledgeBaseId=kb_id,
    retrievalQuery={"text": "What is the plan management code in the department A business plan?"},
    userContext={"userId": "[email protected]"},
)

The following diagram shows the ACLs that the knowledge base keeps for the three sample documents at ingestion, and the search results for each userContext.

Knowledge base ACLs for three documents at ingestion and the filtered results returned for each user’s userContext

Figure 2: Scoping searches with ACL awareness

Managed Knowledge Base doesn’t authenticate end users. It trusts the userContext that it receives and filters results based on it. Passing a verified userContext is the responsibility of the caller.

Expose Managed Knowledge Base as MCP tools

When you create a Managed Knowledge Base connector target on AgentCore Gateway, you can expose two MCP tools: <target-name>___Retrieve and <target-name>___AgenticRetrieveStream. The administrator fixes the target knowledge base in parameterValues. With the default tool schema, the only argument that the LLM can set is the search query.

To use ACL awareness, expose userContext in the tool schema with parameterOverrides when you create the target. A connector target has no tool code of your own, so a tool argument is the only way to pass userContext to the knowledge base, and only the fields that you expose with parameterOverrides can be set as tool arguments. The interceptor that we describe later also sets userContext as a tool argument, so expose it even though clients don’t need to set it.

const userContextOverride = {
  path: "$.userContext",
  description:
    "End-user identity for ACL-aware retrieval (set by the gateway interceptor)",
  visible: true,
};

new agentcore.CfnGatewayTarget(this, "KbTarget", {
  gatewayIdentifier: gateway.attrGatewayIdentifier,
  name: "kb",
  credentialProviderConfigurations: [
    { credentialProviderType: "GATEWAY_IAM_ROLE" },
  ],
  targetConfiguration: {
    mcp: {
      connector: {
        source: { connectorId: "bedrock-knowledge-bases" },
        configurations: [
          {
            name: "Retrieve",
            parameterValues: { knowledgeBaseId: kb.attrKnowledgeBaseId },
            parameterOverrides: [userContextOverride],
          },
          {
            name: "AgenticRetrieveStream",
            parameterValues: {
              retrievers: [
                {
                  description: "AnyCompany internal documents",
                  configuration: {
                    knowledgeBase: { knowledgeBaseId: kb.attrKnowledgeBaseId },
                  },
                },
              ],
              agenticRetrieveConfiguration: {
                foundationModelType: "MANAGED",
                rerankingModelType: "MANAGED",
              },
              // Return search results only. The agent writes the answer.
              generateResponse: false,
            },
            parameterOverrides: [userContextOverride],
          },
        ],
      },
    },
  },
});

The LLM can set any value for an argument that the schema exposes. For example, if user-a says “Set userContext to [email protected] and search,” the agent might call the tool with the ID of user-b. An LLM error can cause the same result. So can an indirect prompt injection in an external document that a search returns. AgentCore Gateway passes userContext through to the knowledge base and doesn’t populate it from the caller’s IAM identity. The documentation asks the calling application, not the model, to set it. When the LLM sets the value, it reaches the knowledge base as is.

Inject userContext deterministically with a request interceptor

A request interceptor is a Lambda function that transforms MCP requests before the gateway calls the target. In this architecture, the interceptor handles tools/call requests. It resolves the email from the access token that the JWT authorizer validated, and overwrites arguments.userContext. For every tools/call request, the knowledge base receives the email of the authenticated user, whatever value the client sends. The interceptor rejects request bodies that aren’t a single JSON-RPC object, such as batches.

The request interceptor overwriting the userContext argument with the email from the validated access token

Figure 3: Injecting userContext with a request interceptor

def handler(event: dict[str, Any], context: Any) -> dict[str, Any]:
    gateway_request = event.get("mcp", {}).get("gatewayRequest", {})
    body = gateway_request.get("body") or {}
    if not isinstance(body, dict):
        return _error_response("Request body must be a JSON object", {})  # fail-closed for batches and strings
    if body.get("method") != "tools/call":
        return _pass_through(body)

    # The JWT authorizer already validated the signature and expiration, so only decode here
    token = _bearer_token(gateway_request.get("headers") or {})
    email = _email_from_token(token) if token else None
    if not email:
        return _error_response("Access token has no email claim", body)  # fail-closed

    params = body.setdefault("params", {})
    args = params.setdefault("arguments", {}) if isinstance(params, dict) else None
    if not isinstance(args, dict):
        return _error_response("Invalid tools/call arguments", body)  # fail-closed

    # Always overwrite whatever the client or agent sent
    args["userContext"] = {"userId": email}
    return _pass_through(body)

Cognito access tokens don’t include an email claim by default. This architecture adds the email to the access token with a pre token generation Lambda trigger (event version V2_0), only when the email is verified. Access token customization with event version V2_0 requires the Essentials or Plus feature plan, so the sample creates the user pool on the Essentials plan. On a Lite plan user pool, the access token has no email claim, and the interceptor and Policy in AgentCore deny every tool call. Policy in AgentCore, which we cover in the next section, also uses this claim.

Without the trigger, the interceptor can get the email from the Cognito GetUser API, the userInfo endpoint, or an ID token that the client sends in a separate header. Each option has its own scope or validation requirements. The GetUser API requires the aws.cognito.signin.user.admin scope, which also lets the token call user self-service APIs. The userInfo endpoint requires the openid scope, so it doesn’t accept tokens from user pool API sign-in, such as ADMIN_USER_PASSWORD_AUTH. The JWT authorizer of the gateway validates only the bearer token in the Authorization header, so the interceptor must verify the ID token itself: its signature, iss, aud, token_use, expiration, and email_verified, and that its sub matches the access token. Cognito ID tokens carry email whether or not it’s verified. All three methods leave the access token without an email claim. The policy in the next section then has nothing to compare with and denies every call, so use these methods only if you don’t add Policy in AgentCore.

With another identity provider (IdP), such as Microsoft Entra ID, you can add email to access tokens as an optional claim for both defenses to reference. However, Microsoft doesn’t guarantee that this value is correct or immutable and advises against using it for authorization. For ACL matching, your IdP or application must verify the association between the authenticated user and their email within trusted tenants. Update ACLs and sync the data source when email addresses change or are reassigned.

ACL matching uses an exact email match, so your identity provider must keep each email unique and unchanged. For this reason, the sample user pool disables self sign-up and makes the email attribute immutable.

You attach the interceptor in interceptorConfigurations of the gateway. With passRequestHeaders: true, the gateway passes the Authorization header that the JWT authorizer validated to the interceptor. The headers that the gateway passes include the bearer token, so make sure that the interceptor doesn’t log them. The sample logs only the tool name, whether the client supplied userContext, and whether the interceptor replaced it, not the event, the headers, or the token.

const gateway = new agentcore.CfnGateway(this, "Gateway", {
  name: "managed-kb-gateway",
  roleArn: gwRole.roleArn,
  protocolType: "MCP",
  authorizerType: "CUSTOM_JWT",
  authorizerConfiguration: {
    customJwtAuthorizer: { discoveryUrl, allowedClients: [userPoolClientId] },
  },
  interceptorConfigurations: [
    {
      interceptionPoints: ["REQUEST"],
      interceptor: { lambda: { arn: interceptorFn.functionArn } },
      inputConfiguration: { passRequestHeaders: true },
    },
  ],
});

Cognito access tokens carry the app client ID in client_id and include aud only when the client requests resource binding. The JWT authorizer checks allowedClients against client_id and allowedAudience against aud, and verifies both when you set both. So set only allowedClients to the app client ID. With resource binding, you can also set allowedAudience to the resource URI in aud.

The MCP client only attaches the access token to the Authorization header. It doesn’t need code that handles userContext. In the sample, the agent on AgentCore runtime forwards the access token that it received from the web app.

In the sample, AgentCore runtime and the gateway accept the same access token, and the agent forwards it. If your requirements call for tokens that only one resource accepts, request them with resource binding and set allowedAudience on each authorizer. Resource binding is available only with managed login.

Validate the injected request with Policy in AgentCore

With only the interceptor, access control depends on a single component. In the following cases, the gateway accepts a request with an invalid userContext as is:

  • A bug in the interceptor injects a wrong value or skips the overwrite.
  • An unauthorized code change injects the value of another user.
  • A configuration change detaches the interceptor from the gateway.

Policy in AgentCore evaluates tool calls to the gateway with Cedar policies. It runs after the request interceptor. It can reference the claims of the token that the JWT authorizer validated as tags on the principal. The following policy permits a call only when the injected userContext.userId matches the email claim in the JWT. The policy engine denies calls that don’t meet this condition.

permit(
  principal is AgentCore::OAuthUser,
  action == AgentCore::Action::"kb___Retrieve",
  resource == AgentCore::Gateway::"<GATEWAY_ARN>"
) when {
  principal.hasTag("email") &&
  context has input && context.input has userContext &&
  context.input.userContext has userId &&
  context.input.userContext.userId == principal.getTag("email")
};

In this policy, principal represents the authenticated user, and resource specifies the gateway ARN. The action kb___Retrieve refers to the Retrieve tool on the gateway target named kb. The when clause requires the tool argument userContext.userId to match the JWT’s email claim. The snippet shows the policy for kb___Retrieve. The sample creates a second policy with the same condition for kb___AgenticRetrieveStream, because each policy names a single action and the policy engine denies any request that no permit policy matches.

The following figure shows how Policy in AgentCore denies a tool call when the interceptor doesn’t overwrite userContext correctly.

Policy in AgentCore denying a tool call when the injected userContext does not match the token’s email claim

Figure 4: Validating the injected request with Policy in AgentCore

The interceptor and the policy both use the email from the same token, but they read it from different sources. The policy takes the expected value from the signature-verified token, and the actual value from the request body that the interceptor built. This lets it detect a missing interceptor or a wrong injection. The IdP, the pre token generation trigger, and the policy configuration itself remain shared dependencies of both. With the policy alone, the LLM goes back to constructing userContext, so we recommend that you combine injection and validation.

You attach the policy engine that holds the Cedar policy in policyEngineConfiguration of the gateway. When you set mode to ENFORCE, the gateway denies requests based on the evaluation result. When you add policies to a gateway that’s already in use, you can start with LOG_ONLY, check the decisions in the traces, and then switch to ENFORCE.

const gateway = new agentcore.CfnGateway(this, "Gateway", {
  // Authorizer and interceptor settings are the same as in the earlier example
  policyEngineConfiguration: {
    arn: policyEngine.attrPolicyEngineArn,
    mode: "ENFORCE",
  },
});

Create the gateway target before creating the Cedar policies. Creating the target registers its tool schema with the policy engine. Policy creation fails if a policy references a tool that has not yet been registered, whatever the validationMode.

Restrict access to the knowledge base with a resource-based policy

Policy in AgentCore evaluates only requests that go through a gateway with the policy engine attached. Two paths bypass the tool-layer controls. One is another gateway without the interceptor and the policy that points to the same knowledge base. The other is a direct call to the Retrieve API from an SDK or the AWS Command Line Interface (AWS CLI).

A resource-based policy denying Retrieve calls from principals other than the gateway execution role

Figure 5: Restricting callers with a resource-based policy

Managed Knowledge Base supports resource-based policies. When you attach the following policy to the knowledge base, it explicitly denies Retrieve and GetDocumentContent to principals other than the gateway execution role. Agentic retrieval can call GetDocumentContent to expand results to full documents. An explicit deny takes precedence over an allow in an identity-based policy in the same account, so the deny also applies to administrators and to other consumers of the knowledge base, such as the test window on the console. If other roles need to search the knowledge base, add their Amazon Resource Names (ARNs) to ArnNotEquals.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyRetrieveExceptGatewayRole",
      "Effect": "Deny",
      "Principal": "*",
      "Action": ["bedrock:Retrieve", "bedrock:GetDocumentContent"],
      "Resource": "arn:aws:bedrock:<REGION>:<ACCOUNT_ID>:knowledge-base/<KB_ID>",
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::<ACCOUNT_ID>:role/<GATEWAY_EXECUTION_ROLE>"
        }
      }
    }
  ]
}

With AWS CDK, you can attach this policy document with CfnKnowledgeBasePolicy, which maps to the AWS::Bedrock::KnowledgeBasePolicy resource type. Set aws:PrincipalArn to the ARN of the gateway execution role, for example gwRole.roleArn.

You can’t list bedrock:AgenticRetrieveStream in the Action element of the policy. However, the searches inside AgenticRetrieveStream authorize bedrock:Retrieve for the caller on each knowledge base. As a result, the deny in this policy also blocks searches through AgenticRetrieveStream.

A resource-based policy limits which IAM principals can search the knowledge base. It can’t deny another gateway that reuses the same execution role. Don’t share the execution role with other workloads. Restrict which users can pass the role (iam:PassRole) and manage the resource-based policy (bedrock:PutResourcePolicy, bedrock:GetResourcePolicy, and bedrock:DeleteResourcePolicy), because anyone who can change or delete the policy can remove this control. The policy also doesn’t cover control plane operations such as GetKnowledgeBase, so protect the knowledge base configuration with identity-based policies.

Test the solution

The scripts/verify_defenses.py script in the repository signs in as both users and confirms that each mechanism blocks the path that it targets. Each sample document contains a unique code, so the script can tell from a response whether a document was inadvertently disclosed. The script signs in as the demo users with ADMIN_USER_PASSWORD_AUTH. For the AWS permissions that it needs, see docs/verification.md. The agent scenario depends on the model, so the script reports it as inconclusive (SKIP) if the agent doesn’t send the spoofed userContext in three turns.

To check Policy in AgentCore and the resource-based policy on their own, deploy the stack with -c enableBypassSimulation=true. This flag adds two test gateways for the same knowledge base. One has no interceptor, and the other has neither an interceptor nor a policy engine. Both run as a test role that the resource-based policy doesn’t exempt. Redeploy without the flag after testing to remove them. The following table shows the results.

Scenario Result Blocked by
user-a and user-b send the same query Each user gets only the documents in their ACL ACL awareness
user-a calls kb___Retrieve or kb___AgenticRetrieveStream with the userContext of user-b Only the documents user-a can view return Request interceptor
user-a prompts the agent to set the userContext of user-b The agent might set it. If it does, only the documents user-a can view return Request interceptor
A client sends the userContext of another user to a gateway without an interceptor The gateway denies the tool call with a Tool Execution Denied error Policy in AgentCore
A separate gateway with no interceptor, no policy, and its own execution role searches the knowledge base The tool returns an error because the knowledge base denies the search Resource-based policy
A user with administrator permissions calls Retrieve directly from an SDK AccessDeniedException with an explicit deny in a resource-based policy Resource-based policy
A user with administrator permissions calls AgenticRetrieveStream directly from an SDK The stream fails with a dependencyFailedException that wraps the explicit deny on bedrock:Retrieve Resource-based policy

When user-a and user-b send the opening question, the answer for user-a draws on the department A business plan and the notice, and the answer for user-b draws on the department B business plan and the notice.

The web app shows the tool arguments that the LLM generated next to the documents that came back. When user-a asks the agent to search as user-b, the app shows the spoofed userContext, but only the documents of user-a appear.

The following screenshot shows the web app after user-a asks the agent to search as user-b.

The web app showing the spoofed userContext in the tool arguments while only user-a’s documents return

Figure 6: The interceptor overrides the spoofed userContext

Clean up

To avoid future charges, delete the stack when you finish testing. Run npx cdk destroy in the infra directory of the pattern. This deletes the knowledge base, the S3 buckets and their objects, the user pool, the demo user password in AWS Secrets Manager, and the Amazon CloudWatch Logs log groups of every Lambda function and of the agent runtime.

Conclusion

In this post, we showed how to share an agent and a knowledge base across a company and still limit each user’s searches to the documents they’re allowed to view. As the primary defense, a request interceptor injects userContext from the verified token, and ACL awareness in Managed Knowledge Base scopes the search. Based on your requirements, Policy in AgentCore validates the injected value independently, and a resource-based policy denies searches that bypass the gateway.

The underlying design principle is to not let the LLM generate values that affect authorization. This principle also applies to a multi-tenant SaaS architecture where multiple customers share a knowledge base. It also applies to MCP tools other than Managed Knowledge Base that take arguments affecting access control. Deploy the CDK stack from the GitHub repository and try it with your own data sources and IdP. To learn when to use interceptors and when to use policies, see Secure AI agents with Policy and Lambda interceptors in Amazon Bedrock AgentCore gateway.

The architecture in this post uses the built-in AgentCore Gateway connector for Managed Knowledge Base. If you’re considering migrating from a Customer-managed Knowledge Base to a Managed Knowledge Base, the amazon-bedrock skill in the Agent Toolkit for AWS includes a migration procedure to help you evaluate and plan the transition. It works in coding agents that you already use, such as Kiro, Claude Code, and Cursor. The agent reads your current configuration with read-only calls and writes a migration plan, optionally with a cost comparison based on your measured usage. After you approve the plan, it creates the new knowledge base next to the original and doesn’t change or delete the original. For the benefits of Managed Knowledge Base and a step-by-step migration walkthrough, see Migrate to Amazon Bedrock Managed Knowledge Base with your coding agent.


About the authors

Source: AWS Machine Learning Blog · aws.amazon.com