← All posts Attack paths

Attack path analysis vs attack path validation in AWS

Key takeaways

  • Attack path analysis links individual findings into the sequence of steps an attacker could take from an entry point to a target. It answers the question of what could be chained.
  • Attack path validation checks each candidate chain against the authorization AWS would evaluate: identity policies, resource policies, trust policies, service control policies, permission boundaries, and condition keys. It answers which of those chains work.
  • In AWS the two answers differ a lot. A chain that looks complete on a graph can still be blocked by an SCP, a boundary, or a condition key, and only resolving all of them together tells you which chains survive.
  • Validation in the control plane does not require running an exploit. Resolving the real authorization read-only gives the same answer with none of the risk.
  • Prioritization depends on validation. In the Pathbreak lab account, 4,942 candidate paths reduced to a ranked list where two changes removed 80 percent of the risk.

Attack path analysis finds the chains of permissions, trust relationships and exposures that an attacker could use to move from an entry point to a target in AWS. Attack path validation checks each of those chains against the authorization AWS evaluates for every call, and keeps the ones that work.

Instead of a list of 3,000 isolated issues, analysis produces chains: this public instance holds this role, this role can pass that role to Lambda, that role is an administrator. Most cloud security platforms now offer some form of it, and it is a large improvement on severity-sorted lists.

Validation is the step after analysis. In AWS it is a harder question than it looks, because several kinds of policy take part in every decision, and the two answers diverge more than most teams expect.

What attack path analysis does

CreateFunction iam:PassRole runs as role 01 Attacker principal 02 New Lambda 03 Passed role 04 Administrator
The chain in this post. With iam:PassRole and lambda:CreateFunction held together, a principal creates a function, hands it a privileged role, and the function runs as that role. This post takes it from a candidate on the graph to a proven path.

Analysis starts from an inventory: principals, roles, policies, trust relationships, compute, storage, and the network edges between them. It builds a graph, then searches the graph for routes that end at something sensitive, an administrator role, a production database, a bucket of customer data. Each hop is a known technique. iam:PassRole with lambda:CreateFunction is a hop. sts:AssumeRole into a trusting account is a hop. A public function URL is an entry point.

The output is a set of candidate paths. They are candidates because the graph was built from policy documents as written, and an identity policy on its own does not tell you what AWS will decide when the call is made.

Where analysis stops

AWS evaluates every API call against several documents at once, and any one of them can turn an allow into a deny. A path that exists on the graph can be blocked by any of these:

  • Service control policies. An SCP on the organizational unit can deny lambda:CreateFunction for the whole OU, and no identity policy inside it can override that.
  • Permission boundaries. A boundary on the source principal caps what its identity policies can grant. If the boundary omits iam:PassRole, the pass fails even though the identity policy allows it.
  • Trust policies. The target role must trust the service or principal that the hop relies on. A role that does not trust lambda.amazonaws.com cannot be passed to Lambda, whatever the caller holds.
  • Resource policies. The bucket, the key, the queue, or the function at the end of the path has its own policy, and it can deny the principal that the chain arrived as.
  • Condition keys. iam:PassedToService, aws:SourceAccount, aws:PrincipalOrgID, and the sts:ExternalId check all narrow a grant that looks broad in the action list.
  • Explicit denies. A deny statement anywhere in the evaluation wins over every allow, and it is often in a different policy from the one the graph read.

Reading any one of these documents is easy. The work is resolving all of them together, in the order AWS does, for every step of every chain, and that step is what separates a candidate path from a proven one. Skip it and the list is long, and a large share of it would fail on the first call.

How to validate a cloud attack path in AWS

Take a common chain. A CI role called ci-deploy holds iam:PassRole on a role called data-pipeline, plus lambda:CreateFunction and lambda:InvokeFunction. The data-pipeline role has AdministratorAccess. On the graph that is a two-hop path from the CI role to administrator: create a function with data-pipeline attached, invoke it, and the function's code runs as an administrator.

Analysis marks the path reachable. Validation then walks it one check at a time:

  1. Does the identity policy on ci-deploy allow iam:PassRole on the ARN of data-pipeline, or on a wildcard that covers it? Yes, on arn:aws:iam::*:role/data-*.
  2. Is the pass narrowed by iam:PassedToService? No condition is present, so any service is accepted.
  3. Does the trust policy of data-pipeline trust lambda.amazonaws.com? Yes, it was created for a Lambda-based pipeline.
  4. Does an SCP on the account's OU deny lambda:CreateFunction or iam:PassRole? The OU has an SCP, and it denies neither.
  5. Does a permission boundary on ci-deploy exclude either action? The role has no boundary.
  6. Does the function's execution reach anything that matters? data-pipeline is an administrator, so the answer is everything in the account, and through two cross-account trusts, two more accounts.

