Triage and Remediation
- Remediation
Remediation
Using Console
Using Console
Below is a practical, step‑by‑step way to find and fix IAM roles that have permissions to modify infrastructure in AWS, using only the AWS Console.
If you share an example of a specific role’s current policy (JSON or console screenshots), I can walk you through an exact “before → after” policy and the precise console clicks for that case.
1. Identify High‑Risk Roles
- Sign in to the AWS Management Console.
- Go to IAM:
- Search for “IAM” in the services search bar and open IAM.
- In the left menu, click Access reports → Policy usage (AWS Managed Policies) (if available in your region), or:
- Click Policies and filter by:
AdministratorAccessPowerUserAccess- Any custom policies that obviously grant high privileges (e.g., names containing
admin,fullaccess,*).
- Click Policies and filter by:
- For each high‑privilege policy:
- Click the policy.
- Go to the Policy usage tab.
- Review which roles this policy is attached to.
- Use AdministratorAccess, PowerUserAccess, or very broad
*permissions. - Have broad access to critical infra services:
ec2:*,iam:*,cloudformation:*,eks:*,rds:*,lambda:*,elasticloadbalancing:*, etc.
2. Understand What Each Role Really Needs
For each high‑risk role you found:- In IAM → Roles, click the role name.
- Check:
- Trust relationships (who/what can assume the role).
- Permissions tab → all attached policies.
- Determine the role’s real purpose:
- Is it used by an application (e.g., EC2 instance profile, Lambda, ECS task)?
- Is it used by a human via AWS SSO or
sts:AssumeRole? - Is it used by a CI/CD system (e.g., GitHub Actions, Jenkins, CodePipeline)?
- Which specific services and actions does this role actually need to perform?
- What environments does it operate in (dev/test/prod)?
3. Create a Least‑Privilege Custom Policy
You’ll now replace broad/infrastructure‑modifying permissions with a custom least‑privilege policy.- In IAM → Policies, click Create policy.
- Choose Visual editor (easier through console).
-
For each service the role truly needs:
- Click Service and select (for example):
Amazon EC2AWS LambdaAmazon S3- etc.
- Under Actions, select only the exact Read/Write operations required, and avoid:
*(All EC2 actions, All IAM actions, etc.).- Any action that allows broad infra modification if not required, such as:
ec2:TerminateInstances,ec2:RunInstances,ec2:CreateVpc, etc.iam:*or powerful IAM actions likeiam:CreateRole,iam:PutRolePolicy,iam:PassRole*(unless truly required).cloudformation:*if not really needed.
- Under Resources, avoid
All resourceswhere possible:- Use ARNs to narrow to specific resources (e.g., a specific S3 bucket, specific Lambda functions, a particular VPC or EC2 instances via tags).
- Use Conditions to further restrict (e.g., only allow certain tags, regions, or actions from particular principals/IPs).
- Click Service and select (for example):
- Click Next → add Tags if needed → Next: Review.
-
Give the policy a clear, descriptive name, e.g.:
AppName-Role-LeastPrivilege-EC2Lambda-Policy
- Click Create policy.
4. Apply the New Policy to the Role and Remove Over‑Privileged Ones
For each high‑risk role:- In IAM → Roles, select the role.
- Go to the Permissions tab and click Add permissions → Attach policies.
- Search for and select the new custom policy(ies) you just created.
- Click Next → Add permissions.
- Still on the role’s Permissions tab, identify over‑privileged policies such as:
AdministratorAccessPowerUserAccess- Any policy with
*on critical infra services.
- For each such policy:
- Click the X or “Detach” button next to the policy.
- Confirm the detachment.
5. Tighten IAM Permissions Specifically Related to Infrastructure
For roles that still must modify infrastructure (e.g., CI/CD roles, automation roles), scope them down:- Limit IAM Changes:
- Avoid
iam:*. Instead grant minimal:iam:PassRoleonly for specific roles (narrow by ARN).- If needed,
iam:CreateRole,iam:AttachRolePolicy, etc., but only for specific roles and with conditions.
- Avoid
- Limit EC2 / VPC / RDS / CFN:
- Prefer granular actions: e.g.,
ec2:DescribeInstances,ec2:RebootInstancesinstead ofec2:*. - Restrict by resource ARN or tags when supported.
- Prefer granular actions: e.g.,
- Use Conditions in policies:
- Restrict to specific regions:
aws:RequestedRegion. - Restrict to specific VPC / tags when available.
- Restrict to service principals or specific users where relevant.
- Restrict to specific regions:
6. (Optional) Use IAM Permissions Boundaries for Shared/Delegated Roles
If you delegate creation of roles to different teams but want to ensure they cannot grant themselves infra‑wide powers:- Create a permissions boundary policy (IAM → Policies → Create policy) that:
- Allows typical application actions.
- Explicitly denies dangerous top‑level actions such as:
iam:*(or specificallyiam:CreateRole,iam:PutRolePolicy, etc.).ec2:*except for approved actions.cloudformation:*if not required.
- Save the policy (e.g.,
OrgAppRoles-PermissionsBoundary). - When a new role is created:
- In IAM → Roles → Create role, on the Permissions boundary step select this policy.
- For existing roles (where needed):
- Go to the role → Permissions tab → Permissions boundary → Edit and attach the boundary.
7. Validate with IAM Access Analyzer and Access Advisor
- In IAM → Access Analyzer:
- Create an analyzer if not present.
- Review Findings for unusual or broad access (e.g., roles with external access or public access).
- In IAM → Roles, select a role and go to:
- Access Advisor tab (or Last accessed info):
- Inspect which services the role actually uses.
- If some services are never used, remove those permissions from the role’s policies.
- Access Advisor tab (or Last accessed info):
8. Put Guardrails in Place (Optional but Recommended)
- AWS Config Rules:
- Go to AWS Config in the console.
- Set up rules such as:
IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESSIAM_USER_NO_POLICIES_CHECK- And other IAM‑related rules that flag over‑privileged policies.
- Security Hub (if used):
- Enable Foundational Security Best Practices standard.
- Review and remediate IAM‑related findings regularly.
9. Operate a Safe Change Process
For production roles that can modify infrastructure, add process protections:- Test role changes in dev/stage accounts first.
- Keep versioned IAM policies (JSON exported to Git or similar).
- Implement change approvals for any role that:
- Can modify networks (VPC, Security Groups, Route Tables).
- Can create/modify IAM roles or policies.
- Can deploy infra via CloudFormation/Terraform/other IaC tools.
If you share an example of a specific role’s current policy (JSON or console screenshots), I can walk you through an exact “before → after” policy and the precise console clicks for that case.
Using CLI
Using CLI
Below is a concise, AWS-CLI–focused walkthrough to find and remediate IAM roles whose permissions can modify infrastructure (e.g., EC2, RDS, Lambda, CloudFormation, IAM, etc.).
Ensure you’re using an admin or security/audit account to inspect and update IAM.
Review For each ARN:Again, examine
6.1 If AWS-managed (e.g.,
You cannot change AWS-managed policies; instead:
Check which actions are “allowed.” Confirm only intended actions are permitted.
If you share a sample policy document or a specific role name/policy, I can provide an exact CLI sequence and a concrete “before/after” JSON policy tailored to your use case.
1. Preparation
Configure AWS CLI with appropriate credentials and region:2. Identify IAM Roles and Attached Policies
2.1 List all roles
2.2 For each role, list its inline and attached policies
Example for one role:3. Detect “Infrastructure-Modifying” Permissions
You’re looking for actions that can create/update/delete infrastructure, or grant such rights to others.3.1 Common infrastructure-modifying actions
Examples (not exhaustive):ec2:*,ec2:RunInstances,ec2:Create*,ec2:Modify*,ec2:TerminateInstancesrds:*,lambda:*,elasticloadbalancing:*,eks:*,cloudformation:*iam:Create*,iam:PutRolePolicy,iam:Attach*,iam:PassRoleautoscaling:*,elasticbeanstalk:*,apigateway:*,ecs:*,s3:CreateBucket,s3:PutBucketPolicy, etc.
3.2 Inspect policies attached to a role
a) Inline role policies
PolicyDocument.Statement[].Action for broad or dangerous actions (especially * or infra APIs above).b) Attached managed policies
Statement[].Action for infra-modifying permissions.You can script this to grep for suspicious services:4. Decide the Intended Scope (Least Privilege Design)
For each role:- What is it supposed to do? (Application role, CI/CD role, break-glass admin, etc.)
- Map required actions:
- e.g., EC2 instance profile that only needs to read from S3:
s3:GetObject,s3:ListBucket. - CI/CD may need
cloudformation:*in specific stacks only.
- e.g., EC2 instance profile that only needs to read from S3:
5. Remediate Inline Policies (Using AWS CLI)
5.1 Export existing inline policy
5.2 Edit to least privilege
Manually editold_policy.json:- Remove wildcards like
"Action": "*". - Replace broad services like
"ec2:*"with specific actions (e.g.,"ec2:DescribeInstances"). - Add resource constraints where possible (e.g., specific ARNs instead of
"Resource": "*") - Add conditions where appropriate (e.g., IP, tags, MFA).
new_policy.json.5.3 Apply updated inline policy
6. Remediate Managed Policies Attached to Roles
6.1 If AWS-managed (e.g., AdministratorAccess)
You cannot change AWS-managed policies; instead:-
Detach from the role:
-
Create a new customer-managed least-privilege policy:
Prepare
least_priv_policy.jsonwith restricted actions/resources. -
Attach the new policy:
6.2 If customer-managed
-
Create a new version with reduced permissions.
Edit current document into
new_policy.json(least privilege). -
Optionally, delete old policy versions later to stay under the 5-version limit.
Then:
7. Lock Down IAM-Sensitive Actions
Special attention to:iam:PassRole– restrict to specific role ARNs and services:iam:AttachRolePolicy,iam:PutRolePolicy,iam:CreatePolicy,iam:CreateRole, etc.
Restrict to admin-only roles, or to specific ARNs.
8. Validate Effective Permissions
8.1 Simulate policy for a role
8.2 Optional: Enumerate all actions (coarse check)
Use a broad set (e.g.,ec2:*, cloudformation:*) in simulation to see if any infra-modifying actions slip through.9. Continuous Control
- Use IAM Access Analyzer to find overly broad permissions:
- Configure a CI check or script to:
- List roles.
- Parse attached policies.
- Flag roles with
Action: "*",resource: "*", or infra-modifying APIs.
If you share a sample policy document or a specific role name/policy, I can provide an exact CLI sequence and a concrete “before/after” JSON policy tailored to your use case.
Using Python
Using Python
Below is a focused, step‑by‑step approach to remediating IAM roles that can modify infrastructure in AWS, using Python (boto3). I’ll assume you want to:
Make sure the credentials you use have permission to call
Run it:Export results to a file if needed.
5.1 Example: Replace
You’d construct
- Identify “risky” IAM roles (those with permissions to change infrastructure such as EC2, IAM, CloudFormation, etc.).
- Review and reduce their permissions.
- Enforce a least‑privilege pattern.
1. Preparation
Install and configure AWS + Python toolingiam:ListRoles, iam:ListAttachedRolePolicies, iam:ListRolePolicies, iam:GetPolicy, iam:GetPolicyVersion, iam:GetRolePolicy.2. Define What “Can Modify Infrastructure” Means
Typical infra‑modifying services (example, adjust as needed):ec2:*iam:*cloudformation:*lambda:*rds:*elasticloadbalancing:*autoscaling:*eks:*route53:*organizations:*s3:*(if modifying buckets that hold infra state, e.g., Terraform state)ssm:*(if used to push changes)logs:*andcloudtrail:*(if you want to protect logging infra)
*:*service:*(e.g.,ec2:*)- Specific mutating actions:
RunInstances,Create*,Update*,Delete*,Put*,Attach*,Detach*,Modify*,Set*, etc.
3. Python Script: Discover Risky IAM Roles
This script:- Lists all roles
- Retrieves attached managed policies
- Retrieves inline policies
- Parses policy documents
- Flags roles that can modify infrastructure
4. Analyze and Design Least‑Privilege Policies
For each flagged role:- Identify who/what uses the role (Lambda, EC2 instance profile, CI/CD, human, etc.).
- Get CloudTrail logs or service usage reports to know exactly which actions/resources are actually used.
- Use AWS Console: CloudTrail → Event history (filter by role ARN).
- Or Athena queries over CloudTrail logs to list actions used.
- Build a minimal policy:
- Restrict to specific actions actually required (e.g.,
ec2:DescribeInstances, notec2:*). - Restrict
Resourceto needed ARNs or patterns instead of"*"where possible. - Add conditions (e.g., limit by tag, region, or source IP if appropriate).
- Restrict to specific actions actually required (e.g.,
5. Remediate Policies via Python
5.1 Example: Replace AdministratorAccess with Custom Managed Policy
- Create a new least‑privilege managed policy.
- Attach it to the role.
- Detach the broad policy.
5.2 Example: Tighten Inline Policy
If a role has an inline policy that’s too broad, replace it with a stricter one.new_doc (least‑privilege) based on CloudTrail usage.6. Implement Guardrails (Optional but Recommended)
- Service Control Policies (SCPs) (in AWS Organizations):
- Deny dangerous infra‑modifying actions account‑wide except from designated roles.
- IAM permission boundaries:
- Ensure new roles cannot be given wider permissions than an approved “boundary” policy.
- Automated checks:
- Integrate the detection script into CI/CD.
- Fail builds or send alerts if a role is created/updated with infra‑modifying permissions outside a whitelist.
7. Practical Workflow Summary
- Run discovery script → list risky roles.
- Prioritize by sensitivity (production, admin, CI/CD).
- For each role:
- Review actual usage via CloudTrail.
- Design a minimal policy (actions + resources + conditions).
- Update the role via Python: create managed policy / update inline policy → detach/remove broad policies.
- Re‑run the discovery script to confirm the role no longer has broad infra‑modifying permissions.
- Add guardrails (SCPs, permission boundaries) to prevent regressions.
Using Terraform
Using Terraform
var.AWS_REGIONandvar.AWS_ACCOUNT_IDwith your variables or literals.INSTANCE_ID_1,INSTANCE_ID_2with the specific instance IDs the workload may manage.SECURITY_GROUP_IDwith the specific security group ID.APP_OWNED_BUCKET_NAMEwith the S3 bucket the workload owns.APP_INFRA_ROLE_NAMEwith the IAM role that should have this scoped infra-write access.
terraform plan should show:~(update in-place) for the existingaws_iam_policy(or a new+if you are introducing this policy for the first time).- No changes that recreate the IAM role, only attachment changes if you are switching from a previous broad policy to this scoped one.

