- Knowledge Base
- Amazon Web Services
- AWS Identity and Access Management (IAM)
- IAM Role Policy Too Permissive
Ensure that the policies attached to your Amazon IAM roles are not too permissive. To adhere to IAM security best practices, the policies configured for your IAM roles should implement the Principle of Least Privilege (also known as the principle of least authority, i.e. the security concept of providing every identity, process, or system the minimal set of permissions required to successfully perform its tasks).
This rule can help you with the following compliance standards:
- APRA
- MAS
- NIST4
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
Providing the right permissions for your Amazon IAM roles will significantly reduce the risk of unauthorized access to your AWS cloud services and resources.
Audit
Case A: To determine if the identity-based policies (both managed and inline policies) attached to your IAM roles are too permissive, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
03 In the navigation panel, under Access management, choose Roles.
04 Click on the name of the Amazon IAM role that you want to examine.
05 Select the Permissions tab to access the identity-based policies attached to the selected role.
06 In the Permissions policies section, click on the Expand button (right arrow icon) available next to each managed/inline policy, and choose {} JSON to show the policy document in JSON format.
07 Within the {} JSON policy document box, perform the following actions:
- Identify the "Action" element defined for each statement and check the element value. If the "Action" element value is set to "*", all the supported actions can be performed by the AWS cloud resource(s) defined within the policy statement, therefore the selected IAM policy is too permissive.
- Find the "Action" element defined for each policy statement and check the element value. If the "Action" value is set to "iam:*", all the Identity and Access Management (IAM) actions can be performed by the AWS resource(s) defined within the policy statement (i.e. full access to Amazon IAM), therefore the selected IAM policy is too permissive.
- Identify the "Action" and "Resource" elements defined for each policy statement, and check their values. If the "Action" element value contains "iam:PassRole" and the "Resource" element value is set to "*" or ends with a wildcard character (*), the policy allows the role to pass other IAM role(s) to the associated EC2 instance, therefore the selected IAM policy is too permissive.
- The "NotAction" policy element used in combination with "Effect": "Allow" often provides more privileges than desired. Search for "NonAction" elements defined within the selected policy document. If the document contains one or more "NonAction" elements used in combination with "Effect": "Allow", the selected Amazon IAM policy is too permissive.
08 Repeat step no. 6 and 7 to verify permissions for other IAM policies attached to the selected IAM role.
09 Repeat steps no. 4 – 8 for each Amazon IAM role available within your AWS cloud account.
Using AWS CLI
01 Run list-roles command (OSX/Linux/UNIX) with custom query filters to list the names of all Amazon IAM roles available in your AWS account:
aws iam list-roles --output table --query 'Roles[*].RoleName'
02 The command output should return a table with the requested IAM role identifiers:
------------------------------ | ListRoles | +----------------------------+ | cc-project5-manager-role | | cc-s3-data-customer-role | | cc-cloudwatch-view-role | +----------------------------+
03 Run list-attached-role-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM role that you want to examine as the identifier parameter and custom query filters to list the Amazon Resource Name (ARN) of each managed policy attached to the selected IAM role:
aws iam list-attached-role-policies --role-name cc-project5-manager-role --query 'AttachedPolicies[*].PolicyArn'
04 The command output should return the ARN of each managed policy attached to the selected role:
[ "arn:aws:iam::123456789012:policy/cc-project5-managed-policy" ]
05 Run get-policy-version command (OSX/Linux/UNIX) using the ARN of the IAM managed policy that you want to examine as the identifier parameter and custom filtering to describe the policy document (JSON format) defined for the selected policy version:
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/cc-project5-managed-policy --version-id v1 --query 'PolicyVersion.Document'
06 The command output should return the requested IAM policy document:
{ "Version": "2012-10-17", "Statement": [ { "Action": "*", "Resource": "*", "Effect": "Allow" } ] }
07 Analyze the get-policy-version command output by performing the following actions:
- Identify the "Action" element defined for each policy statement and check the element value. If the "Action" element value is set to "*", all the supported actions can be performed by the AWS cloud resource(s) defined within the policy statement, therefore the selected Amazon IAM managed policy is too permissive.
- Find the "Action" element defined for each statement and check the element value. If the "Action" value is set to "iam:*", all the Identity and Access Management (IAM) actions can be performed by the AWS resource(s) defined within the policy statement (i.e. full access to Amazon IAM service), therefore the selected IAM managed policy is too permissive.
- Identify the "Action" and "Resource" elements defined for each statement and check their values. If the "Action" element value contains "iam:PassRole" and the "Resource" element value is set to "*" or ends with a wildcard character (*), the policy allows the role to pass other IAM role(s) to the associated EC2 instance, therefore the selected IAM policy is too permissive.
- The "NotAction" policy element used in combination with "Effect": "Allow" often provides more privileges than desired. Search for "NonAction" elements defined in the selected policy document. If the document contains one or more "NonAction" elements used in combination with "Effect": "Allow", the selected IAM managed policy is too permissive.
08 Repeat steps no. 5 – 7 to verify permissions for other managed policies attached to the selected IAM role.
09 Run list-role-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM role that you want to examine as the identifier parameter and custom filtering to describe the name of each inline policy attached to the selected IAM role:
aws iam list-role-policies --role-name cc-project5-manager-role --query 'PolicyNames'
10 The command output should return the name of each inline policy associated with the selected role:
[ "cc-project5-inline-policy" ]
11 Run get-role-policy command (OSX/Linux/UNIX) using the name of the IAM inline policy that you want to examine as the identifier parameter and custom query filters to describe the policy document (JSON format) defined for the selected inline policy:
aws iam get-role-policy --role-name cc-project5-manager-role --policy-name cc-project5-inline-policy --query 'PolicyDocument'
12 The command output should return the requested inline policy document:
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "*" ], "Resource": [ "*" ], "Effect": "Allow", "Sid": "FullAccess" } ] }
13 Perform the following actions for the get-role-policy command output:
- Identify the "Action" element defined for each policy statement and check the element value. If the "Action" element value is set to "*", all the supported actions can be performed by the AWS resource(s) defined within the policy statement, therefore the selected Amazon IAM inline policy is too permissive.
- Find the "Action" element defined for each statement and check the element value. If the "Action" value is set to "iam:*", all the Identity and Access Management (IAM) actions can be performed by the AWS resource(s) defined within the policy statement (i.e. full access to Amazon IAM service), therefore the selected IAM inline policy is too permissive.
- Identify the "Action" and "Resource" elements defined for each statement and check their values. If the "Action" element value contains "iam:PassRole" and the "Resource" element value is set to "*" or ends with a wildcard character (*), the policy allows the role to pass other IAM role(s) to the associated EC2 instance, therefore the selected IAM policy is too permissive.
- The "NotAction" policy element used in combination with "Effect": "Allow" often provides more privileges than desired. Search for "NonAction" elements defined within the selected policy document. If the document contains one or more "NonAction" elements used in combination with "Effect": "Allow", the selected IAM inline policy is too permissive.
14 Repeat steps no. 11 – 13 to check permissions for other inline policies embedded within the selected IAM role.
15 Repeat steps no. 3 – 14 for each Amazon IAM role created within your AWS cloud account.
Case B: To determine if the trust relationship policies configured for your IAM roles allow "sts:AssumeRole" from anyone, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
03 In the navigation panel, under Access management, choose Roles.
04 Click on the name of the Amazon IAM role that you want to examine.
05 Select the Trust relationships tab and choose Edit trust relationship to access the trust relationship policy configured for the selected role.
06 On the Edit Trust Relationship page, in the Policy Document section, identify the "Action" and "Principal" elements and their values. If the "Action" element value is set to "sts:AssumeRole" and the "Principal" element value is set to { "AWS": "*" }, anyone (any IAM entity) can assume the IAM role, therefore the trust relationship policy configured for the selected IAM role is too permissive.
07 Repeat steps no. 4 – 6 for each Amazon IAM role available within your AWS cloud account.
Using AWS CLI
01 Run list-roles command (OSX/Linux/UNIX) with custom query filters to list the names of all Amazon IAM roles available in your AWS account:
aws iam list-roles --output table --query 'Roles[*].RoleName'
02 The command output should return a table with the requested IAM role identifiers:
------------------------------ | ListRoles | +----------------------------+ | cc-project5-manager-role | | cc-s3-data-customer-role | | cc-cloudwatch-view-role | +----------------------------+
03 Run get-role command (OSX/Linux/UNIX) using the name of the Amazon IAM role that you want to examine as the identifier parameter and custom query filters to describe the trust relationship policy configured for the selected IAM role:
aws iam get-role --role-name cc-project5-manager-role --query 'Role.AssumeRolePolicyDocument'
04 The command output should return the requested trust relationship policy:
{ "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "AWS": "*" } } ] }
Identify the "Action" and "Principal" elements values within the policy document returned by the get-role command output. If the "Action" element value is set to "sts:AssumeRole" and the "Principal" element value is set to { "AWS": "*" }, anyone can assume the IAM role, therefore the trust relationship policy configured for the selected IAM role is too permissive.
05 Repeat steps no. 3 and 4 for each Amazon IAM role available in your AWS cloud account.
Remediation / Resolution
Case A: To update your Amazon IAM role permissions through IAM policies in order to implement the Principle of Least Privilege (POLP), perform the following operations:
For managed IAM policies:Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "IAMRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "cc-project5-manager-role", "Description": "Project Manager Access", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Path": "/" } }, "RolePolicy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "cc-project5-managed-policy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "*" ] } ] }, "Roles": [ { "Ref": "IAMRole" } ] } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: IAMRole: Type: AWS::IAM::Role Properties: RoleName: cc-project5-manager-role Description: Project Manager Access AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / RolePolicy: Type: AWS::IAM::Policy Properties: PolicyName: cc-project5-managed-policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:* Resource: - '*' Roles: - !Ref 'IAMRole'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_role" "iam-role" { name = "cc-project5-manager-role" path = "/" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF managed_policy_arns = [aws_iam_policy.cc-project5-managed-policy.arn] } resource "aws_iam_policy" "cc-project5-managed-policy" { name = "cc-project5-managed-policy" policy = jsonencode({ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "*" ] } ] }) }
For inline IAM policies:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "IAMRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "cc-project5-manager-role", "Description": "Project Manager Access", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "cc-project5-inline-policy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "*" ] } ] } } ] } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: IAMRole: Type: AWS::IAM::Role Properties: RoleName: cc-project5-manager-role Description: Project Manager Access AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: cc-project5-inline-policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:* Resource: - '*'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_role" "iam-role" { name = "cc-project5-manager-role" path = "/" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF inline_policy { name = "cc-project5-inline-policy" policy = jsonencode({ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "*" ] } ] }) } }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
03 In the navigation panel, under Access management, choose Roles.
04 Click on the name of the Amazon IAM role that you want to reconfigure.
05 Select the Permissions tab to access the identity-based policies attached to the selected role.
06 IIn the Permissions policies section, perform the following actions based on the policy type:
- For managed IAM policies (AWS-managed and customer-managed policies):
- Click on the x (detach) icon to detach the overly permissive policy from the selected IAM role.
- Inside the Detach policy confirmation box, choose Detach to confirm the action.
- Choose Attach policies to attach managed IAM policies to the selected role. Select one or more IAM policies from the Attach Permissions list based on your role access requirements. Follow the Principle of Least Privilege (the security concept of providing every identity the minimal set of permissions required to perform successfully its tasks) when selecting the managed policies to attach to your IAM role. Choose Attach policy to confirm your action.
- For inline IAM policies:
- Choose the overly permissive inline policy embedded within the selected IAM role, click on the Expand button (right arrow icon), and select Edit policy.
- Select the JSON tab and customize the policy document according to your IAM role access requirements. Follow the Principle of Least Privilege (the security concept of providing every identity the minimal set of permissions required to perform successfully its tasks) when editing the inline policy associated with to your IAM role. For example, replace the "Action" element value "*" with specific Amazon EC2 service actions such as "ec2:DescribeInstances" and "ec2:DescribeImages" if you want your IAM role to grant permission to describe one or more EC2 instances and AMIs. Or pass a specific and compliant IAM role to AWS cloud services when "Action" is set to "iam:PassRole".
- Choose Review policy to review the inline policy before you save your changes.
- Choose Save changes to apply the permission changes.
07 Repeat steps no. 4 – 6 for each Amazon IAM role that you want to reconfigure, available in your AWS cloud account.
Using AWS CLI
01 Define the new identity–based policy that will replace the overly permissive policy associated with your Amazon IAM role, and save the policy document to a JSON file named cc-iam-role-policy.json. You can update the existing, overly permissive policies, with the appropriate permissions, or you can use the AWS Policy Generator available at https://awspolicygen.s3.amazonaws.com/policygen.html to build custom policies for your IAM roles. To adhere to AWS cloud security best practices, the new identity-based IAM policy should implement the Principle of Least Privilege (POLP) and provide the minimal set of permissions required to perform successfully the desired tasks. For example, the following IAM policy grants administrative permissions for Amazon S3 to applications running on the associated EC2 instance:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "*" ] } ] }
02 Depending on whether you need to update a managed IAM policy or an inline IAM policy, execute one of the following sets of commands:
- If the policy attached to your IAM role is a managed policy, run create-policy-version command (OSX/Linux/UNIX) using the policy document created at the previous step (i.e. cc-iam-role-policy.json) to create a new and compliant version of the attached managed policy. The following command request example creates a new version of an IAM managed policy identified by the ARN "arn:aws:iam::123456789012:policy/cc-project5-managed-policy" and makes it the default version:
aws iam create-policy-version --policy-arn arn:aws:iam::123456789012:policy/cc-project5-managed-policy --policy-document file://cc-iam-role-policy.json --set-as-default
- The command output should return the metadata of the new managed policy version:
{ "PolicyVersion": { "CreateDate": "2020-12-18T10:00:00Z", "VersionId": "v2", "IsDefaultVersion": true } }
- If the policy associated with your Amazon IAM role is an inline policy, run put-role-policy command (OSX/Linux/UNIX) using the policy document created at the previous step (i.e. cc-iam-role-policy.json) to update the permissions of the selected inline policy. The following command request example updates an inline IAM policy named "cc-project5-inline-policy" (the command does not produce an output):
aws iam put-role-policy --role-name cc-project5-manager-role --policy-name cc-project5-inline-policy --policy-document file://cc-iam-role-policy.json
03 Repeat steps no. 1 and 2 to change permissions for other overly permissive IAM policies associated with the selected Amazon IAM role.
04 Repeat steps no. 1 – 3 for each IAM role that you want to reconfigure, available in your AWS cloud account.
Case B: To update the trust relationship policies configured for your IAM roles in order to implement the Principle of Least Privilege (POLP), perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Implement the Principle of Least Privilege for IAM Role Trust Policy", "Resources": { "IAMRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "cc-ec2-manager", "Description": "Full Access to Amazon EC2", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AmazonEC2FullAccess" ], "Path": "/" } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Implement the Principle of Least Privilege for IAM Role Trust Policy Resources: IAMRole: Type: AWS::IAM::Role Properties: RoleName: cc-ec2-manager Description: Full Access to Amazon EC2 AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEC2FullAccess Path: /
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_role" "iam-role" { name = "cc-ec2-manager" path = "/" managed_policy_arns = [ "arn:aws:iam::aws:policy/AmazonEC2FullAccess" ] # Implement the Principle of Least Privilege for IAM Role Trust Policy assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
03 In the navigation panel, under Access management, choose Roles.
04 Click on the name of the Amazon IAM role that you want to reconfigure.
05 Select the Trust relationships tab and choose Edit trust relationship to access the trust relationship policy configured for the selected role.
06 On the Edit Trust Relationship page, in the Policy Document section, replace the "Principal" element value with an AWS trusted entity such as the Amazon EC2 service (i.e. "Service": "ec2.amazonaws.com"). Choose Update Trust Policy to apply the changes. The specified AWS entity will assume the selected role.
07 Repeat steps no. 4 – 6 for each Amazon IAM role that you want to reconfigure available within your AWS cloud account.
Using AWS CLI
01 Modify the associated trust relationship policy and replace the "Principal" element value with an AWS trusted entity that can assume the selected IAM role, such as the Amazon EC2 service, then save the policy document to a JSON file named cc-trust-policy.json. The following policy example describes a trust relationship policy that allows the Amazon EC2 service to assume the IAM role:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
02 Run update-assume-role-policy command (OSX/Linux/UNIX) using the name of the Amazon IAM role that you want to reconfigure as the identifier parameter, to update the trust relationship policy configured for the selected IAM role with the policy defined at the previous step (i.e. cc-trust-policy.json):
aws iam update-assume-role-policy --role-name cc-project5-manager-role --policy-document file://cc-trust-policy.json
03 Repeat steps no. 1 and 2 for each Amazon IAM role that you want to reconfigure available in your AWS cloud account.
References
- AWS Documentation
- Security best practices in IAM
- IAM Roles for Amazon EC2
- Modifying a Role
- IAM JSON policy elements reference
- Validating IAM policies
- AWS Policy Generator
- AWS Command Line Interface (CLI) Documentation
- iam
- list-roles
- list-attached-role-policies
- get-policy-version
- list-role-policies
- get-role-policy
- get-role
- create-policy-version
- put-role-policy
- update-assume-role-policy
- CloudFormation Documentation:
- AWS Identity and Access Management resource type reference
- Terraform Documentation:
- AWS Provider