Abstract technical illustration on a dark navy field: a single small glowing amber hexagonal agent glyph sits at the lower left inside a large translucent rectangular boundary; a thin line runs from it to a small stack of server panels enclosed in a ring, and a fan of fine cyan filaments spreads from that stack to dozens of small agent glyphs arranged on a wide grid inside the boundary. No text, people or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.
AI Safety Incidents

One Prompt, One Agent, an Entire AWS Account: Inside AgentCorruption on Amazon Bedrock AgentCore

Author

Elias Hawthorne

Date Published

Latest models · 20View all models →
Benchmarks: Artificial Analysis · updated daily
Back to all posts

On 8 October 2026, Zenity Labs disclosed AgentCorruption: a chain of flaws in Amazon Bedrock AgentCore, AWS's managed platform for deploying and running AI agents, that let a single natural-language prompt to one public-facing agent take control of every AgentCore agent in the same AWS account and region. The research was published alongside a talk at SecTor 2026 in Toronto, where Zenity's director of security research, Tamir Ishay Sharbat, presented it (Dark Reading, 8 October 2026). Zenity's own write-up, credited to Sharbat, Lana Salameh, Dmitry Lozovoy and João Donato, opens with the mechanism: an AgentCore agent that has any tool able to make an outbound request can be steered into calling the AWS Instance Metadata Service (IMDS) at the link-local address 169.254.169.254, which returns temporary credentials for the agent's own execution role. Zenity states it exported those credentials to its own machine and confirmed they worked from there. No CVE identifier was assigned.

The archive records this as a vulnerability — something found, not necessarily exploited — with high severity, confidence A, no recorded real harm and confirmed AI involvement. The parties disagree about the framing even though they agree on the behaviour: AWS told Dark Reading the research "inaccurately paints expected and documented behavior as a vulnerability."

What the chain actually was

AgentCore packages each agent as a container and runs it in a per-session Firecracker MicroVM. Zenity's first post in the series reproduces the whole foothold with a plain-language request to a test agent built with Strands SDK, AWS's open-source agent framework, which ships a built-in HTTP request tool and a shell tool. The microVM did not restrict traffic to the metadata service, so the request came from inside the instance and IMDS answered it. The researchers walked the endpoints after that: the IAM role name, the temporary STS credentials themselves, the user-data endpoint — which returned the account ID, full ARNs, the runtime URL and the agent's Amazon Elastic Container Registry (ECR) image URI — and instance tags including an mTLS certificate chain, a private key and a presigned URL to internal storage. Zenity says the same result came through the shell tool, because the isolation failure sits at the platform level rather than in any one tool.

Two details in that sequence are easy to read past. The credentials were not confined to the sandbox: Zenity exported them outside AgentCore and ran an AWS identity call that came back as the agent's assumed role. And the stolen role could pull the container image, which is how agents' source code became readable — Zenity's post notes that images routinely carry hardcoded keys, leftover tokens and configuration that should never have been baked in, and that a pulled image is a map of the underlying business logic.

The default role is where a foothold became an account

The second flaw, reported separately, is that the execution role AgentCore attached to agents by default was not scoped to one agent. Zenity describes permissions reaching across every AgentCore resource in the account and region, including bedrock-agentcore:InvokeAgentRuntime, bedrock-agentcore:ListEvents, bedrock-agentcore:CreateEvent, bedrock-agentcore:DeleteEvent and, at the credential end of the chain, bedrock-agentcore:GetResourceApiKey and secretsmanager:GetSecretValue.

HTML card titled 'One prompt, one role, four capabilities', kicked 'AgentCorruption · the path Zenity Labs describes' and subtitled 'The studied attack path, with the AWS permission Zenity names at each step. No CVE was assigned; AWS disputes the vulnerability framing.' Four stacked bands run down the card. Step 1, 'Foothold through a chat message': a public-facing agent holding any tool that can make an outbound request is asked, in plain language, to fetch 169.254.169.254; the Firecracker MicroVM did not restrict traffic to the metadata service, so the request came from inside the instance and IMDS returned the agent's own execution-role credentials as a temporary STS key pair and session token. Step 2, 'Every agent in the account and region': permissions logs:DescribeLogGroups and region-wide ECR read; agent IDs were derived from CloudWatch log groups named /aws/bedrock-agentcore/runtimes/AGENT_ID-ENDPOINT_NAME, and ECR repository names followed the convention bedrock-agentcore-AGENT_NAME, so every agent's container image and source code could be pulled. Step 3, 'Conversations, sessions and persistence': permissions InvokeAgentRuntime, ListEvents, ListActors, ListSessions, CreateEvent, DeleteEvent and GetMemory; read private conversations across users and sessions, invoke internal agents, inject an assistant-role event into a live session, and plant a memory that sends the agent to an attacker-controlled page before each answer. Step 4, 'Credentials outside AWS': permissions secretsmanager:GetSecretValue and bedrock-agentcore:GetResourceApiKey; provider names recovered from scraped agent source code or by enumerating 2 x (10+26)^5 = 120,932,352 likely default names, reaching API keys and OAuth secrets for third-party services. A footer reads 'Steps and permissions as described by Zenity Labs on 8 October 2026. AWS states the behaviour described is documented and expected, and disputes the vulnerability framing. Card rendered by OrcaRouter.'

Enumerability turned those wildcards into a target list. Zenity used the role's logs:DescribeLogGroups permission, because AgentCore names each agent's CloudWatch log group /aws/bedrock-agentcore/runtimes/{AGENT_ID}-{ENDPOINT_NAME}, and derived agent IDs from those log group names. ECR repository names followed a convention the researchers observed — bedrock-agentcore-<agent_name> — so every agent's image in the region could be pulled. Memory resources were found the same way, from the log group pattern /aws/vendedlogs/bedrock-agentcore/memory/APPLICATION_LOGS/{MEMORY_ID}, and the role's ListActors, ListSessions and ListEvents permissions produced the actor and session identifiers needed to read conversation content.

Zenity's write-up gives a concrete lateral-movement demonstration: entering through a public-facing agent, discovering the tools of a billing_agent in the same region, spotting a file named billing.json and exfiltrating it through a file-read tool. The press release states the same scenario in general terms — an attacker entering through an internet-facing customer service agent could move to an internal finance agent deployed in the same region, invoke it, and reach its data, tools, related credentials and private conversations.

Memory was the part that outlived the prompt

AgentCore Memory keeps the conversation itself as short-term memory and stores extracted records as long-term memory, using strategies named SEMANTIC, USER_PREFERENCE, SUMMARIZATION and EPISODIC. Zenity used CreateEvent to write conversation events into other agents' memory resources. Its post is careful about what that primitive can and cannot do: CreateEvent does not let the caller choose a long-term namespace or overwrite a record directly — the target memory's configured strategies decide what gets extracted and where it lands. Zenity also describes DeleteEvent being used to remove tool-result events so an agent draws a wrong conclusion from missing data, and to cover tracks by deleting the event that planted a memory.

What the write primitive produced was persistence. Zenity's demonstration planted a request that the agent fetch a page the researchers controlled before answering, and follow that page's contents — a command-and-control endpoint whose instructions could be changed without planting another memory. The same channel then carried conversation content out: the write-up describes the agent sending the user's messages and its own replies to a collection endpoint, and states that the memory permissions on the role extended across the account and region rather than only to the compromised agent. A video published with the research shows a user continuing a conversation while that content arrives at the researchers' server.

Credentials beyond AWS

The last post in the series closes the loop on connected tools. AgentCore Identity and Outbound Auth store tool credentials as secrets in AWS Secrets Manager, under names built from a provider name and a fixed pattern such as bedrock-agentcore-identity!default/apikey/{provider_name}. Zenity recovered provider names by scraping the agent source code it had already pulled from ECR, and recovered others by brute force: it reports that the default five-character suffix is generated client-side from digits and lowercase letters, giving 2 x (10+26)^5 = 120,932,352 combinations across the two provider types. At the request rate it could sustain against Secrets Manager, Zenity says a full enumeration takes several hours — longer than the STS credentials last — so it built a loop that re-queried the agent's IMDS endpoint for fresh credentials as the old ones expired. Zenity adds that environment variables were readable through the metadata user-data endpoint with every name prefixed CONTAINER_ENV_, including the key an agent uses to authenticate to its model provider, and that invoking each discovered agent with a suitable prompt harvested those values at scale.

Established, and disputed on a technicality

What is established is narrow and specific. AgentCore agents could reach IMDS and receive their own execution role's temporary credentials — AWS does not dispute this, describing it in its statement as "documented and expected." The default execution role carried permissions scoped to the account and region rather than to one agent; AWS has since changed it, and Zenity says its own testing confirmed the reduction. The research is a demonstration, not an observed campaign: Sharbat told Dark Reading that Zenity had seen no evidence the flaw was exploited in the wild before the fix, attributing that in part to the difficulty of identifying which organisations run agents on AgentCore, and adding that he was "100% sure there are ways to do it."

What is disputed is whether any of it should be called a vulnerability. AWS's statement, as given to Dark Reading and The Next Web, reads: "AWS is aware of the research published about Amazon Bedrock AgentCore, which inaccurately paints expected and documented behavior as a vulnerability. An agent can access resources in another AWS account only if the developer explicitly grants permissions on both the agent's execution role and the target resource." The AWS statement reproduced in Zenity's own posts keeps the substance of the first sentence — "the behavior described is documented and expected" — and adds that customers should grant execution roles only the permissions their agents need. Two things sit under the disagreement. AWS frames the boundary in terms of access to resources in another AWS account, while Zenity's finding concerns agents inside a single AWS account and region; and the roles Zenity describes came from the platform's defaults rather than from a customer writing a policy by hand.

The Next Web's correction to its own story is worth recording, because it shows the claim being tightened by someone other than the researchers. It first reported, and later corrected, a headline saying the researchers took over every AgentCore agent in a region; the corrected version states that the research covered agents within a single AWS account and region, and notes that the earlier headline had stated the researchers' claim as fact.

The disclosure timeline

HTML card titled 'How the disclosure ran, and what AWS changed', subtitled 'Two reports, filed on different dates and answered separately. Dates as published by Zenity Labs and as reported by Dark Reading and The Next Web.' Eight rows run down a vertical timeline. 25 December 2025: Zenity Labs reports the IMDS access issue to AWS, report number one. 12 January 2026: Zenity Labs files a second report covering the over-privileged default execution role and the resulting blast radius. 14 February 2026: per AWS, as reported by Zenity, newly deployed AgentCore agents launch with IMDSv2 only, which requires a session token on each request. 25 February 2026: AWS tells Zenity the team is working on the underlying role issue, and the default execution role stays the same. 12 April 2026: AWS closes report number one as 'informative', noting the February IMDSv2 change. 22 June 2026: Zenity reviews the default execution role again and confirms its permissions are unchanged. 29 September 2026: the final pre-publication review finds substantial changes, with permissions to invoke other agents, read private conversations and access Secrets Manager removed and other permissions significantly restricted. 8 October 2026: research, press release and SecTor 2026 talk in Toronto; AWS gives its statement to press the same day; no CVE was assigned. A footer reads 'Timeline per Zenity Labs' disclosure notes, with AWS's IMDSv2 date as reported by Zenity and Dark Reading. Card rendered by OrcaRouter.'

Zenity filed two reports rather than one, and they were answered differently. The IMDS access report went in on 25 December 2025; AWS closed it on 12 April 2026 as "informative," writing that AgentCore had used IMDSv2 only since 14 February 2026, with newly deployed agents launching that way. That revision matters for the specifics of this research, because IMDSv2 requires a session token on each request and breaks the plain unauthenticated fetch the researchers used to obtain credentials. The second report, on the default role and its blast radius, went in on 12 January 2026. AWS told Zenity on 25 February 2026 that the team was working on it while the role stayed as it was; Zenity reviewed the role again on 22 June 2026 and found its permissions unchanged. A final review on 29 September 2026 found the role substantially narrowed, and Zenity's press release states the removal covered invoking other agents, reading private conversations and accessing secrets in AWS Secrets Manager, with other permissions significantly restricted as well. Zenity's own posts note that AWS has since made IMDSv2 the default for AgentCore deployments and that the two sides collaborated through the process.

What is not known

Zenity has not published how many agents or organisations ran with the default role in the period between the February IMDSv2 change and the late-September narrowing, and nothing in the cited sources states that any customer data was exposed outside the researchers' own environment. The IMDSv2 change applies to agents deployed after 14 February 2026, per AWS as reported by Zenity; what it means for agents deployed before that date is not stated in the sources reviewed here. The archive records no real harm, and the sources support that reading by describing a demonstration and by AWS disputing the vulnerability label rather than reporting an incident of its own.

Sharbat told Dark Reading that Zenity is now examining other cloud platforms for similar metadata-access issues, and that the company is not yet naming them. His stated takeaway is about permissions rather than about the metadata service alone: "Even if someone gets to the IMDS, the blast radius will be a lot smaller."

Why this record is kept

Abstract illustration on a dark navy field of two conversational panels facing each other across a narrow gap, drawn as pale rounded rectangles holding only short unreadable dashes; through the gap between them a thin amber line passes downward into a small stack of server panels and then out again toward a single distant node at the edge of the frame. The panels are connected to nothing else. No text, people, code or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

AgentCorruption is not notable because metadata endpoints are a new idea. Sharbat pointed the SecTor audience at the 2019 Capital One breach, where an SSRF reached IMDS and became stolen credentials, and described that as a least-privilege failure of the same kind. What is new is the actor doing the fetching. The request that produced an AWS identity was made by an AI agent doing what it was asked, in plain language, through a tool it was given so that it could be useful — and the agent relayed the answer back. The two conditions that turned that into an account-wide problem were a metadata endpoint the sandbox did not block and a default role wider than the agent that held it.

The full research, including the five-part technical series and the demonstration video, is linked from Zenity's press release of 8 October 2026. This record is one entry among the documented agent incidents in the AI incident archive, where each entry carries its own sources, severity, confidence grade and disputed flag — the fields that make it possible to tell a vendor dispute about framing, as here, from a contested finding of harm.

This is one record, researched and reported by others and cited here to them. The other documented agent incidents, each with its own sources, severity, confidence grade and disputed flag, sit in the AI incident archive — so a platform default that turns one prompt into an account-wide foothold can be read next to what has actually happened elsewhere.