Every check passed, so the path is proven. No function was created and nothing was invoked. Each step resolved the same documents that AWS would, in the same order, and returned the same decision. That is what validation means in the control plane. The exploit is a permission, so the proof is the authorization result.

The fix follows from step two. The narrowest change is to add iam:PassedToService to the pass grant so that only the intended service can receive the role, or to replace the wildcard ARN with the single role CI needs. After the change, the same six checks run again and step two fails. The path is gone, and the confirmation is recorded next to the finding. The map entry for this chain has the CloudTrail events and the full write-up.

Is attack path validation safe to run in production?

Yes, when the validation is read-only. Pathbreak connects through a least-privilege, read-only IAM role that you create and can revoke at any time. Every call it makes is a read (Get, List and Describe), and the authorization for each step is resolved from the policy documents those calls return. No function is created, no role in the path is assumed and no resource is changed, so production workloads keep running as they were.

The role session and its reads appear in CloudTrail as management events under the Pathbreak role, which keeps the activity easy to audit. Pathbreak reads configuration, including the places where credentials are commonly exposed, such as instance user data, function environment variables and stack outputs. It does not read the contents of object storage or databases.

Read-only validation answers one question for each step: would AWS authorize this call for this principal? It does not test application code, exploits against running hosts, or whether detection and response would catch an attacker. A manual AWS security assessment covers those, and Pathbreak runs alongside one. Some tools validate by running attack steps in the environment, and this comparison covers when each approach fits.

Why the difference decides what you fix first

Ranking paths by impact only works if the paths are real. A list that mixes proven chains with chains that an SCP already blocks will push teams toward work that changes nothing. In the Pathbreak lab account, analysis produced 4,942 candidate paths. After validation and ranking by blast radius, a single Deny on one role removed 3,893 of the 4,087 remaining paths, and two changes together removed 80 percent of the risk in the account. That ordering is only visible once each path has been resolved against the real authorization.

How Pathbreak does it

Pathbreak builds the graph, reasons over it to produce candidate chains, then validates each chain end to end by resolving the authorization AWS would evaluate: identity and resource policies, trust policies, SCPs, boundaries, and conditions. Access is read-only and nothing is executed. Each validated path is ranked by what it reaches, and comes with the specific change that breaks it. After the change ships, the path is re-evaluated and the result is recorded, so the fix is confirmed with evidence.

Pathbreak attack path view: a staging role reads a CloudFormation stack whose template exposes a credential for an admin user, with the risk rating and the evidence for the selected edge
A validated path in Pathbreak. The PathbreakLabStaging role can read a CloudFormation stack whose template embeds a long-lived key for an admin user. The selected edge shows the technique, the evidence (an observed credential), and why the path is rated as it is.

Frequently asked questions

What is attack path analysis?

Attack path analysis connects individual security findings into the sequence of steps an attacker could take from an entry point to a target, usually by building a graph of identities, permissions, and resources and searching it for routes to sensitive assets. Pathbreak builds this graph for AWS and then validates each path it finds.

What is attack path validation?

Attack path validation checks each candidate path against the authorization the cloud provider would evaluate for every step. In AWS that means resolving identity policies, resource policies, trust policies, service control policies, permission boundaries, and condition keys together, and confirming the path works. Pathbreak validates AWS attack paths this way, read-only, and records the result for every hop.

Does validation mean running exploits in my AWS account?

No. In the AWS control plane the attacker's moves are API calls, and each call is allowed or denied by policy documents. Resolving those documents read-only gives the same decision AWS would, so a path can be proven without creating, invoking, or changing anything. This is how Pathbreak validates attack paths in AWS.

Can a CSPM do attack path validation?

CSPM and CNAPP tools offer attack path analysis on a graph of your configuration. Validation as described here means evaluating every layer of AWS authorization for each step and confirming the fix afterwards. Pathbreak does that and can run alongside a CSPM or replace a standalone scanner.

How do you validate cloud attack paths in AWS?

Build a graph of principals, roles, trust relationships and resources, and generate candidate chains from it. For each step in a chain, resolve the identity policy, resource policy, trust policy, service control policy, permission boundary and condition keys together, in the order AWS evaluates them, and keep only the chains where every step is allowed. After a fix ships, run the same checks again to confirm the path is gone. Pathbreak automates these steps for AWS.

What shows up in CloudTrail when Pathbreak validates attack paths?

The sts:AssumeRole call that starts each session on the read-only IAM role you created, followed by read calls. Pathbreak's Get, List and Describe calls appear in CloudTrail as management events under that role. Nothing in the path is created, invoked or changed, so the validation leaves no write events.

What does read-only attack path validation not cover?

It answers whether AWS would authorize each step of a path. It does not test application code, exploits against running hosts, or whether detection and response would catch an attacker. A manual AWS security assessment covers those, and Pathbreak runs alongside one.

Related posts

See which attack paths in your AWS accounts are proven, and the change that breaks each one.

Request a demo Watch the demo