AWS Bedrock AgentCore
Overview
AWS Bedrock AgentCore is Amazon's managed platform for building and operating production AI agents. A Gateway is a managed front door: an MCP Gateway aggregates tools (Lambda, OpenAPI, and MCP servers); a protocol-less Gateway can proxy HTTP Runtime, inference, and custom targets.
Akto secures this traffic with a gateway interceptor: an AWS Lambda function that AgentCore invokes on every request and response passing through the gateway. It validates MCP tools/call traffic (and buffered HTTP target bodies) against your Akto guardrail policies in real time: blocking disallowed calls, redacting sensitive results, holding traffic for human approval when configured, and ingesting activity into the Akto dashboard.
The integration is a public Lambda layer. Attach the layer, set two environment variables, and either:
use Akto's one-line handler if the gateway has no interceptor yet, or
wrap your existing handler if the gateway already has an interceptor.
Open source: github.com/akto-api-security/aws-bedrock-agentcore.
How It Works
A single Lambda is attached to the gateway at two interception points: REQUEST (before the target runs) and RESPONSE (after the target returns). The same function handles both; it detects which phase it is from the event.
What gets guardrailed
MCP tools/call
Validated; blocked, rewritten, or held for approval
Result validated; blocked or redacted
MCP tools/list, initialize, notifications/*, ping
Passed through
Passed through
HTTP-family targets (AgentCore Runtime, inference, custom) in buffered mode
Non-empty bodies validated
Non-empty bodies validated
Guarding an AgentCore Runtime agent
To guardrail the user's prompt and the Runtime's final response, place the Runtime behind a separate Gateway with an HTTP Runtime target:
The outer Gateway invokes Akto for the HTTP request and response. The inner MCP Gateway invokes Akto for tool calls and tool results. Both gateways can use the same interceptor Lambda.
Important AWS requirements:
Create the outer Gateway without
protocolType=MCP; MCP gateways reject HTTP targets.Add the Runtime as an
http.agentcoreRuntimetarget and use buffered responses.Invoke it at
https://<gateway-id>.gateway.bedrock-agentcore.<region>.amazonaws.com/<target-name>/invocations.Restrict the Runtime resource policy to the outer Gateway execution role. Otherwise callers with
InvokeAgentRuntimecan bypass the Gateway and Akto.
The outer Gateway sees the initial user request and final agent response. Calls the agent makes internally to a Bedrock model are not Gateway traffic; use in-agent hooks or a model proxy if those intermediate model requests must also be inspected.
Existing interceptor composition
If you wrap an existing interceptor, your handler runs first. Akto then scans the effective request or response after your transformations, so later code cannot bypass a block or redaction. Your headers, status codes, and unrelated fields are retained. Akto's block or rewrite takes precedence.
What You'll Achieve
✅ Real-time tool-call guardrails: block disallowed tools/call before the tool executes
✅ Response redaction: strip or block sensitive data in tool results before the client sees them
✅ Human approval: hold a call until an admin decides in Akto (up to Lambda's timeout)
✅ Full observability: every guarded call is ingested into the Akto dashboard
✅ Managed enforcement: runs inside AWS as a gateway interceptor; no proxy or sidecar
✅ Fail-closed by default: if Akto is unreachable or approval is unresolved, the call is blocked (set AKTO_FAIL_OPEN=true to allow)
Prerequisites
AWS
An existing AgentCore Gateway: note its Gateway ID and Region. MCP Gateways guard tool traffic; a separate protocol-less Gateway with an HTTP Runtime target is required to guard agent prompts and final responses.
AWS credentials with permissions for
lambda:*(including attaching a layer),iam:CreateRole/PutRolePolicy/PassRole(CLI only), andbedrock-agentcore-control:GetGateway/UpdateGateway,ListGatewayTargets,GetGatewayTargetFor the CLI method:
awsCLI v2,jq, andzipinstalled locally
Akto
Akto Data Ingestion URL (
AKTO_DATA_INGESTION_URL) — base URL only, no/api/ingestDataand no/api/http-proxyAkto API token (
AKTO_API_TOKEN)
Choose your path
No interceptor
Deploy Akto's Lambda with the CLI or Console (layer + one-line handler), attach it as REQUEST + RESPONSE.
Already has an interceptor
Keep that Lambda. Attach the Akto layer, set env vars, wrap your handler. Do not replace the gateway interceptor with a second Lambda unless AWS chaining is confirmed for your account
Akto Lambda layer
Attach this versioned layer to the interceptor Lambda in the same Region. Layers are Region-specific; pin the exact version.
Current public us-east-1 layer:
Compatible runtimes: Python 3.10–3.13. Architectures: x86_64 and arm64. Other accounts can attach this version (lambda:GetLayerVersion is granted to *).
To publish the same artifact in another Region from the repo:
Setup: no existing interceptor
Use this when the gateway does not already run a custom interceptor Lambda.
Clone the repository
Create your .env
Fill in the required values:
AKTO_LAYER_ARN must be a versioned layer in the same Region as the Lambda. Use the us-east-1 ARN above, or the ARN printed by deploy/publish-layer.sh for another Region.
Run the deploy script
The script creates the Lambda execution role (with the required IAM policies), deploys a thin handler that imports akto_agentcore.lambda_handler from the layer, then for each gateway in GATEWAY_IDS grants invoke permission and attaches the interceptor (REQUEST + RESPONSE, with request headers enabled). It is idempotent: safe to re-run.
Create the Lambda function
Open the AWS Lambda console (in the same Region as your gateway) → Create function → Author from scratch.
Function name:
akto-guardrails-interceptorRuntime: Python 3.12 (or 3.13)
Architecture:
x86_64orarm64
Click Create function.
Attach the Akto layer
On the function page: Code → Layers → Add a layer → Specify an ARN. Paste the versioned ARN for your Region, for example:
Click Add.
Add the one-line handler
On the Code tab, replace the default file with handler.py:
Runtime settings → Edit → Handler = handler.lambda_handler. Click Save. Deploy the code if the console asks you to.
Set environment variables and timeout
Go to Configuration → Environment variables → Edit and add:
AKTO_DATA_INGESTION_URL
https://your-akto-instance.com (base URL only)
AKTO_API_TOKEN
your Akto API token (Akto Argus → Connectors → Setup Guardrail)
Optional: AKTO_FAIL_OPEN=false, AKTO_TIMEOUT_SECONDS=30, AKTO_APPROVAL_WAIT_SECONDS=840, AKTO_APPROVAL_POLL_SECONDS=2.
Under Configuration → General configuration, set Timeout to 15 minutes (900 seconds) if you use human-approval policies. Click Save.
Add IAM policy on the Lambda execution role
Open Configuration → Permissions → click the Execution role → Add permissions → Create inline policy → JSON. Name it akto-interceptor-discovery and paste:
Guardrails still work without this policy; it only adds agent and IAM context to Akto. deploy.sh adds it automatically.
Copy the Function ARN shown at the top right of the function page: you'll need it in the next steps.
Allow the gateway to invoke the Lambda
The gateway calls the interceptor using its own execution role, so that role needs lambda:InvokeFunction permission.
In the Bedrock AgentCore console, open your Gateway and note its execution role (an IAM role ARN under the gateway details).
Open the IAM console → Roles → find that role → Add permissions → Create inline policy → JSON tab, and paste (replace the ARN with your function ARN):
Name it
invoke-akto-guardrails-interceptorand Create policy.
Attach the interceptor to the gateway
Back in the Bedrock AgentCore console → your Gateway → Edit, find the interceptor configuration and paste the same Function ARN into both fields:
Request Interceptor Lambda ARN → your function ARN: set Pass request header to True
Response Interceptor Lambda ARN → the same function ARN: set Pass request header to True
Leave Exclude the response body from the interceptor Lambda invocation unchecked
Click Save / Update gateway.
Setup: existing interceptor
Use this when the gateway already invokes your Lambda on REQUEST and/or RESPONSE. You keep that function, your business logic, and the gateway attachment. Akto is added as a layer around your handler.
Attach the Akto layer to your existing Lambda
Lambda console → your interceptor function → Code → Layers → Add a layer → Specify an ARN. Paste the versioned ARN for the function's Region:
Wrap your handler
Do not replace your interceptor. After your lambda_handler is defined, wrap it:
Keep Runtime settings → Handler pointing at the same entry point you already use (for example handler.lambda_handler). Deploy the function.
Set Akto environment variables
Configuration → Environment variables — add (do not remove your existing variables):
AKTO_DATA_INGESTION_URL
Base URL of your Akto instance, no path
AKTO_API_TOKEN
Token from Akto Argus → Connectors → Setup Guardrail
Optional: AKTO_FAIL_OPEN, AKTO_TIMEOUT_SECONDS, AKTO_APPROVAL_WAIT_SECONDS, AKTO_APPROVAL_POLL_SECONDS (see Environment Variables).
If you did not use deploy.sh, add the akto-interceptor-discovery inline policy (same JSON as in the console setup above) to this function's execution role.
Timeout for human approval
If you use human-approval policies, set the Lambda timeout to 900 seconds. Approval polling waits up to AKTO_APPROVAL_WAIT_SECONDS (default 840).
Leave the gateway interceptor pointing at your Lambda
You do not change the gateway's interceptor ARN. Confirm it still lists your function for REQUEST and RESPONSE, Pass request header is True, and Exclude the response body is unchecked.
Verify the Integration
Tail the Lambda logs and make a tool call through the gateway:
On a tools/call you should see:
A blocked call returns a JSON-RPC error to the client instead of the tool result, and the tool activity appears in the Akto dashboard.
Environment Variables
AKTO_DATA_INGESTION_URL
(required)
Base URL of your Akto data ingestion service (no /api/http-proxy)
AKTO_API_TOKEN
(required)
Authorization token sent to the Akto API
AKTO_FAIL_OPEN
false
If true, Akto errors and unresolved human approval allow the call
AKTO_TIMEOUT_SECONDS
30
Timeout for each Akto guardrails API request
AKTO_APPROVAL_WAIT_SECONDS
840
Max seconds to poll for a human_approval decision
AKTO_APPROVAL_POLL_SECONDS
2
Interval between approval status polls
Set the Lambda timeout to 900 seconds when human approval is enabled.
Guardrail Behaviour
The interceptor reads the guardrail verdict from Akto and acts on the policy behaviour:
Allowed
Traffic passes through (existing interceptor transforms are kept)
Blocked (block)
Returns an error; the tool never runs (REQUEST) or the result is replaced (RESPONSE)
warn / alert
Traffic is allowed and logged: a gateway has no interactive resubmit path, so warnings cannot hard-block
Modified
The tool arguments (REQUEST) or result (RESPONSE) are rewritten with Akto's redacted payload
human_approval
Lambda polls Akto until approved, blocked, or timeout
Akto error / timeout / no config
Fail-closed by default (block). Set AKTO_FAIL_OPEN=true to pass traffic through
Troubleshooting
Interceptor not firing
You should see your Lambda ARN with interceptionPoints of ["REQUEST","RESPONSE"] and passRequestHeaders: true.
No module named 'akto_agentcore'
The layer is missing, in the wrong Region, or not attached to this function version. Confirm Layers on the Lambda shows the versioned akto-agentcore ARN, then deploy a new version if you attached the layer after the last publish.
Guardrails always blocking (fail-closed)
The interceptor fails closed unless AKTO_FAIL_OPEN=true. Check the Lambda logs:
Common causes:
AKTO_DATA_INGESTION_URLnot set, includes a path it should not, or is unreachable from the LambdaThe Lambda is in a VPC without outbound internet (NAT) to reach Akto
Guardrail policies not configured in the Akto dashboard
Human approval still
pendingwhen the wait budget expires
Tool results not guardrailed
Confirm the Response Interceptor is configured (same Lambda ARN) and that Exclude the response body is unchecked. Look for Guardrailing RESPONSE tools/call result: in the logs.
Get Support for your Akto setup
There are multiple ways to request support from Akto. We are 24X7 available on the following:
In-app
intercomsupport. Message us with your query on intercom in Akto dashboard and someone will reply.Join our discord channel for community support.
Contact
help@akto.iofor email support.Contact us here.
Last updated