Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Check for Overly Permissive IAM Group Policies

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: High (not acceptable risk)
Rule ID: IAM-069

Ensure that both managed and inline policies attached to your Amazon Identity and Access Management (IAM) groups are not too permissive. To adhere to IAM security best practices, all the policies configured for your Amazon IAM groups 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 perform successfully its tasks).

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.

Security

Providing the right permissions for your Amazon IAM groups will significantly reduce the risk of unauthorized access to your AWS cloud services and resources and help you manage identity-based access more efficiently.


Audit

To determine if your Amazon IAM group policies (both managed and inline policies) 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 User groups.

04 Click on the name of the Amazon IAM group that you want to examine.

05 Select the Permissions tab to access the identity–based policies attached to the selected group.

06 In the Permissions policies section, click on the name (link) of the policy attached to the IAM group.

07 Select the Permissions tab, choose {} JSON, and perform the following actions:

  1. 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 cloud resource(s) defined within the policy statement, therefore the selected IAM policy is too permissive.
  2. Find the "Action" element defined for each policy statement and check the element value. If the "Action" value is set to "iam:*", all Identity and Access Management (IAM) actions can be performed by the cloud resource(s) defined within the policy statement (i.e. full access to Amazon IAM), therefore the selected IAM policy is too permissive.
  3. 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 "*", the policy grants permissions to pass any IAM roles to AWS services, therefore the selected IAM policy is too permissive.
  4. 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 group.

09 Repeat steps no. 4 – 8 for each Amazon IAM group available within your AWS cloud account.

Using AWS CLI

01 Run list-groups command (OSX/Linux/UNIX) using custom query filters to list the names of all Amazon IAM groups available in your AWS account:

aws iam list-groups
  --output table
  --query 'Groups[*].GroupName'

02 The command output should return a table with the requested IAM group identifiers:

-----------------------------
|        ListGroups         |
+---------------------------+
|  cc-project5-user-group   |
|  cc-ec2-management-group  |
+---------------------------+

03 Run list-attached-group-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM group that you want to examine as identifier parameter and custom query filters to list the Amazon Resource Name (ARN) of each managed policy attached to the selected IAM group:

aws iam list-attached-group-policies
  --group-name cc-project5-user-group
  --query 'AttachedPolicies[*].PolicyArn'

04 The command output should return the ARN of each managed policy attached to the selected group:

[
    "arn:aws:iam::123456789012:policy/cc-iam-managed-access-policy"
]

05 Run get-policy-version command (OSX/Linux/UNIX) using the ARN of the IAM managed policy that you want to examine as identifier parameter and custom query filters 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-iam-managed-access-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:

  1. 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 cloud resource(s) defined within the policy statement, therefore the selected Amazon IAM managed policy is too permissive.
  2. Find the "Action" element defined for each statement and check the element value. If the "Action" value is set to "iam:*", all Identity and Access Management (IAM) actions can be performed by the resource(s) defined within the policy statement (i.e. full access to Amazon IAM service), therefore the selected IAM managed policy is too permissive.
  3. 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 "*", the policy grants permissions to pass any IAM roles to AWS services, therefore the selected IAM managed policy is too permissive.
  4. 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 group.

09 Run list-group-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM group 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 group:

aws iam list-group-policies
  --group-name cc-project5-user-group
  --query 'PolicyNames'

10 The command output should return the name of each inline policy associated with the selected group:

[
    "cc-project5-iam-group-policy"
]

11 Run get-group-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-group-policy
  --group-name cc-project5-user-group
  --policy-name cc-project5-iam-group-policy
  --query 'PolicyDocument'

12 The command output should return the requested inline policy document:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow",
            "Sid": "FullUserAccess"
        }
    ]
}

13 Perform the following actions for the get-group-policy command output:

  1. 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 cloud resource(s) defined within the policy statement, therefore the selected Amazon IAM inline policy is too permissive.
  2. Find the "Action" element defined for each statement and check the element value. If the "Action" value is set to "iam:*", all Identity and Access Management (IAM) actions can be performed by the resource(s) defined within the policy statement (i.e. full access to Amazon IAM service), therefore the selected IAM inline policy is too permissive.
  3. 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 "*", the policy grants permissions to pass any IAM roles to AWS services, therefore the selected IAM inline policy is too permissive.
  4. 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 group.

15 Repeat steps no. 3 – 14 for each Amazon IAM group created within your AWS cloud account.

Remediation / Resolution

To update your Amazon IAM group 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": {
    "IAMGroup": {
      "Type": "AWS::IAM::Group",
      "Properties": {
        "GroupName": "cc-project5-user-group",
        "Path": "/"
      }
    },
    "IAMManagedPolicy": {
      "Type": "AWS::IAM::ManagedPolicy",
      "Properties": {
        "Path": "/",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": [
                "acm:ListCertificates",
                "athena:List*",
                "autoscaling:Describe*",
                "batch:ListJobs",
                "cloudformation:List*",
                "cloudformation:DescribeStacks",
                "cloudfront:List*",
                "cloudsearch:List*",
                "cloudsearch:DescribeDomains",
                "cloudtrail:DescribeTrails",
                "cloudtrail:LookupEvents",
                "cloudwatch:List*",
                "cloudwatch:Get*",
                "config:List*",
                "config:Describe*",
                "dynamodb:DescribeBackup",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeGlobalTable",
                "dynamodb:DescribeGlobalTableSettings",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeReservedCapacity",
                "dynamodb:DescribeReservedCapacityOfferings",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:ListBackups",
                "dynamodb:ListGlobalTables",
                "dynamodb:ListStreams",
                "dynamodb:ListTables",
                "dynamodb:ListTagsOfResource",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeBundleTasks",
                "ec2:DescribeClassicLinkInstances",
                "ec2:DescribeConversionTasks",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeExportTasks",
                "ec2:DescribeFlowLogs",
                "ec2:DescribeHost*",
                "ec2:DescribeIdentityIdFormat",
                "ec2:DescribeIdFormat",
                "ec2:DescribeImage*",
                "ec2:DescribeImport*",
                "ec2:DescribeInstance*",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeMovingAddresses",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetwork*",
                "ec2:DescribePlacementGroups",
                "ec2:DescribePrefixLists",
                "ec2:DescribeRegions",
                "ec2:DescribeReserved*",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshot*",
                "ec2:DescribeSpot*",
                "ec2:DescribeSubnets",
                "ec2:DescribeTags",
                "ec2:DescribeVolume*",
                "ec2:DescribeVpc*",
                "ec2:DescribeVpnGateways",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecs:List*",
                "ecs:Describe*",
                "elasticache:Describe*",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticmapreduce:List*",
                "elastictranscoder:List*",
                "es:DescribeElasticsearchDomain",
                "es:DescribeElasticsearchDomains",
                "es:ListDomainNames",
                "events:ListRuleNamesByTarget",
                "events:ListRules",
                "events:ListTargetsByRule",
                "firehose:List*",
                "firehose:DescribeDeliveryStream",
                "gamelift:List*",
                "glacier:List*",
                "greengrass:List*",
                "iam:List*",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "importexport:ListJobs",
                "inspector:List*",
                "iot:List*",
                "kinesis:ListStreams",
                "kinesisanalytics:ListApplications",
                "kms:ListKeys",
                "lambda:List*",
                "rds:Describe*",
                "redshift:DescribeClusters",
                "redshift:DescribeEvents",
                "redshift:ViewQueriesInConsole",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "sagemaker:Describe*",
                "sagemaker:List*",
                "sdb:List*",
                "servicecatalog:List*",
                "ses:List*",
                "shield:List*",
                "states:ListActivities",
                "states:ListStateMachines",
                "sns:List*",
                "sqs:ListQueues",
                "ssm:ListAssociations",
                "ssm:ListDocuments",
                "swf:List*",
                "trustedadvisor:Describe*",
                "waf:List*",
                "waf-regional:List*",
                "wafv2:List*",
                "workdocs:DescribeAvailableDirectories",
                "workdocs:DescribeInstances",
                "workspaces:Describe*"
              ],
              "Effect": "Allow",
              "Resource": "*"
            }
          ]
        },
        "Groups": [
          "IAMGroup"
        ]
      }
    }
  }
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  IAMGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: cc-project5-user-group
      Path: /
  IAMManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Path: /
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action:
              - acm:ListCertificates
              - athena:List*
              - autoscaling:Describe*
              - batch:ListJobs
              - cloudformation:List*
              - cloudformation:DescribeStacks
              - cloudfront:List*
              - cloudsearch:List*
              - cloudsearch:DescribeDomains
              - cloudtrail:DescribeTrails
              - cloudtrail:LookupEvents
              - cloudwatch:List*
              - cloudwatch:Get*
              - config:List*
              - config:Describe*
              - dynamodb:DescribeBackup
              - dynamodb:DescribeContinuousBackups
              - dynamodb:DescribeGlobalTable
              - dynamodb:DescribeGlobalTableSettings
              - dynamodb:DescribeLimits
              - dynamodb:DescribeReservedCapacity
              - dynamodb:DescribeReservedCapacityOfferings
              - dynamodb:DescribeStream
              - dynamodb:DescribeTable
              - dynamodb:DescribeTimeToLive
              - dynamodb:ListBackups
              - dynamodb:ListGlobalTables
              - dynamodb:ListStreams
              - dynamodb:ListTables
              - dynamodb:ListTagsOfResource
              - ec2:DescribeAccountAttributes
              - ec2:DescribeAddresses
              - ec2:DescribeAvailabilityZones
              - ec2:DescribeBundleTasks
              - ec2:DescribeClassicLinkInstances
              - ec2:DescribeConversionTasks
              - ec2:DescribeCustomerGateways
              - ec2:DescribeDhcpOptions
              - ec2:DescribeExportTasks
              - ec2:DescribeFlowLogs
              - ec2:DescribeHost*
              - ec2:DescribeIdentityIdFormat
              - ec2:DescribeIdFormat
              - ec2:DescribeImage*
              - ec2:DescribeImport*
              - ec2:DescribeInstance*
              - ec2:DescribeInternetGateways
              - ec2:DescribeKeyPairs
              - ec2:DescribeMovingAddresses
              - ec2:DescribeNatGateways
              - ec2:DescribeNetwork*
              - ec2:DescribePlacementGroups
              - ec2:DescribePrefixLists
              - ec2:DescribeRegions
              - ec2:DescribeReserved*
              - ec2:DescribeRouteTables
              - ec2:DescribeSecurityGroups
              - ec2:DescribeSnapshot*
              - ec2:DescribeSpot*
              - ec2:DescribeSubnets
              - ec2:DescribeTags
              - ec2:DescribeVolume*
              - ec2:DescribeVpc*
              - ec2:DescribeVpnGateways
              - ecr:DescribeRepositories
              - ecr:ListImages
              - ecs:List*
              - ecs:Describe*
              - elasticache:Describe*
              - elasticloadbalancing:DescribeListeners
              - elasticloadbalancing:DescribeLoadBalancers
              - elasticloadbalancing:DescribeTargetGroups
              - elasticmapreduce:List*
              - elastictranscoder:List*
              - es:DescribeElasticsearchDomain
              - es:DescribeElasticsearchDomains
              - es:ListDomainNames
              - events:ListRuleNamesByTarget
              - events:ListRules
              - events:ListTargetsByRule
              - firehose:List*
              - firehose:DescribeDeliveryStream
              - gamelift:List*
              - glacier:List*
              - greengrass:List*
              - iam:List*
              - iam:GetAccountSummary
              - iam:GetLoginProfile
              - importexport:ListJobs
              - inspector:List*
              - iot:List*
              - kinesis:ListStreams
              - kinesisanalytics:ListApplications
              - kms:ListKeys
              - lambda:List*
              - rds:Describe*
              - redshift:DescribeClusters
              - redshift:DescribeEvents
              - redshift:ViewQueriesInConsole
              - s3:ListAllMyBuckets
              - s3:ListBucket
              - sagemaker:Describe*
              - sagemaker:List*
              - sdb:List*
              - servicecatalog:List*
              - ses:List*
              - shield:List*
              - states:ListActivities
              - states:ListStateMachines
              - sns:List*
              - sqs:ListQueues
              - ssm:ListAssociations
              - ssm:ListDocuments
              - swf:List*
              - trustedadvisor:Describe*
              - waf:List*
              - waf-regional:List*
              - wafv2:List*
              - workdocs:DescribeAvailableDirectories
              - workdocs:DescribeInstances
              - workspaces:Describe*
            Effect: Allow
            Resource: '*'
      Groups:
        - IAMGroup

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_group" "iam-group" {
  name = "cc-project5-user-group"
  path = "/"
}

resource "aws_iam_policy" "managed-policy" {
  name = "cc-iam-managed-access-policy"
  policy = jsonencode({
    "Version": "2012-10-17",
        "Statement": [
        {
            "Action": [
                "acm:ListCertificates",
                "athena:List*",
                "autoscaling:Describe*",
                "batch:ListJobs",
                "cloudformation:List*",
                "cloudformation:DescribeStacks",
                "cloudfront:List*",
                "cloudsearch:List*",
                "cloudsearch:DescribeDomains",
                "cloudtrail:DescribeTrails",
                "cloudtrail:LookupEvents",
                "cloudwatch:List*",
                "cloudwatch:Get*",
                "config:List*",
                "config:Describe*",
                "dynamodb:DescribeBackup",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeGlobalTable",
                "dynamodb:DescribeGlobalTableSettings",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeReservedCapacity",
                "dynamodb:DescribeReservedCapacityOfferings",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:ListBackups",
                "dynamodb:ListGlobalTables",
                "dynamodb:ListStreams",
                "dynamodb:ListTables",
                "dynamodb:ListTagsOfResource",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeBundleTasks",
                "ec2:DescribeClassicLinkInstances",
                "ec2:DescribeConversionTasks",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeExportTasks",
                "ec2:DescribeFlowLogs",
                "ec2:DescribeHost*",
                "ec2:DescribeIdentityIdFormat",
                "ec2:DescribeIdFormat",
                "ec2:DescribeImage*",
                "ec2:DescribeImport*",
                "ec2:DescribeInstance*",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeMovingAddresses",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetwork*",
                "ec2:DescribePlacementGroups",
                "ec2:DescribePrefixLists",
                "ec2:DescribeRegions",
                "ec2:DescribeReserved*",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshot*",
                "ec2:DescribeSpot*",
                "ec2:DescribeSubnets",
                "ec2:DescribeTags",
                "ec2:DescribeVolume*",
                "ec2:DescribeVpc*",
                "ec2:DescribeVpnGateways",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecs:List*",
                "ecs:Describe*",
                "elasticache:Describe*",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticmapreduce:List*",
                "elastictranscoder:List*",
                "es:DescribeElasticsearchDomain",
                "es:DescribeElasticsearchDomains",
                "es:ListDomainNames",
                "events:ListRuleNamesByTarget",
                "events:ListRules",
                "events:ListTargetsByRule",
                "firehose:List*",
                "firehose:DescribeDeliveryStream",
                "gamelift:List*",
                "glacier:List*",
                "greengrass:List*",
                "iam:List*",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "importexport:ListJobs",
                "inspector:List*",
                "iot:List*",
                "kinesis:ListStreams",
                "kinesisanalytics:ListApplications",
                "kms:ListKeys",
                "lambda:List*",
                "rds:Describe*",
                "redshift:DescribeClusters",
                "redshift:DescribeEvents",
                "redshift:ViewQueriesInConsole",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "sagemaker:Describe*",
                "sagemaker:List*",
                "sdb:List*",
                "servicecatalog:List*",
                "ses:List*",
                "shield:List*",
                "states:ListActivities",
                "states:ListStateMachines",
                "sns:List*",
                "sqs:ListQueues",
                "ssm:ListAssociations",
                "ssm:ListDocuments",
                "swf:List*",
                "trustedadvisor:Describe*",
                "waf:List*",
                "waf-regional:List*",
                "wafv2:List*",
                "workdocs:DescribeAvailableDirectories",
                "workdocs:DescribeInstances",
                "workspaces:Describe*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
     ]
  })
}

resource "aws_iam_group_policy_attachment" "group-policy-attach" {
  group = aws_iam_group.iam-group.name
  policy_arn = aws_iam_policy.managed-policy.arn
}

For inline IAM policies:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "IAMGroup": {
      "Type": "AWS::IAM::Group",
      "Properties": {
        "GroupName": "cc-project5-user-group",
        "Path": "/",
        "Policies": [
          {
            "PolicyName": "cc-project5-inline-policy",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "acm:ListCertificates",
                    "athena:List*",
                    "autoscaling:Describe*",
                    "batch:ListJobs",
                    "cloudformation:List*",
                    "cloudformation:DescribeStacks",
                    "cloudfront:List*",
                    "cloudsearch:List*",
                    "cloudsearch:DescribeDomains",
                    "cloudtrail:DescribeTrails",
                    "cloudtrail:LookupEvents",
                    "cloudwatch:List*",
                    "cloudwatch:Get*",
                    "config:List*",
                    "config:Describe*",
                    "dynamodb:DescribeBackup",
                    "dynamodb:DescribeContinuousBackups",
                    "dynamodb:DescribeGlobalTable",
                    "dynamodb:DescribeGlobalTableSettings",
                    "dynamodb:DescribeLimits",
                    "dynamodb:DescribeReservedCapacity",
                    "dynamodb:DescribeReservedCapacityOfferings",
                    "dynamodb:DescribeStream",
                    "dynamodb:DescribeTable",
                    "dynamodb:DescribeTimeToLive",
                    "dynamodb:ListBackups",
                    "dynamodb:ListGlobalTables",
                    "dynamodb:ListStreams",
                    "dynamodb:ListTables",
                    "dynamodb:ListTagsOfResource",
                    "ec2:DescribeAccountAttributes",
                    "ec2:DescribeAddresses",
                    "ec2:DescribeAvailabilityZones",
                    "ec2:DescribeBundleTasks",
                    "ec2:DescribeClassicLinkInstances",
                    "ec2:DescribeConversionTasks",
                    "ec2:DescribeCustomerGateways",
                    "ec2:DescribeDhcpOptions",
                    "ec2:DescribeExportTasks",
                    "ec2:DescribeFlowLogs",
                    "ec2:DescribeHost*",
                    "ec2:DescribeIdentityIdFormat",
                    "ec2:DescribeIdFormat",
                    "ec2:DescribeImage*",
                    "ec2:DescribeImport*",
                    "ec2:DescribeInstance*",
                    "ec2:DescribeInternetGateways",
                    "ec2:DescribeKeyPairs",
                    "ec2:DescribeMovingAddresses",
                    "ec2:DescribeNatGateways",
                    "ec2:DescribeNetwork*",
                    "ec2:DescribePlacementGroups",
                    "ec2:DescribePrefixLists",
                    "ec2:DescribeRegions",
                    "ec2:DescribeReserved*",
                    "ec2:DescribeRouteTables",
                    "ec2:DescribeSecurityGroups",
                    "ec2:DescribeSnapshot*",
                    "ec2:DescribeSpot*",
                    "ec2:DescribeSubnets",
                    "ec2:DescribeTags",
                    "ec2:DescribeVolume*",
                    "ec2:DescribeVpc*",
                    "ec2:DescribeVpnGateways",
                    "ecr:DescribeRepositories",
                    "ecr:ListImages",
                    "ecs:List*",
                    "ecs:Describe*",
                    "elasticache:Describe*",
                    "elasticloadbalancing:DescribeListeners",
                    "elasticloadbalancing:DescribeLoadBalancers",
                    "elasticloadbalancing:DescribeTargetGroups",
                    "elasticmapreduce:List*",
                    "elastictranscoder:List*",
                    "es:DescribeElasticsearchDomain",
                    "es:DescribeElasticsearchDomains",
                    "es:ListDomainNames",
                    "events:ListRuleNamesByTarget",
                    "events:ListRules",
                    "events:ListTargetsByRule",
                    "firehose:List*",
                    "firehose:DescribeDeliveryStream",
                    "gamelift:List*",
                    "glacier:List*",
                    "greengrass:List*",
                    "iam:List*",
                    "iam:GetAccountSummary",
                    "iam:GetLoginProfile",
                    "importexport:ListJobs",
                    "inspector:List*",
                    "iot:List*",
                    "kinesis:ListStreams",
                    "kinesisanalytics:ListApplications",
                    "kms:ListKeys",
                    "lambda:List*",
                    "rds:Describe*",
                    "redshift:DescribeClusters",
                    "redshift:DescribeEvents",
                    "redshift:ViewQueriesInConsole",
                    "s3:ListAllMyBuckets",
                    "s3:ListBucket",
                    "sagemaker:Describe*",
                    "sagemaker:List*",
                    "sdb:List*",
                    "servicecatalog:List*",
                    "ses:List*",
                    "shield:List*",
                    "states:ListActivities",
                    "states:ListStateMachines",
                    "sns:List*",
                    "sqs:ListQueues",
                    "ssm:ListAssociations",
                    "ssm:ListDocuments",
                    "swf:List*",
                    "trustedadvisor:Describe*",
                    "waf:List*",
                    "waf-regional:List*",
                    "wafv2:List*",
                    "workdocs:DescribeAvailableDirectories",
                    "workdocs:DescribeInstances",
                    "workspaces:Describe*"
                  ],
                  "Effect": "Allow",
                  "Resource": "*"
                }
              ]
            }
          }
        ]
      }
    }
  }
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  IAMGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: cc-project5-user-group
      Path: /
      Policies:
        - PolicyName: cc-project5-inline-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - acm:ListCertificates
                  - athena:List*
                  - autoscaling:Describe*
                  - batch:ListJobs
                  - cloudformation:List*
                  - cloudformation:DescribeStacks
                  - cloudfront:List*
                  - cloudsearch:List*
                  - cloudsearch:DescribeDomains
                  - cloudtrail:DescribeTrails
                  - cloudtrail:LookupEvents
                  - cloudwatch:List*
                  - cloudwatch:Get*
                  - config:List*
                  - config:Describe*
                  - dynamodb:DescribeBackup
                  - dynamodb:DescribeContinuousBackups
                  - dynamodb:DescribeGlobalTable
                  - dynamodb:DescribeGlobalTableSettings
                  - dynamodb:DescribeLimits
                  - dynamodb:DescribeReservedCapacity
                  - dynamodb:DescribeReservedCapacityOfferings
                  - dynamodb:DescribeStream
                  - dynamodb:DescribeTable
                  - dynamodb:DescribeTimeToLive
                  - dynamodb:ListBackups
                  - dynamodb:ListGlobalTables
                  - dynamodb:ListStreams
                  - dynamodb:ListTables
                  - dynamodb:ListTagsOfResource
                  - ec2:DescribeAccountAttributes
                  - ec2:DescribeAddresses
                  - ec2:DescribeAvailabilityZones
                  - ec2:DescribeBundleTasks
                  - ec2:DescribeClassicLinkInstances
                  - ec2:DescribeConversionTasks
                  - ec2:DescribeCustomerGateways
                  - ec2:DescribeDhcpOptions
                  - ec2:DescribeExportTasks
                  - ec2:DescribeFlowLogs
                  - ec2:DescribeHost*
                  - ec2:DescribeIdentityIdFormat
                  - ec2:DescribeIdFormat
                  - ec2:DescribeImage*
                  - ec2:DescribeImport*
                  - ec2:DescribeInstance*
                  - ec2:DescribeInternetGateways
                  - ec2:DescribeKeyPairs
                  - ec2:DescribeMovingAddresses
                  - ec2:DescribeNatGateways
                  - ec2:DescribeNetwork*
                  - ec2:DescribePlacementGroups
                  - ec2:DescribePrefixLists
                  - ec2:DescribeRegions
                  - ec2:DescribeReserved*
                  - ec2:DescribeRouteTables
                  - ec2:DescribeSecurityGroups
                  - ec2:DescribeSnapshot*
                  - ec2:DescribeSpot*
                  - ec2:DescribeSubnets
                  - ec2:DescribeTags
                  - ec2:DescribeVolume*
                  - ec2:DescribeVpc*
                  - ec2:DescribeVpnGateways
                  - ecr:DescribeRepositories
                  - ecr:ListImages
                  - ecs:List*
                  - ecs:Describe*
                  - elasticache:Describe*
                  - elasticloadbalancing:DescribeListeners
                  - elasticloadbalancing:DescribeLoadBalancers
                  - elasticloadbalancing:DescribeTargetGroups
                  - elasticmapreduce:List*
                  - elastictranscoder:List*
                  - es:DescribeElasticsearchDomain
                  - es:DescribeElasticsearchDomains
                  - es:ListDomainNames
                  - events:ListRuleNamesByTarget
                  - events:ListRules
                  - events:ListTargetsByRule
                  - firehose:List*
                  - firehose:DescribeDeliveryStream
                  - gamelift:List*
                  - glacier:List*
                  - greengrass:List*
                  - iam:List*
                  - iam:GetAccountSummary
                  - iam:GetLoginProfile
                  - importexport:ListJobs
                  - inspector:List*
                  - iot:List*
                  - kinesis:ListStreams
                  - kinesisanalytics:ListApplications
                  - kms:ListKeys
                  - lambda:List*
                  - rds:Describe*
                  - redshift:DescribeClusters
                  - redshift:DescribeEvents
                  - redshift:ViewQueriesInConsole
                  - s3:ListAllMyBuckets
                  - s3:ListBucket
                  - sagemaker:Describe*
                  - sagemaker:List*
                  - sdb:List*
                  - servicecatalog:List*
                  - ses:List*
                  - shield:List*
                  - states:ListActivities
                  - states:ListStateMachines
                  - sns:List*
                  - sqs:ListQueues
                  - ssm:ListAssociations
                  - ssm:ListDocuments
                  - swf:List*
                  - trustedadvisor:Describe*
                  - waf:List*
                  - waf-regional:List*
                  - wafv2:List*
                  - workdocs:DescribeAvailableDirectories
                  - workdocs:DescribeInstances
                  - workspaces:Describe*
                Effect: Allow
                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_group_policy" "iam-group-policy" {
  name  = "cc-project5-iam-group-policy"
  group = aws_iam_group.iam-group.name
  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "acm:ListCertificates",
                "athena:List*",
                "autoscaling:Describe*",
                "batch:ListJobs",
                "cloudformation:List*",
                "cloudformation:DescribeStacks",
                "cloudfront:List*",
                "cloudsearch:List*",
                "cloudsearch:DescribeDomains",
                "cloudtrail:DescribeTrails",
                "cloudtrail:LookupEvents",
                "cloudwatch:List*",
                "cloudwatch:Get*",
                "config:List*",
                "config:Describe*",
                "dynamodb:DescribeBackup",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeGlobalTable",
                "dynamodb:DescribeGlobalTableSettings",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeReservedCapacity",
                "dynamodb:DescribeReservedCapacityOfferings",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:ListBackups",
                "dynamodb:ListGlobalTables",
                "dynamodb:ListStreams",
                "dynamodb:ListTables",
                "dynamodb:ListTagsOfResource",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeBundleTasks",
                "ec2:DescribeClassicLinkInstances",
                "ec2:DescribeConversionTasks",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeExportTasks",
                "ec2:DescribeFlowLogs",
                "ec2:DescribeHost*",
                "ec2:DescribeIdentityIdFormat",
                "ec2:DescribeIdFormat",
                "ec2:DescribeImage*",
                "ec2:DescribeImport*",
                "ec2:DescribeInstance*",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeMovingAddresses",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetwork*",
                "ec2:DescribePlacementGroups",
                "ec2:DescribePrefixLists",
                "ec2:DescribeRegions",
                "ec2:DescribeReserved*",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshot*",
                "ec2:DescribeSpot*",
                "ec2:DescribeSubnets",
                "ec2:DescribeTags",
                "ec2:DescribeVolume*",
                "ec2:DescribeVpc*",
                "ec2:DescribeVpnGateways",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecs:List*",
                "ecs:Describe*",
                "elasticache:Describe*",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticmapreduce:List*",
                "elastictranscoder:List*",
                "es:DescribeElasticsearchDomain",
                "es:DescribeElasticsearchDomains",
                "es:ListDomainNames",
                "events:ListRuleNamesByTarget",
                "events:ListRules",
                "events:ListTargetsByRule",
                "firehose:List*",
                "firehose:DescribeDeliveryStream",
                "gamelift:List*",
                "glacier:List*",
                "greengrass:List*",
                "iam:List*",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "importexport:ListJobs",
                "inspector:List*",
                "iot:List*",
                "kinesis:ListStreams",
                "kinesisanalytics:ListApplications",
                "kms:ListKeys",
                "lambda:List*",
                "rds:Describe*",
                "redshift:DescribeClusters",
                "redshift:DescribeEvents",
                "redshift:ViewQueriesInConsole",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "sagemaker:Describe*",
                "sagemaker:List*",
                "sdb:List*",
                "servicecatalog:List*",
                "ses:List*",
                "shield:List*",
                "states:ListActivities",
                "states:ListStateMachines",
                "sns:List*",
                "sqs:ListQueues",
                "ssm:ListAssociations",
                "ssm:ListDocuments",
                "swf:List*",
                "trustedadvisor:Describe*",
                "waf:List*",
                "waf-regional:List*",
                "wafv2:List*",
                "workdocs:DescribeAvailableDirectories",
                "workdocs:DescribeInstances",
                "workspaces:Describe*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
     ]
  })
}

resource "aws_iam_group" "iam-group" {
  name = "cc-project5-user-group"
  path = "/"
}

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 User groups.

04 Click on the name of the Amazon IAM group that you want to reconfigure.

05 Select the Permissions tab to access the identity–based policies attached to the selected group.

06 In the Permissions policies section, perform the following actions based on the policy type:

  1. For managed IAM policies (AWS-managed and customer-managed policies):
    • Select the overly permissive policy and choose Remove to detach the non-compliant IAM policy from the selected IAM group.
    • In the Remove <policy-name>? confirmation box, choose Delete.
    • Choose Add permissions and select Attach policies to attach managed IAM policies to the selected group. Select one or more IAM policies from the Other permission policies list based on your group 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 group. Choose Add permissions to confirm your action.
  2. For inline IAM policies:
    • Click on the name of the overly permissive policy to edit the inline policy embedded within the selected IAM group.
    • Select the JSON tab and customize the policy document according to your IAM group 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 group. 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 group users to view your EC2 instances and AMIs. Or pass a specific, compliant IAM role to AWS 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 changes.

07 Repeat steps no. 4 – 6 for each Amazon IAM group 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 group, and save the policy document to a JSON file named cc-iam-policy-document.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 groups. To adhere to cloud security best practices, the new IAM policy should implement the Principle of Least Privilege (POLP) and provide the users within the IAM group the minimal set of permissions required to perform successfully their tasks. For example, the following IAM policy grants permissions to the users within your IAM group to view resources and basic metadata across all supported AWS services. The users cannot read resource content or metadata that goes beyond the quota and list information for resources. This policy provides view-only access to your AWS cloud account and it is useful to consultants or contractors that need to examine your cloud environment without being able to read content or change anything:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "acm:ListCertificates",
                "athena:List*",
                "autoscaling:Describe*",
                "batch:ListJobs",
                "cloudformation:List*",
                "cloudformation:DescribeStacks",
                "cloudfront:List*",
                "cloudsearch:List*",
                "cloudsearch:DescribeDomains",
                "cloudtrail:DescribeTrails",
                "cloudtrail:LookupEvents",
                "cloudwatch:List*",
                "cloudwatch:Get*",
                "config:List*",
                "config:Describe*",
                "dynamodb:DescribeBackup",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeGlobalTable",
                "dynamodb:DescribeGlobalTableSettings",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeReservedCapacity",
                "dynamodb:DescribeReservedCapacityOfferings",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:ListBackups",
                "dynamodb:ListGlobalTables",
                "dynamodb:ListStreams",
                "dynamodb:ListTables",
                "dynamodb:ListTagsOfResource",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeBundleTasks",
                "ec2:DescribeClassicLinkInstances",
                "ec2:DescribeConversionTasks",
                "ec2:DescribeCustomerGateways",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeExportTasks",
                "ec2:DescribeFlowLogs",
                "ec2:DescribeHost*",
                "ec2:DescribeIdentityIdFormat",
                "ec2:DescribeIdFormat",
                "ec2:DescribeImage*",
                "ec2:DescribeImport*",
                "ec2:DescribeInstance*",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeMovingAddresses",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetwork*",
                "ec2:DescribePlacementGroups",
                "ec2:DescribePrefixLists",
                "ec2:DescribeRegions",
                "ec2:DescribeReserved*",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshot*",
                "ec2:DescribeSpot*",
                "ec2:DescribeSubnets",
                "ec2:DescribeTags",
                "ec2:DescribeVolume*",
                "ec2:DescribeVpc*",
                "ec2:DescribeVpnGateways",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecs:List*",
                "ecs:Describe*",
                "elasticache:Describe*",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticmapreduce:List*",
                "elastictranscoder:List*",
                "es:DescribeElasticsearchDomain",
                "es:DescribeElasticsearchDomains",
                "es:ListDomainNames",
                "events:ListRuleNamesByTarget",
                "events:ListRules",
                "events:ListTargetsByRule",
                "firehose:List*",
                "firehose:DescribeDeliveryStream",
                "gamelift:List*",
                "glacier:List*",
                "greengrass:List*",
                "iam:List*",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "importexport:ListJobs",
                "inspector:List*",
                "iot:List*",
                "kinesis:ListStreams",
                "kinesisanalytics:ListApplications",
                "kms:ListKeys",
                "lambda:List*",
                "rds:Describe*",
                "redshift:DescribeClusters",
                "redshift:DescribeEvents",
                "redshift:ViewQueriesInConsole",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "sagemaker:Describe*",
                "sagemaker:List*",
                "sdb:List*",
                "servicecatalog:List*",
                "ses:List*",
                "shield:List*",
                "states:ListActivities",
                "states:ListStateMachines",
                "sns:List*",
                "sqs:ListQueues",
                "ssm:ListAssociations",
                "ssm:ListDocuments",
                "swf:List*",
                "trustedadvisor:Describe*",
                "waf:List*",
                "waf-regional:List*",
                "wafv2:List*",
                "workdocs:DescribeAvailableDirectories",
                "workdocs:DescribeInstances",
                "workspaces:Describe*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

02 Depending on whether you need to update an Amazon IAM managed policy or an inline policy, execute one of the following commands:

  1. If the policy attached to your IAM group 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-policy-document.json) to create a new and compliant version of the attached IAM 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-iam-managed-access-policy" and makes it the default version:
    aws iam create-policy-version
      --policy-arn arn:aws:iam::123456789012:policy/cc-iam-managed-access-policy
      --policy-document file://cc-iam-policy-document.json
      --set-as-default
    
  2. The command output should return the metadata of the new managed policy version:
    {
        "PolicyVersion": {
            "CreateDate": "2020-12-18T10:00:00Z",
            "VersionId": "v2",
            "IsDefaultVersion": true
        }
    }
    
  3. If the policy associated with your Amazon IAM group is an inline policy, run put-group-policy command (OSX/Linux/UNIX) using the policy document created at the previous step (i.e. cc-iam-policy-document.json) to update the permissions of the selected IAM inline policy. The following command request example updates an IAM group inline policy named "cc-project5-iam-group-policy" (the command does not produce an output):
    aws iam put-group-policy
      --group-name cc-project5-user-group
      --policy-name cc-project5-iam-group-policy
      --policy-document file://cc-iam-policy-document.json
    

03 Repeat steps no. 1 and 2 to change permissions for other overly permissive IAM policies associated with the selected Amazon IAM group.

04 Repeat steps no. 1 – 3 for each IAM group that you want to reconfigure, available within your AWS cloud account.

References

Publication date Dec 30, 2020