Create Least Privilege Policies

Prerequisite: We recommend that you create a cross-account role manually or using CloudFormation before you create a policy.

As part of your account preparation, you will need to create IAM policies—identity-based policies that you will attach to a cross-account role, which will allow CloudCheckr to access the AWS data it needs to create its reports.

CloudCheckr has its own IAM policies known as least privilege policies, which are individual policies that represent each core area of functionality within our application:

  • Cost
  • Billing
  • Security/Compliance
  • Inventory
  • CloudTrail
  • CloudWatch Flow Logs

Although it may seem like one big policy would be easier to manage, separate policies ensure that whoever uses the cross-account role can only access the permissions they need to do their job.

This procedure will show you how to create the least-privileged policies in the AWS Management Console.


Procedure

  1. Login to the AWS Management Console.

    The AWS services page opens.

  2. Scroll down to the Security, Identity & Compliance section and select IAM.

    The Welcome to Identity and Access Management screen displays.

  3. From the dashboard, click Policies.

    A list of policies displays.

  4. Click Create policy.

    The Create Policy page opens.

    In the next step, you will learn how to create a least privilege policy, which is a separate JSON permissions policy document.

  5. For each least privilege policy that you want a cross-account role to have access to, follow these steps:
    1. Click a button to display the selected policy document.

      {  
      "Version":"2012-10-17",
      "Statement":[
      {
      "Sid":"CloudCheckrCostPermissions",
      "Effect":"Allow",
      "Action":[
      "ec2:DescribeAccountAttributes",
      "ec2:DescribeAvailabilityZones",
      "ec2:DescribeReservedInstancesOfferings",
      "ec2:DescribeReservedInstances",
      "ec2:DescribeReservedInstancesListings",
      "ec2:DescribeHostReservationOfferings",
      "ec2:DescribeReservedInstancesModifications",
      "ec2:DescribeHostReservations",
      "ec2:DescribeInstances",
      "ec2:DescribeInstanceStatus",
      "ec2:DescribeRegions",
      "ec2:DescribeKeyPairs",
      "ec2:DescribePlacementGroups",
      "ec2:DescribeAddresses",
      "ec2:DescribeSpotInstanceRequests",
      "ec2:DescribeImages",
      "ec2:DescribeImageAttribute",
      "ec2:DescribeSnapshots",
      "ec2:DescribeVolumes",
      "ec2:DescribeTags",
      "ec2:DescribeNetworkInterfaces",
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeInstanceAttribute",
      "ec2:DescribeVolumeStatus",
      "elasticache:DescribeReservedCacheNodes",
      "elasticache:DescribeReservedCacheNodesOfferings",
      "rds:DescribeReservedDBInstances",
      "rds:DescribeReservedDBInstancesOfferings",
      "rds:DescribeDBInstances",
      "redshift:DescribeReservedNodes",
      "redshift:DescribeReservedNodeOfferings",
      "s3:GetBucketACL",
      "s3:GetBucketLocation",
      "s3:GetBucketLogging",
      "s3:GetBucketPolicy",
      "s3:GetBucketTagging",
      "s3:GetBucketWebsite",
      "s3:GetBucketNotification",
      "s3:GetLifecycleConfiguration",
      "s3:GetNotificationConfiguration",
      "s3:List*",
      "dynamodb:DescribeReservedCapacity",
      "dynamodb:DescribeReservedCapacityOfferings",
      "iam:GetAccountAuthorizationDetails",
      "iam:ListRolePolicies",
      "iam:ListAttachedRolePolicies"
      ],
      "Resource":"*"
      }
      ]
      }

      {  
      "Version":"2012-10-17",
      "Statement":[
      {
      "Sid":"CostReadDBR",
      "Effect":"Allow",
      "Action":[
      "s3:GetBucketACL",
      "s3:GetBucketLocation",
      "s3:GetBucketLogging",
      "s3:GetBucketPolicy",
      "s3:GetBucketTagging",
      "s3:GetBucketWebsite",
      "s3:GetBucketNotification",
      "s3:GetLifecycleConfiguration",
      "s3:GetNotificationConfiguration",
      "s3:GetObject"
      ],
      "Resource":[
      "arn:aws:s3:::[YOUR DETAILED BILLING REPORT BUCKET]",
      "arn:aws:s3:::[YOUR DETAILED BILLING REPORT BUCKET]/*",
      "arn:aws:s3:::[YOUR COST AND USAGE REPORT BUCKET] (optional)",
      "arn:aws:s3:::[YOUR COST AND USAGE REPORT BUCKET]/* (optional)"
      ]
      }

      ]
      }

      {  
      "Version":"2012-10-17",
      "Statement":[
      {
      "Sid":"SecurityPermissons",
      "Effect":"Allow",
      "Action":[
      "acm:DescribeCertificate",
      "acm:ListCertificates",
      "acm:GetCertificate",
      "cloudtrail:DescribeTrails",
      "cloudtrail:GetTrailStatus",
      "logs:GetLogEvents",
      "logs:DescribeLogGroups",
      "logs:DescribeLogStreams",
      "config:DescribeConfigRules",
      "config:GetComplianceDetailsByConfigRule",
      "config:DescribeDeliveryChannels",
      "config:DescribeDeliveryChannelStatus",
      "config:DescribeConfigurationRecorders",
      "config:DescribeConfigurationRecorderStatus",
      "ec2:Describe*",
      "iam:Get*",
      "iam:List*",
      "iam:GenerateCredentialReport",
      "kms:DescribeKey",
      "kms:GetKeyPolicy",
      "kms:GetKeyRotationStatus",
      "kms:ListAliases",
      "kms:ListGrants",
      "kms:ListKeys",
      "kms:ListKeyPolicies",
      "kms:ListResourceTags",
      "rds:Describe*",
      "ses:ListIdentities",
      "ses:GetSendStatistics",
      "ses:GetIdentityDkimAttributes",
      "ses:GetIdentityVerificationAttributes",
      "ses:GetSendQuota",
      "sns:GetSnsTopic",
      "sns:GetTopicAttributes",
      "sns:GetSubscriptionAttributes",
      "sns:ListTopics",
      "sns:ListSubscriptionsByTopic",
      "sqs:ListQueues",
      "sqs:GetQueueAttributes"
      ],
      "Resource":"*"
      }
      ]
      }

      { 
      "Version": "2012-10-17",
      "Statement": [
      {
      "Sid": "InventoryAndUtilization",
      "Effect": "Allow",
      "Action": [
      "acm:DescribeCertificate",
      "acm:ListCertificates",
      "acm:GetCertificate",
      "ec2:Describe*",
      "ec2:GetConsoleOutput",
      "autoscaling:Describe*",
      "cloudformation:DescribeStacks",
      "cloudformation:GetStackPolicy",
      "cloudformation:GetTemplate",
      "cloudformation:ListStackResources",
      "cloudfront:List*",
      "cloudfront:GetDistributionConfig",
      "cloudfront:GetStreamingDistributionConfig",
      "cloudhsm:Describe*",
      "cloudhsm:List*",
      "cloudsearch:Describe*",
      "cloudtrail:DescribeTrails",
      "cloudtrail:GetTrailStatus",
      "cloudwatch:DescribeAlarms",
      "cloudwatch:GetMetricStatistics",
      "cloudwatch:ListMetrics",
      "cognito-identity:ListIdentities",
      "cognito-identity:ListIdentityPools",
      "cognito-idp:ListGroups",
      "cognito-idp:ListIdentityProviders",
      "cognito-idp:ListUserPools",
      "cognito-idp:ListUsers",
      "cognito-idp:ListUsersInGroup",
      "config:DescribeConfigRules",
      "config:GetComplianceDetailsByConfigRule",
      "config:Describe*",
      "datapipeline:ListPipelines",
      "datapipeline:GetPipelineDefinition",
      "datapipeline:DescribePipelines",
      "directconnect:DescribeLocations",
      "directconnect:DescribeConnections",
      "directconnect:DescribeVirtualInterfaces",
      "dynamodb:ListTables",
      "dynamodb:DescribeTable",
      "dynamodb:ListTagsOfResource",
      "ecs:ListClusters",

      "ecs:DescribeClusters",
      "ecs:ListContainerInstances",
      "ecs:DescribeContainerInstances",
      "ecs:ListServices",
      "ecs:DescribeServices",

      "ecs:ListTaskDefinitions",
      "ecs:DescribeTaskDefinition",
      "ecs:ListTasks",
      "ecs:DescribeTasks",
      "ssm:ListResourceDataSync",
      "ssm:ListAssociations",
      "ssm:ListDocumentVersions",
      "ssm:ListDocuments",
      "ssm:ListInstanceAssociations",
      "ssm:ListInventoryEntries",
      "elasticache:Describe*",
      "elasticache:List*",
      "elasticbeanstalk:Describe*",
      "elasticfilesystem:DescribeFileSystems",
      "elasticfilesystem:DescribeTags",
      "elasticloadbalancing:Describe*",
      "elasticmapreduce:Describe*",
      "elasticmapreduce:List*",
      "es:ListDomainNames",
      "es:DescribeElasticsearchDomains",
      "glacier:ListTagsForVault",
      "glacier:DescribeVault",
      "glacier:GetVaultNotifications",
      "glacier:DescribeJob",
      "glacier:GetJobOutput",
      "glacier:ListJobs",
      "glacier:ListVaults",
      "iam:Get*",
      "iam:List*",
      "iam:GenerateCredentialReport",
      "iot:DescribeThing",
      "iot:ListThings",
      "kms:DescribeKey",
      "kms:GetKeyPolicy",
      "kms:GetKeyRotationStatus",
      "kms:ListAliases",
      "kms:ListGrants",
      "kms:ListKeys",
      "kms:ListKeyPolicies",
      "kms:ListResourceTags",
      "kinesis:ListStreams",
      "kinesis:DescribeStream",
      "kinesis:GetShardIterator",
      "lambda:ListFunctions",
      "lambda:ListTags",
      "Organizations:List*",
      "Organizations:Describe*",
      "rds:Describe*",
      "rds:List*",
      "redshift:Describe*",
      "route53:ListHealthChecks",
      "route53:ListHostedZones",
      "route53:ListResourceRecordSets",
      "s3:GetBucketACL",
      "s3:GetBucketLocation",
      "s3:GetBucketLogging",
      "s3:GetBucketPolicy",

      "s3:GetBucketTagging",
      "s3:GetBucketWebsite",
      "s3:GetBucketNotification",
      "s3:GetEncryptionConfiguration",
      "s3:GetLifecycleConfiguration",
      "s3:GetNotificationConfiguration",
      "s3:List*",
      "sdb:ListDomains",
      "sdb:DomainMetadata",
      "ses:ListIdentities",
      "ses:GetSendStatistics",
      "ses:GetIdentityDkimAttributes",
      "ses:GetIdentityVerificationAttributes",
      "ses:GetSendQuota",
      "sns:GetSnsTopic",
      "sns:GetTopicAttributes",
      "sns:GetSubscriptionAttributes",
      "sns:ListTopics",
      "sns:ListSubscriptionsByTopic",
      "sqs:ListQueues",
      "sqs:GetQueueAttributes",
      "storagegateway:Describe*",
      "storagegateway:List*",
      "support:*",
      "swf:ListClosedWorkflowExecutions",
      "swf:ListDomains",
      "swf:ListActivityTypes",
      "swf:ListWorkflowTypes",
      "workspaces:DescribeWorkspaceDirectories",
      "workspaces:DescribeWorkspaceBundles",
      "workspaces:DescribeWorkspaces"
      ],
      "Resource": "*"
      }
      ]
      }

      {  
      "Version":"2012-10-17",
      "Statement":[
      {
      "Sid":"CloudTrailPermissions",
      "Effect":"Allow",
      "Action":[
      "s3:GetBucketACL",
      "s3:GetBucketLocation",
      "s3:GetBucketLogging",
      "s3:GetBucketPolicy",
      "s3:GetBucketTagging",
      "s3:GetBucketWebsite",
      "s3:GetBucketNotification",
      "s3:GetLifecycleConfiguration",
      "s3:GetNotificationConfiguration",
      "s3:GetObject",
      "s3:List*"
      ],
      "Resource":[
      "arn:aws:s3:::[YOUR CLOUDTRAIL BUCKET]",
      "arn:aws:s3:::[YOUR CLOUDTRAIL BUCKET]/*"
      ]
      }
      ]
      }

      {   
      "Version":"2012-10-17",
      "Statement":[
      {
      "Sid":"CloudWatchLogsSpecific",
      "Effect":"Allow",
      "Action":[
      "logs:GetLogEvents",
      "logs:DescribeLogGroups",
      "logs:DescribeLogStreams"
      ],
      "Resource":[
      "arn:aws:logs:*:*:*"
      ]
      }
      ]
      }
    2. Copy the entire contents of the policy document to your clipboard.
    3. Return to the Create Policy page in the AWS Management Console.
    4. Click the JSON tab.

      The JSON tab opens.
    5. Replace the text in the JSON tab with the policy you just copied.

      For any Billing and CloudTrail policies that you create, make sure that you replace the dummy S3 bucket name with the name of your S3 bucket where your Detailed Billing Report (DBR) or Cost Usage Report (CUR) will be stored. Here is an example from the Billing JSON file:

    6. Click Review policy.
      The Review policy page opens.
    7. Type a name for the policy and click Create policy.

      A message at the top of the policy page indicates that your policy has been created.

  6. Repeat step 5 for each least privilege policy you want to create.
  7. Continue to the next step in your account preparation: Enable Detailed Billing Reports.

How did we do?