Benchmark tools give you a list: unused credentials, wildcard actions, policies missing conditions. Useful for coverage, useless for prioritisation, because a wildcard on a role nobody can assume matters less than a narrowly scoped permission on the role your build pipeline hands to every contributor.
The reordering question is: if this identity is compromised, what happens next? Here is how to answer it in about a day per account.
Step 1: list the identities an attacker can plausibly reach
Not every principal — the ones with a realistic compromise path.
- CI/CD roles and any long-lived deployment keys.
- Compute roles attached to internet-facing workloads: an SSRF in one of those hands over its credentials.
- Developer and contractor logins, especially any without hardware MFA.
- Third-party integrations with cross-account trust — monitoring, cost tools, security vendors.
- Anything with a static access key older than ninety days.
Step 2: for each, enumerate what it can actually do
Effective permissions, not attached policies. Resource policies, permission boundaries, session policies and service control policies all interact, and reading the attached policy alone gives you the wrong answer.
- Use policy simulation and effective-permission tooling rather than reading JSON.
- Group the result into four buckets: read data, modify data, escalate privilege, destroy or deny service.
- Note every permission that touches secrets, key management or logging — those change everything downstream.
Step 3: trace escalation edges
This is where the real findings are. Escalation is rarely a single permission called AdministratorAccess; it is a chain nobody drew.
- iam:PassRole plus the ability to launch compute equals the permissions of the role you pass.
- Updating a Lambda function’s code, or its execution role, executes your code with that role’s permissions.
- Writing to an infrastructure-as-code bucket, or to a pipeline definition, is production deployment with extra steps.
- Editing a trust policy on a role you can already assume can widen it to something far more useful.
- Creating access keys for another user is direct impersonation.
Step 4: check the CI path specifically
In most small and mid-size environments, the shortest route to production is the build pipeline, and it is guarded by conventions rather than controls.
- Who can modify a workflow file? If the answer is any contributor, they can deploy.
- Is deployment credentialed with a long-lived key, or with short-lived federated credentials?
- Can a pull request from a fork trigger a workflow that holds those credentials?
- Are third-party actions pinned to a commit, or to a tag someone else can move?
- Does the production role trust one branch, or the whole repository?
Step 5: rank by reachable impact and write the two-week plan
Sort by what the compromise reaches, not by tool severity. In practice the first fixes are usually the same four:
- Replace long-lived keys with OIDC federation and per-environment roles.
- Split staging and production trust so no single identity spans both.
- Scope iam:PassRole to specific roles instead of a wildcard.
- Turn on and protect audit logging — an environment with no trail turns every incident into speculation.
Then re-draw the graph. If cutting two edges collapsed the reachable set, that is the evidence the review was worth the day it cost.