Skip to content

Build1 publisher2 min readPublished

DevOps Agent declined ec2:RunInstances after a tester granted it to the elevated role

A tester gave AWS DevOps Agent a broad elevated role and found its temporary session policy admits only supported actions, while an SSM document that accepts arbitrary package names still installed tmux after one approval.

The Engineer · Build desk

Illustration accompanying DevOps Agent declined ec2:RunInstances after a tester granted it to the elevated role

What happened

  • A write-up in the AWS Builders community gave an AWS DevOps Agent elevated role relatively broad permissions, then asked for arbitrary commands, unauthorised EC2 operations and combinations of the two.
  • The tests assume an attacker can already operate the agent and approve its proposals, so the approval prompt is not treated as a guardrail.
  • The agent warned that the target SSM document had no package allowlist, then installed tmux once the operator explicitly approved the operation.
  • Adding ec2:RunInstances and rds:StartExportTask to the elevated role did not make either operation invokable through the agent.
  • A request to run uname -a through AWS-RunShellScript was rejected with no approval prompt and no SendCommand call.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure An operator who approves by habit sits in the same threat class as the attacker in this model; the author points at mistaken approvals and social engineering as routes to the same install.
  • constraint Widening the elevated role buys no extra agent capability while the supported action set is the ceiling, so IAM breadth is not where this risk concentrates.
  • decision The parameter shape of your SSM documents is the control you actually own: allowlist the package names, or treat patching and arbitrary installation as the same call.
  • precedent Should AWS add actions to the supported set, the ceiling moves without anyone editing a role or a boundary, and the author says he intends to keep watching for that.

How the agent builds its credentials explains the two grants that never fired. AWS DevOps Agent creates a temporary session policy for a directed action, and the documentation the author cites says that policy includes only actions from the agent's supported set [5]. The elevated role can name whatever you like, but in these tests the supported set was the ceiling [5].

The refusal of AWS-RunShellScript sits on a different layer. The document the agent rejected declares a StringList parameter named `commands` and hands `{{ commands }}` straight to `aws:runShellScript` [7]. The author writes that the decision appeared to depend on the document accepting arbitrary commands, not on whether the particular command was safe, and that repeating the prompt in new sessions produced the same result [8].

One elevated role in the test had no permissions boundary attached, and it was the one used against the instance whose SSM document accepted arbitrary package names [9]. The rest of the rig was built to deny: a boundary matched to the intended permissions of the elevated role, an SSM document with a package allowlist, an instance restricted to a single designated document, plus CloudTrail, CloudWatch Logs and SSM Run Command logs [11]. Of the three escalation attempts described, one succeeded, and the two that failed were stopped by the agent's own restrictions and not by an IAM denial [15].

Whether IAM and permissions boundaries can still stop an operation after the agent has accepted it is the other half of the test plan, along with what evidence remains in CloudTrail [13]. The author calls that part "extremely important" and says it "may be the most important point I want to share in this article" [12]. The available text ends mid-sentence, as he begins describing inconsistent behaviour, before those results appear [16]. So the idea that CloudTrail is the only durable record of what the agent did on your behalf is not yet demonstrated here.

Two things have to be true of your account for the rest to transfer: the supported action set bounds your elevated role the way it bounded his, and your SSM documents constrain package names. Where a document takes arbitrary package names, the agent's warning about the missing allowlist is advisory, and the operator's approval clears it. The author wrote that "even well-designed security controls can have gaps" [19].

What to watch

  • Whether AWS expands DevOps Agent's supported action set, and what lands in it.
  • Publication of the CloudTrail portion of these tests, including what a directed action records.
  • Whether the refusal of documents that accept arbitrary commands holds outside this author's sessions, given the inconsistent behaviour he begins to describe.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories