Back to all articles
    AgentCorruption: How One AWS Agent Reached Its Neighbors
    AI SecurityAWSAgentCoreIAMPrompt Injection

    AgentCorruption: How One AWS Agent Reached Its Neighbors

    Y

    Yoni Fraimorice

    Share:

    One prompt did not magically jump between isolated AI agents. It did something more familiar: it stole a cloud identity with too much access.

    That is the core of AgentCorruption, research published by Zenity Labs on October 8 about Amazon Bedrock AgentCore.

    Zenity says a public-facing test agent followed a plain-language request to contact its local metadata service. The service returned temporary AWS credentials for the agent's execution role. The researchers then used those credentials outside AgentCore.

    According to Zenity, the default role had broad permissions across AgentCore resources in the same AWS account and region. That let the team discover other agents, pull container images, invoke internal agents, read conversations, modify memory, and reach secrets.

    These are Zenity's reported results. I did not independently reproduce the attack. AWS disputes the vulnerability framing: it told The Next Web that the behavior is documented, that access depends on permissions granted by the developer, and that customers should apply least privilege.

    The chain started with a useful tool

    The public agent in Zenity's demonstration used the AWS Strands framework and had a tool that could make HTTP requests. Zenity says it reproduced the result with a shell tool too.

    AgentCore runs sessions in isolated Firecracker microVMs. Inside those VMs, its MicroVM Metadata Service, or MMDS, provides temporary execution-role credentials. AWS describes MMDS as similar to the EC2 Instance Metadata Service, commonly called IMDS.

    AWS's credentials documentation now states the boundary clearly: any code or actor running inside the VM can call the metadata endpoint and access those credentials.

    That matters for agents. A public user does not need direct network access to the VM if the agent has a flexible web or command tool and can be persuaded to use it.

    Zenity reports that its agent contacted the link-local metadata address, collected temporary STS credentials, and sent them to a controlled destination. The team verified the credentials from its own machine with AWS APIs.

    At that point, prompt injection was no longer the main issue. The question became: what can this IAM role do?

    Broad role permissions created the lateral path

    MicroVM isolation kept one VM from directly reading another VM's memory or disk. But the stolen role could call AWS control-plane and data-plane APIs.

    Zenity's role analysis says the then-default execution role used wildcards across resources in the account and region.

    The team reports using CloudWatch log-group discovery to find agent and memory identifiers. ECR permissions allowed it to pull other agents' container images. AgentCore permissions allowed it to invoke other runtimes and list conversation events. Memory write permissions allowed it to plant events that could influence later sessions. A Secrets Manager permission reportedly covered outbound credentials for multiple providers.

    The dangerous design was not only "an agent can read its own role." It was:

    text
    untrusted prompt
      → flexible network or shell tool
      → execution-role credentials
      → wildcard access to neighboring agents and shared services

    If the execution role had been limited to one runtime, one model, one log group, and the exact data needed for that agent's job, the first compromise would still matter. But the blast radius would be much smaller.

    AWS says this is documented behavior

    AWS told The Next Web that Zenity's research "inaccurately paints expected and documented behavior as a vulnerability." AWS stressed that access to another AWS account requires explicit permissions on both the execution role and target resource.

    Zenity's published chain concerned agents in the same account and region, not an automatic escape into unrelated AWS accounts.

    The current AWS documentation also warns developers that code in the microVM can obtain execution-role credentials. Its security guide says CLI-generated IAM policies are for development and testing, not production, and recommends custom policies with exact resource ARNs.

    The platform changed during disclosure. Zenity says newly deployed agents used IMDSv2-only access from February 14, 2026. It also says that by September 29, AWS had removed several broad permissions from the default role, including permissions used to invoke other agents, read conversations, and access Secrets Manager.

    AWS's current AgentCore security guide says runtimes must enable MMDSv2 and documents requireMMDSV2: true.

    So AgentCorruption should not be read as proof that every new AgentCore deployment still has the original default role. It is evidence of what happens when agent tools, metadata credentials, and broad IAM permissions meet.

    Least privilege: isolate each agent's cloud identity

    Start with one execution role per agent or per tightly related trust boundary. A public support agent and an internal finance agent should never share a role simply because deployment tooling makes that easy.

    For each role:

    • Allow only the AWS actions the agent must perform.
    • Scope Resource to the exact runtime, model, bucket, secret, repository, memory, and log group.
    • Remove cross-agent actions such as runtime invocation or memory access unless they are a defined product requirement.
    • Avoid production policies generated for quick starts or CLI demos.
    • Keep the role's power equal to or lower than the power of users allowed to invoke the agent.
    • Add aws:SourceAccount and a narrow aws:SourceArn to the trust policy.
    • Use IAM Access Analyzer and test denied paths, not only successful ones.

    For third-party services, prefer AgentCore Identity with user-delegated credentials where possible. Do not place long-lived API keys in source code, container layers, or environment variables available to arbitrary agent code.

    Harden metadata access and the tools around it

    First, inventory every runtime and verify MMDSv2 is required. For AgentCore, update older runtimes with metadataConfiguration.requireMMDSV2 set to true, then redeploy where needed.

    IMDSv2 requires a session token, which blocks simple one-request SSRF patterns. It does not make an overprivileged role safe. An agent with arbitrary shell access or a sufficiently flexible HTTP tool may still be able to perform the token flow.

    Add a second boundary in the tool:

    • Reject link-local, loopback, private, and otherwise forbidden destinations before connecting.
    • Recheck the resolved IP after DNS lookup and on every redirect.
    • Use destination allowlists for public agents instead of general web access.
    • Put shell and code-execution tools in separate, non-public runtimes with narrower roles.
    • Alert on requests to metadata paths and unexpected STS, ECR, AgentCore Memory, or Secrets Manager calls.

    If metadata credentials may have been exposed, update the runtime, replace the role policy, rotate connected secrets, inspect CloudTrail and AgentCore logs, and review memory for unauthorized events.

    The sandbox is only one boundary

    AgentCorruption is a cloud lesson with an AI entry point.

    Prompt injection gave Zenity's test agent a bad instruction. Metadata supplied the identity. IAM permissions decided how far that identity could travel.

    The smallest reliable fix is not a smarter system prompt. It is a role that becomes boring when stolen.

    Sources

    Hero photo: Server Rack with Spaghetti-Like Mass of Network Cables, photographed by Kim Scarborough on January 25, 2006. CC BY-SA 2.0. Resized from 2560 x 1920 to 1920 x 1440 pixels and JPEG-compressed; no other edits. This illustrative photograph represents connected infrastructure and does not show AWS, AgentCore, Zenity, or the reported research environment. No endorsement is implied.

    Share: