Stackvora.tech

AWS IAM: least-privilege without going insane

A pragmatic guide to AWS IAM least-privilege — policies, boundaries, and how to migrate from "AdministratorAccess" safely.

Least-privilege on AWS is easy to preach and painful to implement. The mistake most teams make is trying to hand-write policies from a blank page. Do this instead.

The three-tier approach

  1. Managed policies for humans. Use AWS-managed policies (ReadOnlyAccess, PowerUserAccess, service-specific admin like AmazonEC2FullAccess) as the baseline.
  2. Custom policies for automation. CI roles, Terraform roles, Lambda roles — these should be tightly scoped to specific resources.
  3. Permission boundaries for delegation. When teams create their own roles, boundaries cap what those roles can ever do.

Discover what a role actually needs

# Turn on IAM Access Analyzer, then let the role run for 90 days
aws accessanalyzer start-policy-generation \
  --policy-generation-details principalArn=arn:aws:iam::123:role/ci-deploy

Access Analyzer will generate a minimum-viable policy based on actual CloudTrail activity. This is 10× better than guessing.

A least-privilege deploy role — real example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::acme-artifacts/prod/*"
    },
    {
      "Effect": "Allow",
      "Action": "ecs:UpdateService",
      "Resource": "arn:aws:ecs:eu-west-1:123:service/prod/*",
      "Condition": {
        "StringEquals": { "ecs:cluster": "arn:aws:ecs:eu-west-1:123:cluster/prod" }
      }
    }
  ]
}

Guardrails that scale

  • SCP (Service Control Policies) at the org level — deny actions no account should ever use (like iam:CreateUser outside break-glass).
  • Permission boundaries — cap the maximum a role can have, even if a developer attaches AdministratorAccess to it.
  • Session tags — restrict what a federated user can do based on their SSO group.

Migrating from wide-open

  1. Turn on CloudTrail + Access Analyzer everywhere.
  2. For each role with AdministratorAccess: run 30–90 days, then let Access Analyzer generate a real policy.
  3. Attach the new policy alongside, monitor for a week, then remove admin.
  4. Repeat.
Least-privilege isn't a project you finish — it's a discipline you keep. Automate the discovery step or it will never happen.

Back to the knowledge base · Ask the AI assistant