Secure multi-tenant AI agents with Amazon Bedrock AgentCore resource-based policies
Source: AWS - Security
Software as a service (SaaS) providers building AI-powered applications on Amazon Bedrock AgentCore often need to serve multiple tenants with distinct security requirements from a shared infrastructure. Some tenants require cross-account access from their own Amazon Web Services (AWS) accounts, while others mandate that traffic stay within a private virtual private cloud (VPC) for regulatory compliance. Without centralized resource-level control, managing these diverse requirements can be complex.
AgentCore supports resource-based policies, giving you centralized, resource-level control over who can access your AgentCore Runtime and AgentCore Runtime endpoint resources and under what conditions.
In this post, you walk through a multi-tenant AI customer service platform where two tenants need different levels of access to the same agent. You learn how to use resource-based policies on AgentCore to grant cross-account access for one tenant while restricting another to VPC-only trafficâall while sharing the same underlying AgentCore Runtime and AgentCore Runtime endpoint.
The multi-tenant scenario
Imagine youâre an SaaS provider who builds and operates an AI-powered customer service platform. You use AgentCore to deploy intelligent agents that handle customer inquiries, answering product questions, processing returns, and escalating complex issues to human agents.
You serve multiple enterprise clients (tenants), each with their own AWS account and unique security requirements:
- Tenant A: Example Corp is a large retailer operating in AWS account 111122223333. Their development team is building a customer-facing chat agent that calls your AI agent to answer product questions in real time, and their admin team needs access to test agent behavior and monitor responses. Both roles must invoke the agent directly from Example Corpâs own AWS account without you having to share credentials or create AWS Identity and Access Management (IAM) users on their behalf. Example Corp has no network restriction requirementsâtheir teams can invoke the agent from any network path as long as they have valid AWS credentials.
- Tenant B: AnyCompany is a healthcare company operating in AWS account 444455556666. Because of regulatory (HIPAA) requirements, AI agent traffic must originate only from their private VPC (vpc-health1234). Their internal support staff uses the AI agent to assist with patient billing inquiries, which might involve protected health information (PHI). Their compliance team mandates that no API call to the agent can be made from developer laptops, public endpoints, or any network outside the controlled VPC boundary.
- Your platform (SaaS provider) runs in account 555555555555 in the us-west-2 AWS Region. You operate an AgentCore Runtime (
support-agent-runtime) that handles the core customer service logic, and an AgentCore Runtime endpoint (DEFAULT) that routes requests to the latest version of the support agent. Both tenants share this same agent infrastructure.
You can use resource-based policies to define who can access your AgentCore Runtime and AgentCore Runtime endpoint directly on the resources themselvesâcentralizing access control on the resource side. For cross-account scenarios like Example Corp, both a resource-based policy on your resources and an identity-based policy in the tenantâs account are required. For VPC-restricted scenarios like AnyCompany, you can use specific IAM conditions to enforce that requests originate only from an approved VPC, adding a network-level security boundary on top of identity-based controls.
Solution architecture
The following diagram shows the architecture for the multi-tenant AI customer service platform with both access patterns.
Figure 1: Architecture for the multi-tenant AI customer service platform with both access patterns
- Your account (555555555555) with AgentCore Runtime and AgentCore Runtime endpoint
- Example Corpâs account (111122223333) with
DeveloperRoleandAdminRole - AnyCompanyâs account (444455556666) with VPC boundary and
ApplicationRole - Policy enforcement points on both resources
- VPC endpoint in AnyCompanyâs VPC connecting to AgentCore
The SaaS provider account (555555555555) hosts the AgentCore Runtime and AgentCore Runtime endpoint that both tenants share. Example Corp (111122223333) accesses the agent cross-account using IAM rolesâDeveloperRole and AdminRoleâauthenticated with Signature Version 4 (SigV4), the standard AWS request signing protocol. AWS evaluates both the resource-based policy on your resources and the identity-based policy in Example Corpâs account before granting access.
AnyCompany (444455556666) also accesses the agent cross-account, but with an additional constraint: all requests must originate from within their private VPC (vpc-health1234) through a VPC endpoint for AgentCore. The resource-based policy on your resources includes an explicit Deny statement that blocks any request from AnyCompanyâs ApplicationRole when it doesnât originate from the approved VPC.
In both cases, resource-based policies must be applied to both the AgentCore Runtime and AgentCore Runtime endpoint. AWS evaluates policies on both resources for InvokeAgentRuntime operationsâif either resource denies access or lacks an explicit Allow, the request is denied.
Prerequisites
Before you begin, ensure you have the following:
- An AWS account with AgentCore access and permissions to call
PutResourcePolicy,GetResourcePolicy, andDeleteResourcePolicyon AgentCore resources - AWS Command Line Interface (AWS CLI) v2 installed and configured with the
bedrock-agentcore-controlAPI available - An AgentCore Runtime with SigV4 authentication and a
DEFAULTAgentCore Runtime endpoint pointing to the latest runtime version
For the VPC-restricted scenario, the tenant must have a VPC endpoint for AgentCore configured in their VPC. An interface VPC endpoint creates a private connection between the tenantâs VPC and the AgentCore service without requiring traffic to traverse the public internet. For more information, see Interface VPC endpoints for Amazon Bedrock AgentCore.
Implementation
Both Example Corp and AnyCompanyoperate in separate AWS accounts from your platform. For cross-account access to AgentCore Runtime, AWS requires that both of the following allow the action:
- A resource-based policy in your platform account applied to both the AgentCore Runtime and its AgentCore Runtime endpoint. InvokeAgentRuntime operations require an explicit
Allowon both resourcesâif either lacks one, the request is denied. - An identity-based policy attached to the callerâs IAM role in the tenantâs account.
If either side is missing or denies the action, the request is denied.
Step 1: Configure cross-account access for Example Corp (Tenant A)
Example Corpâs DeveloperRole and AdminRole in account 111122223333 need to invoke your AI customer service agent. Without resource-based policies, enabling this cross-account access would typically require Example Corpâs roles to assume a role in your platform account through IAM role chainingâadding operational complexity, introducing temporary credential management, and creating additional IAM roles that must be maintained in your account for each tenant. With resource-based policies, you grant Example Corpâs roles direct access to your AgentCore Runtime and AgentCore Runtime endpoint without role chaining. Example Corpâs roles can invoke the agent directly from their own account using their own credentials, while you maintain centralized control over access on the resource side.
AgentCore Runtime resource-based policy
The following policy grants Example Corpâs DeveloperRole and AdminRole permission to invoke the agent runtime. This is the first of two resource-based policies requiredâit controls access to the runtime resource itself. Save this as runtime-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowExampleCorpCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:role/DeveloperRole",
"arn:aws:iam::111122223333:role/AdminRole"
]
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime"
}
]
}
AgentCore Runtime endpoint resource-based policy
The following policy grants the same roles permission to invoke the AgentCore Runtime endpoint. Without this second policy, requests are allowed at the runtime level but denied at the endpoint level, and the invocation fails. Save this as endpoint-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowExampleCorpCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:role/DeveloperRole",
"arn:aws:iam::111122223333:role/AdminRole"
]
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:999999999999:runtime/support-agent-runtime/runtime-endpoint/DEFAULT"
}
]
}
To apply the resource-based policies
aws bedrock-agentcore-control put-resource-policy \--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime \--policy file://runtime-policy.json \--region us-west-2
aws bedrock-agentcore-control put-resource-policy \--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT \--policy file://endpoint-policy.json \--region us-west-2
To verify the resource-based policies
aws bedrock-agentcore-control get-resource-policy \--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime \--region us-west-2
aws bedrock-agentcore-control get-resource-policy \--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT \--region us-west-2
Configure an identity-based policy (Example Corpâs account)
Resource-based policies alone arenât sufficient for cross-account access. Example Corp must also attach an identity-based policy to DeveloperRole and AdminRole in their account (111122223333) that allows the same action on your resources. Without this policy on the tenant side, IAM denies the cross-account request even though your resource-based policies allow it.
Example Corp attaches the following policy to both DeveloperRole and AdminRole:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowInvokeAgentRuntime",
"Effect": "Allow",
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime",
"arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT"
]
}
]
}
Attach this policy to both DeveloperRole and AdminRole in Example Corpâs account.
Step 2: Configure cross-account with VPC-restricted access for AnyCompany (Tenant B)
AnyCompany operates under HIPAA compliance requirements and mandates that all traffic to your agent stays within a private network path. Like Example Corp, AnyCompany needs cross-account access from account 444455556666âbut with an additional constraint, requests must originate from their VPC vpc-health1234 through an interface VPC endpoint. Any request from outside this VPC is denied, even if it comes from AnyCompanyâs ApplicationRole.
Resource-based policies (your platform account): To enforce this, you update the resource-based policies on both the AgentCore Runtime and AgentCore Runtime endpoint. Each policy includes an Allow statement that grants ApplicationRole permission to invoke the agent, paired with a Deny statement that blocks any request not originating from vpc-health1234. In the following policy, the Deny statement uses StringNotEquals on aws:SourceVpc . When a request arrives through an interface VPC endpoint, AWS populates this key with the VPC ID. If it doesnât match vpc-health1234, or if the key is absent because no VPC endpoint was used, the Deny takes effect. Because an explicit Deny overrides any Allow from any policy, this pattern helps ensure that no other identity-based or resource-based policy can inadvertently grant AnyCompany access from outside the VPC. Add the following statements to runtime-policy-v2.json alongside the Example Corp statement from Step 1:
{
"Sid": "AllowAnyCompanyCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::444455556666:role/ApplicationRole"
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime"
},
{
"Sid": "DenyAnyCompanyOutsideVpc",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::444455556666:role/ApplicationRole"
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime",
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": "vpc-health1234"
}
}
}
AgentCore Runtime endpoint resource-based policy
Add the equivalent statement to endpoint-policy-v2.json:
{
"Sid": "AllowAnyCompanyCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::444455556666:role/ApplicationRole"
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT"
},
{
"Sid": "DenyHealthFirstOutsideVpc",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::444455556666:role/ApplicationRole"
},
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": "arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT",
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": "vpc-health1234"
}
}
}
Because put-resource-policy replaces the entire policy on a resource, your updated policy files must include both the preceding AnyCompany statments and the Example Corp statements from Step 1.
Apply the updated resource-based policies
aws bedrock-agentcore-control put-resource-policy \
--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime \
--policy file://runtime-policy-v2.json \
--region us-west-2
aws bedrock-agentcore-control put-resource-policy \
--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT \
--policy file://endpoint-policy-v2.json \
--region us-west-2
Verify the updated policies
After applying the final policies, verify them using the get-resource-policy command:
# Verify Agent Runtime policy
aws bedrock-agentcore-control get-resource-policy \
--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime \
--region us-west-2
# Verify Agent Runtime Endpoint policy
aws bedrock-agentcore-control get-resource-policy \
--resource-arn arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT \
--region us-west-2
Identity-based policy (AnyCompanyâs account)
AnyCompany must attach an identity-based policy to ApplicationRole in their account 444455556666 that allows the same InvokeAgentRuntime on your resources in account 555555555555. Without this policy on the tenant side, IAM denies the cross-account request even though your resource-based policies allow it.
AnyCompany attaches the following policy to ApplicationRole:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowInvokeAgentRuntime",
"Effect": "Allow",
"Action": "bedrock-agentcore:InvokeAgentRuntime",
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime",
"arn:aws:bedrock-agentcore:us-west-2:555555555555:runtime/support-agent-runtime/runtime-endpoint/DEFAULT"
]
}
]
}
The VPC restriction is enforced entirely on resource account through the resource-based policy condition, AnyCompanyâs identity-based policy doesnât need VPC conditions. This keeps the tenant-side configuration straightforward while you maintain centralized network-level control.
OAuth authentication considerations
The policies in this post use SigV4 authentication with specific IAM role principals. If your AgentCore Runtime or AgentCore Gateway is configured with OAuth authentication instead, the principal structure changes. OAuth-authenticated resources require a wildcard principal (âPrincipal": "*") because the caller identity comes from a JSON Web Token (JWT) validated before policy evaluation. Anonymous or unauthenticated requests are rejected before the policy is evaluated, so the wildcard principal doesnât grant open access. To restrict OAuth-authenticated requests to a specific VPC, combine the wildcard principal with a VPC condition in the resource-based policy. IAM principal-based condition keys such as aws:PrincipalAccount and aws:PrincipalOrgID arenât populated in the OAuth authentication contextâonly supported network-level condition keys (such as aws:SourceVpc, aws:SourceVpce, aws:SourceIp) are available for use in resource-based policies with OAuth. For more details, see Resource-based policies for Amazon Bedrock AgentCore.
Understanding policy evaluation
To understand how AWS evaluates these policies when a request arrives, consider the following scenarios:
| Caller or principal | Network | Identity-based policy (tenant side) | Runtime resource-based policy | Runtime endpoint resource-based policy | Final policy evaluation result |
| Example Corp | Any network | Allows | Allows | Allows | Allowed |
| Example Corp | Any network | Allows | Allows | Allows | Allowed |
| AnyCompany | From | Allows | Allows ( does not match) | Allows ( does not match) | Allowed |
| AnyCompany | Outside VPC | Allows | matches | matches | Denied |
| Any other cross-account role | Any network | Allows | No matching | No matching | Denied |
| Any other cross-account role | Any network | No policy | Allows | Allows | Denied |
Conclusion and next steps
In this post, you learned how to use resource-based policies on AgentCore to secure a multi-tenant AI platform with distinct access patterns for each tenant:
- Example Corp gets seamless cross-account integration, their development and admin teams can invoke your AI agent directly from their own AWS account without credential management.
- AnyCompany gets the strict network-level isolation their compliance team requires, the AI agent is accessible only from within their private VPC, ensuring that interactions involving potential PHI â stay within the controlled network boundary
Both tenants share the same underlying AgentCore Runtime and AgentCore Runtime endpoint, yet each has tailored security controls enforced at the resource level. his approach avoids per-tenant infrastructure duplication while satisfying each tenantâs security posture, a challenge you likely face when onboarding tenants with different compliance postures. Resource-based policies complement identity-based IAM policies, giving you layered control over which principals can invoke which agents, and from which network paths.
Next steps
- Learn more about Amazon Bedrock AgentCore in the official documentation
- Review resource-based policies for Amazon Bedrock AgentCore
- Explore other AWS global condition keys including aws:SourceVpce and aws:PrincipalOrgID
- Visit the AWS Well-Architected Framework Security Pillar for multi-tenancy best practices
If you have feedback about this post, submit comments in the Comments section below.