All resources
// Resources

Cloud IAM Least-Privilege Review: Effective Permissions

Published July 15, 2026

Least privilege is not an attached policy with fewer lines. It is a demonstrated answer to: which authenticated principal can perform which action on which resource, under which conditions, through every available path? Start with workloads and administrators separately; both can become a route to production data.

Build an effective-permission map

For every human group, workload identity, service principal, and break-glass role, collect direct grants, inherited grants, resource policies, group membership, and delegation paths. Google Cloud calls inherited allow-policy union an effective allow policy. Azure RBAC is additive across role assignments, then deny assignments and conditions participate in evaluation. AWS evaluation includes identity policies, resource policies, permissions boundaries, SCPs, and session policies; an explicit deny overrides an allow.

Do not infer this map from a role name. Test representative actions against an intended resource and a forbidden neighbor. Record scope at organization, subscription/account, project, folder, resource group, resource, and data-plane level. A read-only Azure management role does not automatically describe blob data access; similarly, an AWS S3 action and its bucket resource must be evaluated separately.

PrincipalIntended capabilityEffective scopeOwnerEvidenceResult
CI deployment roledeploy staging servicenamed staging resourcesplatform ownerpolicy simulation and trust policypass/fail
application workloadread tenant-a/ objectsone bucket prefixservice ownerruntime identity and access testpass/fail
emergency administratortime-bound recoverydocumented accounts onlysecurity ownerapproval and session audit eventpass/fail

Trace role assumption and delegation

An apparently narrow permissions policy fails if its principal may assume a broader role, pass a privileged role to a service, create credentials, or change its own authorization. Review AWS trust policies, sts:AssumeRole, iam:PassRole, federation mappings, and session policies together. A role session is its own request principal; resource-policy behavior can differ from a grant to the role ARN. Treat cross-account trust as a separate access path, not as a footnote.

Google Cloud workload identity federation and service-account impersonation need the same treatment: identify source identity, target service account, granted roles, resource hierarchy, deny policies, principal access boundaries, and IAM Conditions. Azure requires security principal, role definition, assignment scope, deny assignments, and role-assignment conditions. Resolve transitive group membership before declaring a person or workload limited.

Use boundaries to limit delegation, not to create phantom access. AWS permissions boundaries cap what identity policies can grant; they do not grant permission themselves. In Google Cloud, principal access boundary policies limit resources a principal is eligible to access even when an allow policy grants a role. These controls are useful guardrails for team-managed roles, but neither replaces a precise base grant.

{
  "Effect": "Allow",
  "Action": ["s3:GetObject"],
  "Resource": "arn:aws:s3:::example-private/tenant-a/*"
}

This example is deliberately narrow: no list, write, delete, KMS decrypt, role assumption, or wildcard bucket. Add only operations proven by application behavior, then retest denied paths.

Evidence, exceptions, and repair

A completed review artifact must contain review date, environment, principal ID, intended capability, effective scope, policy/trust-policy versions or immutable links, test command or simulator output, result, and reviewer. For each failed check, name an owner, remediation, due date, and retest evidence. Store policy snapshots outside mutable application repositories when possible.

An exception must state business need, affected principal and resource, exact actions, compensating controls, approving owner, expiry, and removal test. “Temporary admin” without an expiry is a failed control. Remove unused long-lived credentials, broad predefined roles, stale groups, dormant service accounts, and obsolete cross-account trusts before creating new custom roles.

Recheck after identity-provider changes, infrastructure deployments, new resource policies, and incident containment. Infrastructure testing can validate approved cloud authorization paths without treating a checklist as evidence by itself.

Worked case: narrow deployment role

Start with a deployment role allowed to update one named service. Collect intended API calls from a controlled dry run, then write resource and condition boundaries from those calls rather than copying an administrator policy. Expected output allows deployment to named environment and denies update against sibling environment, unrelated service, and direct credential-management action. Record denied event identifiers and compare them with expected denial list; unexpected allows are review defects, while unexpected denies need workflow evidence before widening policy.

Edge tests before closure

Test assumed role from unauthorized principal, expired session, missing tag, and malformed resource identifier. Examine permission boundary and organization-level policy separately, since effective access is intersection. Closure bundle contains policy revision, evaluator output, successful dry-run trace, denial trace, approver, and dated exception if any. Recheck when deployment workflow adds API calls; no standing wildcard is created merely to silence a new denial.

Sources

Have a system that needs testing?