cloudpentest

Cloud identity attack paths: privilege escalation on AWS, Azure and Google Cloud

Updated 12 min read

Ask what a cloud attacker exploits and the honest answer is usually nothing. They authenticate, they assume, they impersonate and they pass roles, using permissions that were granted deliberately by people who were solving a real problem. This guide walks the documented escalation primitives on each provider, quoting the providers’ own warnings, and sets out the controls that cut the chains.

Why the graph beats the list

A permissions audit produces a list: this principal has these policies. An identity attack path is a different object. It is a sequence of transitions, each of which is allowed, whose endpoint is something the starting principal was never intended to reach. The list contains no findings. The graph contains all of them.

The transitions come in a small number of shapes, and they repeat across providers. A principal can assume a role. A principal can hand a role to a service that will then act with it. A principal can obtain a token as another identity. A principal can create a compute resource that runs as an identity. A principal can read a secret that authenticates as somebody else. Each provider implements these differently and each documents the risk in its own words, which is what makes the primitives easy to cite in a report.

MITRE ATT&CK covers the same ground behaviourally. Its Cloud matrix spans IaaS, SaaS, Identity Provider and Office Suite platforms, and the identity techniques are the ones that matter here: valid accounts, additional cloud credentials and additional cloud roles are the mechanics by which a foothold becomes durable, privileged access.

AWS: passing a role you should not be able to use

To configure many AWS services you must pass an IAM role to the service, so that the service can assume it later and act on your behalf. AWS controls this with a dedicated permission, and states the point of it directly: to pass a role and its permissions to an AWS service, a user must have permissions to pass the role to the service, which helps administrators ensure that only approved users can configure a service with a role that grants permissions.

The escalation follows from what happens when that permission is granted without a resource restriction. AWS spells out the warning itself: when setting the PassRole permission, you should make sure that a user does not pass a role where the role has more permissions than you want the user to have. Its own example is a user who cannot perform any Amazon S3 actions but who can pass a role to a service that allows them, at which point the service performs those actions on the user’s behalf.

Two details make this worse in practice than it looks on paper. The first is that iam:PassRole is frequently granted with "Resource": "*", because scoping it requires knowing which roles a pipeline will need before the pipeline exists. The second is an auditing gap AWS documents plainly: PassRole is not an API call, it is a permission, so no CloudTrail logs are generated for IAM PassRole. To see which roles were passed to which services, you have to review the CloudTrail record of the action that created or modified the resource receiving the role, such as the CreateFunction entry for a Lambda function.

AWS: the confused deputy and the external ID

The second AWS primitive is about trust rather than delegation. AWS defines the confused deputy problem as a security issue where an entity that does not have permission to perform an action can coerce a more-privileged entity to perform the action, and it arises in two places: when you give a third party cross-account access, and when one AWS service acts on a resource in another service.

The cross-account version is the one every organisation has. You hire a vendor, you create a role whose trust policy names the vendor’s account, and you hand them the role ARN. The vendor now assumes that role to serve you. But the vendor serves other customers too, and your role ARN is not a secret. If another of the vendor’s customers supplies your role ARN as though it were their own, the vendor will assume it and act inside your account. The vendor is the confused deputy.

The control is the external ID: an optional identifier used in an IAM role trust policy to designate who can assume the role, whose primary function, in AWS’s words, is to address and prevent the confused deputy problem. The requirement that makes it work is easy to get wrong. The external ID value must be unique among the third party’s customers and controlled by the third party, not by its customers, which is why you receive it from the vendor rather than inventing one. With an sts:ExternalId condition in the trust policy, an AssumeRole call that does not carry your value fails, and the other customer cannot supply your value because they never see it.

The cross-service version needs a different control. When an AWS service principal accesses a resource in another service, the resource policy authorises the service principal and not the actor who configured it. AWS recommends using aws:SourceArn, aws:SourceAccount, aws:SourceOrgID or aws:SourceOrgPaths in a resource policy wherever a service principal is granted access, so the policy can test that the service is acting on behalf of a resource, account or organisation you expect. Its worked example is a central S3 bucket that trusts cloudtrail.amazonaws.com with no conditions, and therefore accepts CloudTrail logs from any account whose owner knows the bucket name.

This matters directly to the engagement itself. A tester assuming a read-only audit role in a client account is a third party in exactly the sense AWS describes, so the audit role should carry an external ID condition. It is a small detail that says a lot about whether the assessor understands the model they are testing.

AWS: instance metadata as a credential endpoint

Every EC2 instance can reach the Instance Metadata Service at 169.254.169.254, and where an instance profile is attached, the metadata service will hand out credentials for its role. That makes any server-side request forgery, open reverse proxy or over-permissive firewall on the instance a credential disclosure rather than an information leak.

AWS addressed this with IMDSv2, which it describes as a session-oriented method against IMDSv1’s request and response method. A PUT initiates a session and returns a token, which must be included in every subsequent GET; where token usage is required, requests without a valid or unexpired token receive a 401. Three properties do the defensive work. The token is an instance-specific key that is not valid on other EC2 instances. PUT requests are rejected if they contain an X-Forwarded-For header, which defeats the naive proxy case. And the response to a PUT has a default hop limit of 1 at the IP protocol level, so the token does not travel beyond the instance itself.

The catch is the default. AWS states that by default you can use either IMDSv1 or IMDSv2, or both, and that an instance must be configured to only accept IMDSv2 calls for IMDSv1 calls to fail. An estate that has enabled IMDSv2 without requiring it has not closed the path. Two checks belong in every AWS assessment: whether token usage is set to required on every instance, and whether the hop limit has been raised above 1, which is sometimes done for container compatibility and which puts the metadata endpoint back within reach of a container network.

Google Cloud: impersonation is the whole story

Google names the primitive directly. When an authenticated principal, such as a user or another service account, authenticates as a service account to gain the service account’s permissions, it is called impersonating the service account. Two roles enable it: Service Account Token Creator, roles/iam.serviceAccountTokenCreator, which allows minting access tokens as the service account, and Service Account User, roles/iam.serviceAccountUser, which allows attaching or otherwise using it.

Google’s own warning is the sentence to quote in a finding: when granting a role that allows a user to impersonate a service account, keep in mind that the user can access all the resources that the service account can access. It follows this with a specific caution against letting users impersonate highly privileged service accounts, naming the Compute Engine and App Engine default service accounts, which are frequently over-privileged because they were created that way and never trimmed.

Because impersonation grants are set per service account rather than centrally, the reachability question is not answerable by reading one policy. It requires walking every service account’s IAM policy and resolving who holds Token Creator or Service Account User on it, then repeating for the service accounts those principals can then act as. That is a graph traversal, and it is where the finding lives.

Service account keys are the related exposure. Google describes them as a security risk if not managed correctly, and its guidance is to choose a more secure alternative to service account keys whenever possible. A downloaded key is a long-lived credential that leaves the platform: once it is in a build system, a laptop or a vendor’s configuration store, it is outside the identity controls that everything else on the project relies on.

Microsoft Entra: standing privilege as the finding

Azure resource access is governed by Azure RBAC, but the identity that matters sits above it in Microsoft Entra ID, which supports over 65 built-in roles. The escalation questions here are less about individual permissions and more about how much privilege is standing at rest.

Microsoft publishes thresholds, which makes this unusually easy to assess against a stated position. It recommends assigning the Global Administrator role to fewer than five people in an organisation, and limiting privileged role assignments to fewer than ten, with a warning displayed in the portal above that number. It recommends two cloud-only emergency access accounts permanently assigned Global Administrator for break-glass use, not assigned to specific individuals. And it recommends that everything else be granted just in time through Privileged Identity Management, where a user is made eligible for a role and activates it for a limited period, with privileged access automatically removed when the timeframe expires.

Two further items belong on the checklist. Microsoft advises against using on-premises synced accounts for Entra role assignments, on the basis that a compromised on-premises account can then compromise Entra resources. And multifactor authentication on every administrator account is not optional: Microsoft cites its own study that an account is 99.9% less likely to be compromised where MFA is used.

On the workload side, managed identities are the control rather than the risk. Microsoft describes manual handling of secrets and certificates as a known source of security issues and outages, and managed identities as eliminating the need for developers to manage them: applications obtain Entra tokens without managing any credentials, and the credentials are not even accessible to you. The assessment question is therefore not whether managed identities are used but what each one is authorised to reach, and whether a user-assigned identity shared across many resources has accumulated the union of everything any of them ever needed.

Walking the graph in an engagement

The practical sequence is the same on every provider. Enumerate the principals: users, groups, roles, service principals, service accounts and workload identities, including federated ones. Enumerate the transitions: role trust policies, assume-role permissions, PassRole grants and their resource scopes, impersonation grants, Kubernetes service account bindings, and any permission that creates compute able to run as an identity. Resolve reachability from each low-privilege starting point. Rank what each reachable identity can actually touch, because a path to an unused role is not a finding and a path to a role that can read production data is the report.

Then prove the paths that matter, from a credentialed low-privilege principal supplied for the purpose. This is the part a read-only audit role cannot do: reading the policies tells you a path should exist, and only walking it tells you whether it does. Keep the proof minimal and reversible, stop at the point the path is demonstrated, and record the exact permission that made each transition possible, because that permission is the remediation.

  • Where a transition depends on a wildcard resource, the fix is a resource scope, not a smaller policy.
  • Where it depends on a trust policy, the fix is a condition: an external ID for third-party access, a source account or organisation for service principals.
  • Where it depends on standing privilege, the fix is time: just-in-time activation with an expiry, rather than a permanent assignment that is reviewed annually.
  • Where it depends on a long-lived key, the fix is to remove the key and federate, because a key that can be copied will eventually be copied.

None of these controls is exotic and all four are documented by the provider whose platform they apply to. What makes the work valuable is not knowing them. It is resolving which of the thousands of grants in a real account compose into a path that reaches something worth reaching, which is why the configuration baseline comes first and the identity graph is built on top of it.

Sources

  1. Grant a user permissions to pass a role to an AWS service Amazon Web Services · 2026 The PassRole permission, the warning about passing stronger roles, the iam:PassedToService condition key and the absence of CloudTrail records for PassRole.
  2. The confused deputy problem Amazon Web Services · 2026 Cross-account and cross-service confused deputy, the sts:ExternalId condition and the aws:Source* condition keys.
  3. Use the Instance Metadata Service to access instance metadata Amazon Web Services · 2026 IMDSv2 session tokens, instance-specific keys, X-Forwarded-For rejection and the default hop limit of 1.
  4. Service accounts overview Google Cloud · 2026 Impersonation, the Token Creator and Service Account User roles, and the guidance on service account keys.
  5. Best practices for Microsoft Entra roles Microsoft · 2026 Fewer than five Global Administrators, fewer than ten privileged assignments, PIM just-in-time activation, break-glass accounts and cloud-only admin accounts.
  6. Managed identities for Azure resources Microsoft · 2026 System-assigned against user-assigned identities, and the removal of stored credentials.
  7. Cloud Matrix MITRE ATT&CK · 2026 Platforms covered and the identity techniques: valid accounts, additional cloud credentials, additional cloud roles.

Questions

Related questions

What is the most common cloud privilege-escalation path?

Delegation that reaches further than the delegate. On AWS that is typically iam:PassRole granted without a resource restriction, letting a principal hand a stronger role to a service it can create. On Google Cloud it is an impersonation grant on a privileged service account. On Azure it is standing privileged role assignments that were never converted to just-in-time activation.

Does enabling IMDSv2 fix server-side request forgery on EC2?

Only if IMDSv1 is disabled. AWS states that by default you can use either version, and that an instance must be configured to accept IMDSv2 calls only for IMDSv1 calls to fail. Check both that token usage is required and that the response hop limit is still 1, since raising it for container compatibility puts the metadata endpoint back within reach.

Why does a third-party audit role need an external ID?

Because your role ARN is not a secret and the assessor serves other clients. The external ID is the condition AWS documents specifically to prevent the confused deputy problem, and it works because the value is unique per customer and controlled by the third party rather than by its customers.

Can you find these paths from a read-only role?

You can find the candidates. Reading trust policies, PassRole grants and impersonation bindings tells you which paths should exist. Proving that a path actually works, and that it reaches what it appears to reach, needs a credentialed low-privilege principal supplied for the purpose, which is why an assessment asks for one per persona you want tested.