AWS IAM Least Privilege in Practice: From Everyone-Has-Admin to Scoped Permissions

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
Over-permissioned IAM is the AWS security problem that nearly every cloud team understands in principle but almost none remediate successfully in practice. The gap between knowing that least privilege matters and actually implementing it across a real AWS environment comes down to two things: the difficulty of understanding what permissions are actually being used, and the fear of breaking production workloads by removing permissions that might be needed. This guide addresses both problems directly. It covers the tooling that generates actionable permission-reduction data, the policy patterns that let you enforce least privilege incrementally without a big-bang cutover, and the specific approaches that work for CI/CD pipelines, which are typically the most over-permissioned and most operationally sensitive part of any AWS environment.
Why Everyone-Has-Admin Happens and Why It Stays
The path to widespread AdministratorAccess in an AWS environment is almost always the same. An early engineer or team needs to ship quickly and grants themselves or their service roles AdministratorAccess to avoid friction. This works so well that the pattern propagates: the next CI/CD pipeline gets AdministratorAccess because the previous one had it and nobody was blocked. New team members are onboarded with admin access because scoping permissions would take time the team doesn't have. Infrastructure as code tools like Terraform and CDK get service roles with AdministratorAccess because the scope of what they might need to provision is genuinely broad and nobody wants to debug a permissions error during a critical deployment.
The pattern stays because fixing it carries real operational risk. Removing permissions from a role that a production workload is using can cause immediate, visible failures. The blast radius of a permissions reduction mistake is often a production outage, which makes engineers understandably reluctant to touch IAM policies on running systems. Without tooling that shows exactly which permissions a role has actually used, there is no safe way to determine which permissions are safe to remove.
The consequence of allowing this to persist is that a single compromised credential in your environment, whether through a phishing email, an exposed CI secret, or a misconfigured SSRF endpoint on an EC2 instance, can result in full account takeover. An attacker with access to an AdministratorAccess role can create new IAM users, disable CloudTrail logging, exfiltrate all S3 data, spin up cryptocurrency mining infrastructure, and establish persistence mechanisms that survive credential rotation. The PACU framework, a publicly available AWS exploitation toolkit, automates most of these steps and can enumerate your entire account's resources and permissions in minutes.
The reason least privilege never gets implemented without a deliberate program is that it is never urgent until after a breach. Every week the environment runs fine with AdministratorAccess everywhere is evidence (to busy engineers) that the permissions don't need to change. Changing this requires executive sponsorship of a least privilege initiative, dedicated engineering time, and tooling that makes the risk concrete and the remediation safe.
Subscribe to unlock Remediation & Mitigation steps
Free subscribers unlock full IOC lists, Sigma detection rules, remediation steps, and every daily briefing.
IAM Access Analyzer: Finding What You Actually Use
IAM Access Analyzer's last-accessed information feature is the tool that makes safe permission reduction possible. It analyzes CloudTrail logs to determine which services, actions, and resources each IAM entity (user, role, or group) has actually accessed within the past 90 days. This data answers the question that makes engineers nervous about permission reduction: if I remove permission X, will something break?
To access last-accessed data, navigate to the IAM console, select a role or user, and click the "Access Advisor" tab. The tab lists every service policy that grants access to that entity, and for each service shows either the last date the service was accessed or "Not accessed in the tracking period" if the service has never been used by that entity. For roles, this reflects all sessions that assumed the role. For users, it reflects direct API calls.
Access Analyzer also provides unused access findings through its console. In the Access Analyzer section of IAM, you can enable unused access analyzers that automatically surface IAM roles with unused permissions, unused access keys older than 90 days, and roles that have not been used at all. These findings are presented as a prioritized list that your security team can work through as a remediation queue.
The practical workflow for a permission reduction initiative is to start with the unused roles finding first. Roles that have not been used at all in the past 90 days are safe candidates for deletion (with a deletion prevention step: detach all policies and add a deny-all boundary first, then monitor for a week before deleting, in case the role is used for an infrequent or scheduled task). After clearing unused roles, move to roles that have been used but show a significant mismatch between attached permissions and accessed services.
For a role with AdministratorAccess that the Access Advisor shows has only accessed EC2, CloudWatch, and S3, you can generate a least-privilege policy using IAM Access Analyzer's policy generation feature. This feature reads CloudTrail logs for the role within a specified date range and produces a policy document that grants only the actions it actually observed, scoped to the resources it actually accessed. The generated policy is a starting point that requires human review (to account for periodic tasks that may not have run in the analysis window) but is dramatically more scoped than AdministratorAccess.
Subscribe to unlock Remediation & Mitigation steps
Free subscribers unlock full IOC lists, Sigma detection rules, remediation steps, and every daily briefing.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Permission Boundaries and Service Control Policies: The Safety Net Architecture
Access Analyzer data tells you what permissions to remove. Permission boundaries and Service Control Policies (SCPs) enforce maximum permission ceilings that prevent over-permissioning from being reintroduced, even if an administrator makes a mistake or a developer requests excessive access.
A permission boundary is an IAM managed policy that is attached to an IAM role or user as a boundary rather than as a normal permission policy. The effective permissions of a role are the intersection of its attached policies and its permission boundary. If a role has AdministratorAccess attached but a permission boundary that only allows EC2, S3, and CloudWatch actions, the role can only perform EC2, S3, and CloudWatch actions regardless of what its permission policy says. This is a powerful delegated administration pattern: you can allow a team to create and manage their own IAM roles (necessary for Terraform workflows) but require that all roles they create have a permission boundary attached that caps their maximum permissions.
The Terraform workflow that implements this is: the platform team creates a set of permission boundaries appropriate for each workload tier (application tier, data tier, network tier), and the Terraform code for each team's infrastructure includes an iam_permissions_boundary attribute on all IAM role resources that references the appropriate boundary ARN. The platform team's SCP prevents the creation of IAM roles without a permission boundary, so teams cannot bypass the control by omitting the attribute.
Service Control Policies operate at the AWS Organization level and apply to all accounts within an organizational unit regardless of what IAM policies within the account allow. SCPs are the correct mechanism for organization-wide prohibitions: deny all API calls from outside your approved AWS regions, deny the creation of IAM users (forcing use of SSO instead), deny the disabling of CloudTrail or GuardDuty, and deny the creation of IAM roles with full AdministratorAccess. SCPs do not replace IAM policies but act as the outer boundary that even account root cannot bypass.
A concrete SCP that every AWS organization should implement is a CloudTrail protection policy: deny cloudtrail:StopLogging, cloudtrail:DeleteTrail, and cloudtrail:UpdateTrail for all principals except a specifically named security audit role. This single policy prevents an attacker who has compromised any account role (including administrator roles) from disabling your audit log. Combined with a similar policy protecting GuardDuty, it ensures that your detection controls remain operational even during an active incident.
Subscribe to unlock Remediation & Mitigation steps
Free subscribers unlock full IOC lists, Sigma detection rules, remediation steps, and every daily briefing.
Scoping CI/CD Pipeline Roles: What a Deployment Role Actually Needs
CI/CD pipeline roles are typically the most over-permissioned entities in an AWS environment and also the most operationally sensitive. A pipeline role that is too permissive is a single compromised build artifact away from full account takeover. A pipeline role that is too restrictive will break deployments and generate support tickets. Getting this balance right requires understanding what a deployment role actually needs to do.
For a standard application deployment that builds a container, pushes it to ECR, and deploys it to ECS, the required permissions are: ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:PutImage, and ecr:InitiateLayerUpload (for the ECR push); ecs:RegisterTaskDefinition, ecs:UpdateService, ecs:DescribeServices, and ecs:DescribeTaskDefinition (for the ECS deployment); iam:PassRole scoped to the ECS task execution role ARN (required to register the task definition); and logs:CreateLogGroup, logs:CreateLogStream if the pipeline creates its own log groups. This is dramatically narrower than AdministratorAccess but covers the complete deployment operation.
For Terraform-managed infrastructure, the required permissions are more complex because Terraform needs to read current state, plan changes, and apply changes across multiple AWS services. The correct approach is not to grant AdministratorAccess but to enumerate the services your Terraform code actually provisions and grant only the actions required for create, read, update, and delete operations on those specific resources. Use IAM Access Analyzer's policy generation feature against a staging environment's Terraform apply CloudTrail log to generate a scoped policy automatically.
The separation of plan and apply is an important operational pattern for Terraform pipeline roles. Create two roles: a plan role with read-only access to all relevant services (the equivalent of all Describe*, List*, and Get* actions), and an apply role with the write permissions needed to create and modify resources. The plan role is used for every branch push (to show what would change in a PR review). The apply role is only assumed for deployments from the main or release branch. This limits the blast radius of a compromised PR build to read-only account enumeration rather than resource modification.
For GitHub Actions, the recommended approach is OpenID Connect (OIDC) federation rather than long-lived access keys. Configure an OIDC identity provider in IAM that trusts GitHub's OIDC endpoint, and create an IAM role with a trust policy that restricts assumption to specific GitHub repository and branch combinations. The role can only be assumed by a GitHub Actions workflow running from your specific repository and a specified branch. This eliminates the need to store AWS credentials as GitHub secrets and means there are no long-lived keys to rotate or leak.
Subscribe to unlock Remediation & Mitigation steps
Free subscribers unlock full IOC lists, Sigma detection rules, remediation steps, and every daily briefing.
Break-Glass Admin and Eliminating Long-Lived Access Keys
Every organization needs some mechanism for emergency administrator access, but the architecture of that mechanism determines whether it is a controlled emergency tool or a persistent standing backdoor. The break-glass pattern provides high-privilege access that is logged, time-limited, and requires an explicit human action to activate.
The standard break-glass implementation in AWS uses an IAM role with AdministratorAccess that has a trust policy restricting assumption to a small number of named IAM identities (typically two or three senior security engineers and the on-call account). The role is not assumed in normal operations and does not appear in day-to-day Access Analyzer unused role findings because it is intentionally rarely used. AWS Config rules and an EventBridge rule alert the security team whenever this role is assumed, triggering a notification that includes the session context. Break-glass sessions should be time-boxed using IAM role maximum session duration (set to one hour for break-glass roles) and should be recorded via session logging if your identity platform supports it.
Eliminating long-lived IAM user access keys is one of the highest-impact actions you can take for account security. Access keys do not expire by default, are frequently embedded in application code and CI systems, and are often forgotten about when the engineer who created them changes roles or leaves the organization. AWS has made this visibility easier: the IAM credentials report (accessible from the IAM console or via iam:GenerateCredentialReport) lists every user, their access key ages, and their last-used dates. Any access key older than 90 days that is still active should be investigated, and any key that has not been used in 90 days should be disabled.
The structural solution is to replace IAM users and long-lived access keys with IAM roles and temporary credentials wherever possible. Applications running on AWS compute (EC2, Lambda, ECS, EKS) should use instance profiles and task roles to receive temporary credentials automatically through the instance metadata service. Applications outside AWS should use cross-account OIDC federation or AWS IAM Identity Center access for humans. The only legitimate use case for long-lived IAM user access keys in a mature AWS environment is integration with legacy systems that cannot perform assume-role or OIDC flows.
AWS IAM Identity Center (formerly AWS SSO) is the path for human users. Rather than maintaining an IAM user in each AWS account, Identity Center provides a single sign-on portal where users authenticate with your corporate identity provider (Okta, Azure AD, Google Workspace) and receive time-limited role sessions in the AWS accounts and with the permission sets they are authorized for. This means no long-lived keys, centralized access reviews, and the ability to revoke access from a single place when an employee leaves.
Subscribe to unlock Remediation & Mitigation steps
Free subscribers unlock full IOC lists, Sigma detection rules, remediation steps, and every daily briefing.
Operationalizing Least Privilege: The Incremental Remediation Roadmap
Least privilege in a real AWS environment is not a one-time project but a continuous operational practice. The initial remediation clears the backlog; the ongoing program prevents it from returning. An operationally sustainable least privilege program has four components: a baseline audit, an incremental remediation cycle, a prevention gate in the provisioning pipeline, and a continuous monitoring alert set.
The baseline audit uses IAM Access Analyzer, the credentials report, and a CSPM tool (Wiz, Prisma Cloud, or AWS Security Hub with the CIS AWS Foundations Benchmark standard enabled) to generate a prioritized remediation list. Classify findings by severity using the framework described earlier: unused roles first, then over-permissioned roles, then long-lived keys, then missing SCPs. Set remediation SLAs for each category (unused roles within 30 days, long-lived keys within 60 days) and track completion in your security program dashboard.
The incremental remediation cycle works by processing the remediation list in priority order without attempting to fix everything simultaneously. Pick a set of ten to twenty roles per sprint, generate least-privilege policies using Access Analyzer's policy generation tool, test the new policies in a staging environment using the same workload, and deploy the policy change to production with a rollback plan that can re-attach the original policy within five minutes. This cautious approach adds friction but prevents the production outage that would kill stakeholder support for the program.
The prevention gate is a set of automated checks in your IaC review pipeline. Any pull request that creates a new IAM role with AdministratorAccess or modifies an SCP to remove a protection should fail a policy check that requires security team approval before merge. Tools like Checkov, Terrascan, and Open Policy Agent can evaluate Terraform plans against custom rules and post findings to pull request comments. This creates a security review gate without blocking legitimate IAM changes that pass the rules.
The continuous monitoring set consists of three AWS Config rules: one that alerts when any role with AdministratorAccess is created, one that alerts when any IAM user access key older than 90 days is active, and one that alerts when any S3 bucket in the account is made public. These three alerts, routing to your security team's alert channel, catch the most common IAM drift patterns before they accumulate into the original problem. Set the response expectation for each alert: administrative access keys require a response within 4 business hours, new admin roles within 24 hours, public S3 buckets immediately.
The bottom line
Run IAM Access Analyzer's unused access report today to see your actual permissions exposure. Start restricting the highest-risk accounts first: any human user with AdministratorAccess, any CI/CD role with write access to production. Apply permission boundaries as a safety net before touching production policies, and migrate to IAM Identity Center to eliminate long-lived access keys entirely.
Frequently asked questions
How do we handle the risk that removing permissions breaks a production workload?
Use IAM Access Analyzer to generate a policy based on actual CloudTrail usage data before removing permissions. Apply the new scoped policy to a staging workload first and run a full test cycle. For production changes, keep the original policy document stored in version control or Parameter Store and create a runbook step to reattach it within five minutes if the deployment triggers errors. Never delete the old policy until the replacement has been running in production without errors for at least two weeks.
What is the difference between a permission boundary and a Service Control Policy?
A permission boundary is attached to an individual IAM role or user and caps that entity's maximum permissions. It is enforced at the IAM level and affects only the entity it is attached to. A Service Control Policy is attached to an AWS Organization unit or account and applies to all IAM entities within that account, including the account root. SCPs set account-wide ceilings; permission boundaries set entity-level ceilings. For comprehensive coverage you need both.
Our Terraform pipeline needs broad permissions to provision diverse infrastructure. How do we scope it?
Run an IAM Access Analyzer policy generation against the CloudTrail logs from a complete Terraform apply cycle in a staging environment. The generated policy will show exactly which actions were called against which resource types. Scope the production Terraform role to those actions. Create a separate read-only plan role for PR builds. Accept that the apply role will have broader permissions than application roles, but narrow it from AdministratorAccess to the specific services your infrastructure actually uses.
How do we track which team owns each IAM role for remediation coordination?
Enforce IAM resource tagging using an SCP that denies role creation without required tags such as owner, team, and purpose. For existing roles without tags, use the AWS Tag Editor to bulk-apply tags based on role naming conventions or the accounts they were created in. Store the tag-to-team mapping in your CMDB or a simple spreadsheet, and use this mapping to route remediation tickets to the right team automatically when Access Analyzer generates findings.
What is the fastest way to get visibility into current IAM risk across a multi-account AWS organization?
Enable AWS Security Hub across all accounts in your organization using AWS Organizations delegated administrator, and activate the AWS Foundational Security Best Practices standard and the CIS AWS Foundations Benchmark standard. This generates IAM findings across all accounts in a single console within 24 hours. Pair this with IAM Access Analyzer organization-level deployment (which surfaces external access and unused access findings organization-wide) for a comprehensive multi-account IAM risk picture without installing additional tooling.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
