
I implemented IAM authentication from AgentCore Runtime to AgentCore Gateway using MCP Proxy for AWS
This page has been translated by machine translation. View original
Introduction
Hello, I'm Jinno from the Consulting Department, who loves La Mu supermarket (@yjinno).
How do you handle Inbound Auth authentication when calling a Gateway from Amazon Bedrock AgentCore Runtime?
When AgentCore was in Preview, I thought M2M authentication was the way to go,
but now that Gateway also supports IAM authentication, I wondered if IAM authentication might be simpler in some cases... which prompted me to write this article.
Prerequisites
Environment
I used the following versions for this implementation:
| Item | Version |
|---|---|
| Terraform | >= 1.5.0 |
| AWS Provider | >= 6.25.0 |
| Python | 3.12 |
| bedrock-agentcore | >= 1.2.0 |
| strands-agents | >= 1.22.0 |
| mcp-proxy-for-aws | >= 1.1.5 |
Architecture Overview
Here's the architecture we'll be building:
Gateway calls will use IAM authentication, and Runtime calls will also use IAM authentication for simplicity.

For the complete Terraform code, please refer to the repository below:
Terminology
Since AgentCore has two layers of authentication for Runtime and Gateway, let's clarify the terminology first:
- Runtime Inbound Auth
- Authentication (IAM or JWT) when clients (people/applications) call AgentCore Runtime
- Gateway Inbound Auth
- Authentication (IAM (SigV4) or JWT) when Runtime calls AgentCore Gateway
- Gateway Outbound Auth
- Authentication (SigV4, etc.) when Gateway calls targets (e.g., Lambda/external API)
The main focus of this article is Runtime → Gateway calls (= Gateway Inbound Auth).
Runtime Inbound Auth is set to IAM to simplify verification.
Authentication Methods for Runtime→Gateway
M2M Authentication
Initially, I was considering M2M (Machine-to-Machine) authentication for Runtime→Gateway.
However, using M2M authentication requires:
- Setting up a Cognito User Pool
- Creating a Machine-to-Machine application client
- Managing client secrets
- Implementing token acquisition and refresh
Creating Cognito and acquiring tokens takes a bit more effort.
Of course, token acquisition can be simplified by utilizing the SDK.
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token, requires_api_key
@requires_access_token(
provider_name= "sample-provider",
scopes= [],
auth_flow= 'M2M',
)
async def need_token_2LO_async(*, access_token: str):
IAM Authentication
On the other hand, IAM authentication offers these advantages:
- No Cognito needed
- No secret management required (completed with IAM roles)
- Just add
bedrock-agentcore:InvokeGatewaypermission to Runtime's IAM role - SigV4 signatures automated with
mcp-proxy-for-aws
Since AgentCore Runtime already has an IAM role, it's nice that we just need to add permissions to the Gateway without building additional authentication infrastructure.
The Gateway configuration is also simple - just specify AWS_IAM for the authorizer_type:
resource "aws_bedrockagentcore_gateway" "main" {
name = "${var.project_name}-gateway"
role_arn = aws_iam_role.gateway.arn
protocol_type = "MCP"
# Inbound authentication: Specify IAM authentication
authorizer_type = "AWS_IAM"
# ...omitted
}
For the Runtime side, add the bedrock-agentcore:InvokeGateway permission:
resource "aws_iam_role_policy" "agent_runtime_gateway" {
name = "${var.project_name}-agent-runtime-gateway-policy"
role = aws_iam_role.agent_runtime.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "InvokeGateway"
Effect = "Allow"
Action = [
"bedrock-agentcore:InvokeGateway"
]
Resource = aws_bedrockagentcore_gateway.main.gateway_arn
}
]
})
}
While MCP clients normally expect token authentication when connecting to a Gateway,
AgentCore Gateway requires IAM (SigV4) authentication. You might wonder about signature processing, but fortunately, the useful MCP Proxy for AWS library bridges this gap!
We'll look at the detailed implementation later.
When to Use IAM vs M2M Authentication
So far I've explained the advantages of IAM authentication, but you might wonder when to use M2M authentication.
If you have multiple agents and need fine-grained authorization control at the tool level for each agent, M2M authentication might be worth considering. Let's look at the differences in detail.
IAM Authentication Constraints
IAM authentication allows access control at the Gateway level.
{
"Action": "bedrock-agentcore:InvokeGateway",
"Resource": "arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/my-gateway"
}
You can't control access at the tool level, like allowing a Runtime to use only specific tools within a Gateway.
So if you need different agents to execute different sets of tools, you'll likely need to separate Gateways.
Something like this:

If you're using very few tools, you might not need a Gateway at all, or if you only have general-purpose tools that all agents can use, a single Gateway might be sufficient.
What M2M Authentication + Interceptor/Policy Can Do
On the other hand, combining M2M JWT authentication with Gateway Interceptors/Cedar Policies enables more granular authorization control.
Consider a scenario with multiple AI agents where you want to restrict which tools each agent can use:

Such control can be achieved by verifying JWT scopes or attributes through Interceptors or Cedar Policies.
Choosing an Authentication Method
| Pattern | Use Case | Tool-level Authorization |
|---|---|---|
| IAM Authentication | Simple setup, all tools accessible | Not possible |
| M2M JWT + Interceptor/Policy | Multi-agent, tool-level authorization needed | Possible |
I believe IAM authentication is sufficient for simple setups with a single agent.
If you have multiple agents and need to grant each different access permissions to tools within a single Gateway, consider M2M authentication.
I'd like to explore and introduce methods for separating permissions per agent in a future article.
Notes on M2M Authentication
There are some considerations when adopting custom attributes with M2M authentication:
If you want to control authorization based on user permissions, you'll need to implement user delegation-based permission control. This discussion is limited to cases where the authorization subject is the agent.
Implementation with Strands Agents
Agent Implementation
Let's look at the implementation code.
This is a simple agent that connects to the Gateway and calls tools.
import os
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from strands.models import BedrockModel
from strands.tools.mcp import MCPClient
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
GATEWAY_URL = os.getenv("GATEWAY_URL", "")
AWS_REGION = os.getenv("AWS_REGION", "us-east-1")
MODEL_ID = os.getenv("BEDROCK_MODEL_ID", "us.anthropic.claude-haiku-4-5-20251001-v1:0")
app = BedrockAgentCoreApp()
model = BedrockModel(model_id=MODEL_ID, region_name=AWS_REGION)
@app.entrypoint
def invoke(payload: dict) -> dict:
message = payload.get("prompt") or payload.get("message", "")
if not message:
return {"error": "No message", "status": "error"}
if GATEWAY_URL:
# Create MCP client with SigV4 signature using mcp-proxy-for-aws
mcp_factory = lambda: aws_iam_streamablehttp_client(
endpoint=GATEWAY_URL,
aws_region=AWS_REGION,
aws_service="bedrock-agentcore"
)
mcp_client = MCPClient(mcp_factory)
agent = Agent(model=model, tools=[mcp_client])
result = agent(message)
else:
agent = Agent(model=model)
result = agent(message)
return {"response": str(result.message), "status": "success"}
if __name__ == "__main__":
app.run()
The key point is the core part for connecting to the Gateway with IAM authentication using aws_iam_streamablehttp_client:
mcp_factory = lambda: aws_iam_streamablehttp_client(
endpoint=GATEWAY_URL,
aws_region=AWS_REGION,
aws_service="bedrock-agentcore"
)
| Parameter | Value | Description |
|---|---|---|
| endpoint | Gateway URL | AgentCore Gateway endpoint URL |
| aws_region | us-east-1 etc. | AWS Region |
| aws_service | bedrock-agentcore | Service name used for SigV4 signature |
By specifying bedrock-agentcore as the aws_service, the correct SigV4 signature is added to Gateway requests. Nice and simple to use!
The rest is nearly identical to a standard MCP Client implementation.
The client executes list_tools_sync to synchronize with Gateway tools.
mcp_factory = lambda: aws_iam_streamablehttp_client(
endpoint=GATEWAY_URL,
aws_region=AWS_REGION,
aws_service="bedrock-agentcore"
)
with MCPClient(mcp_factory) as mcp:
agent = Agent(model=model, tools=mcp.list_tools_sync())
result = agent(message)
Trying It Out
Let's deploy this configuration using Terraform and verify that requests are properly sent to the Gateway!
Clone the Repository
First, clone the repository:
git clone https://github.com/yuu551/runtime-to-gateway-for-iam.git
cd runtime-to-gateway-for-iam
Initialize and Deploy Terraform
Initialize Terraform:
terraform init
Then, check the deployment plan:
terraform plan
After confirming that Gateway, Runtime, Lambda functions, and other resources will be created,
execute the deployment:
terraform apply
When prompted for confirmation, enter yes:
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
When deployment is complete, you'll see output like this:
Apply complete! Resources: 23 added, 0 changed, 0 destroyed.
Outputs:
gateway_endpoint = "https://xxxxxxxxxx.bedrock-agentcore.us-east-1.amazonaws.com"
runtime_endpoint = "https://yyyyyyyyyy.bedrock-agentcore.us-east-1.amazonaws.com"
Deployment complete!
Testing from the Console
Now that we've deployed, let's test by sending requests from the console.
We expect to receive responses from the Lambda function attached to the Gateway.
- Addition tool
- Multiplication tool
- Greeting tool
- Tool search tool made available by Gateway
{"prompt": "Tell me what I can do with tools"}

The tool list was returned as expected!
Now let's check if the addition tool works:
{"prompt": "What is 100 + 12?"}

The tool executed without issues! Looking at the logs confirms the tool execution:
{
"message": {
"tool_calls": [
{
"type": "function",
"id": "tooluse_c9qOEPXPS2a6OR8UxN4tfg",
"function": {
"name": "iam-auth-demo-lambda-target___add_numbers",
"arguments": {
"a": 100,
"b": 12
}
}
}
],
"role": "assistant"
},
"index": 0,
"finish_reason": "tool_use"
}
This confirms that Runtime→Gateway works with IAM authentication!
Conclusion
Using mcp-proxy-for-aws makes it convenient to call Gateway from Runtime without worrying about SigV4 signatures.
For simple configurations, IAM authentication can be a viable option as it doesn't require Cognito or secret management.
On the other hand, for multi-agent environments where tool-level authorization is needed per agent, consider using M2M authentication + Interceptor/Policy combinations.
I hope this article was helpful!
Thank you for reading!!


