Using identity-based policies (IAM policies) for AWS Control Tower
This topic provides examples of identity-based policies that demonstrate how an account administrator can attach permissions policies to IAM identities (that is, users, groups, and roles) and thereby grant permissions to perform operations on AWS Control Tower resources.
Important
We recommend that you first review the introductory topics that explain the basic concepts and options available for you to manage access to your AWS Control Tower resources. For more information, see Overview of managing access permissions to your AWS Control Tower resources.
AWSControlTowerAdmin role
This role provides AWS Control Tower with access to infrastructure critical to maintaining
the landing zone. The AWSControlTowerAdmin
role requires an attached managed
policy and a role trust policy for the IAM role. A role
trust policy is a resource-based policy, specifying which principals
can assume the role.
Here's an example snippet for this role trust policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "controltower.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
To create this role from the AWS CLI, and put it into a file called trust.json
, here's an example CLI command:
aws iam create-role --role-name AWSControlTowerAdmin --path /service-role/ --assume-role-policy-document file://trust.json
This role requires two IAM policies.
An inline policy, for example:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:DescribeAvailabilityZones", "Resource": "*" } ] }
The managed policy that follows, which is the
AWSControlTowerServiceRolePolicy
.
AWSControlTowerServiceRolePolicy
The AWSControlTowerServiceRolePolicy is an AWS-managed policy that defines permissions to create and manage AWS Control Tower resources, such as AWS CloudFormation stacksets and stack instances, AWS CloudTrail log files, a configuration aggregator for AWS Control Tower, as well as AWS Organizations accounts and organizational units (OUs) that are governed by AWS Control Tower.
Updates to this managed policy are summarized in the table, Managed policies for AWS Control Tower.
For more information, see AWSControlTowerServiceRolePolicy
in the AWS Managed Policy Reference Guide.
Managed Policy Name: AWSControlTowerServiceRolePolicy
The JSON artifact for AWSControlTowerServiceRolePolicy
is the
following:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudformation:CreateStack", "cloudformation:CreateStackInstances", "cloudformation:CreateStackSet", "cloudformation:DeleteStack", "cloudformation:DeleteStackInstances", "cloudformation:DeleteStackSet", "cloudformation:DescribeStackInstance", "cloudformation:DescribeStacks", "cloudformation:DescribeStackSet", "cloudformation:DescribeStackSetOperation", "cloudformation:ListStackInstances", "cloudformation:UpdateStack", "cloudformation:UpdateStackInstances", "cloudformation:UpdateStackSet" ], "Resource": [ "arn:aws:cloudformation:*:*:type/resource/AWS-IAM-Role" ] }, { "Effect": "Allow", "Action": [ "account:EnableRegion", "account:ListRegions", "account:GetRegionOptStatus" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "cloudformation:CreateStack", "cloudformation:CreateStackInstances", "cloudformation:CreateStackSet", "cloudformation:DeleteStack", "cloudformation:DeleteStackInstances", "cloudformation:DeleteStackSet", "cloudformation:DescribeStackInstance", "cloudformation:DescribeStacks", "cloudformation:DescribeStackSet", "cloudformation:DescribeStackSetOperation", "cloudformation:GetTemplate", "cloudformation:ListStackInstances", "cloudformation:UpdateStack", "cloudformation:UpdateStackInstances", "cloudformation:UpdateStackSet" ], "Resource": [ "arn:aws:cloudformation:*:*:stack/AWSControlTower*/*", "arn:aws:cloudformation:*:*:stack/StackSet-AWSControlTower*/*", "arn:aws:cloudformation:*:*:stackset/AWSControlTower*:*", "arn:aws:cloudformation:*:*:stackset-target/AWSControlTower*/*" ] }, { "Effect": "Allow", "Action": [ "cloudtrail:CreateTrail", "cloudtrail:DeleteTrail", "cloudtrail:GetTrailStatus", "cloudtrail:StartLogging", "cloudtrail:StopLogging", "cloudtrail:UpdateTrail", "cloudtrail:PutEventSelectors", "logs:CreateLogStream", "logs:PutLogEvents", "logs:PutRetentionPolicy" ], "Resource": [ "arn:aws:logs:*:*:log-group:aws-controltower/CloudTrailLogs:*", "arn:aws:cloudtrail:*:*:trail/aws-controltower*" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::aws-controltower*/*" ] }, { "Effect": "Allow", "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::*:role/AWSControlTowerExecution", "arn:aws:iam::*:role/AWSControlTowerBlueprintAccess" ] }, { "Effect": "Allow", "Action": [ "cloudtrail:DescribeTrails", "ec2:DescribeAvailabilityZones", "iam:ListRoles", "logs:CreateLogGroup", "logs:DescribeLogGroups", "organizations:CreateAccount", "organizations:DescribeAccount", "organizations:DescribeCreateAccountStatus", "organizations:DescribeOrganization", "organizations:DescribeOrganizationalUnit", "organizations:DescribePolicy", "organizations:ListAccounts", "organizations:ListAccountsForParent", "organizations:ListAWSServiceAccessForOrganization", "organizations:ListChildren", "organizations:ListOrganizationalUnitsForParent", "organizations:ListParents", "organizations:ListPoliciesForTarget", "organizations:ListTargetsForPolicy", "organizations:ListRoots", "organizations:MoveAccount", "servicecatalog:AssociatePrincipalWithPortfolio" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:GetRole", "iam:GetUser", "iam:ListAttachedRolePolicies", "iam:GetRolePolicy" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::*:role/service-role/AWSControlTowerStackSetRole", "arn:aws:iam::*:role/service-role/AWSControlTowerCloudTrailRole", "arn:aws:iam::*:role/service-role/AWSControlTowerConfigAggregatorRoleForOrganizations" ] }, { "Effect": "Allow", "Action": [ "config:DeleteConfigurationAggregator", "config:PutConfigurationAggregator", "config:TagResource" ], "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/aws-control-tower": "managed-by-control-tower" } } }, { "Effect": "Allow", "Action": [ "organizations:EnableAWSServiceAccess", "organizations:DisableAWSServiceAccess" ], "Resource": "*", "Condition": { "StringLike": { "organizations:ServicePrincipal": [ "config.amazonaws.com", "cloudtrail.amazonaws.com" ] } } }, { "Effect": "Allow", "Action": "iam:CreateServiceLinkedRole", "Resource": "*", "Condition": { "StringEquals": { "iam:AWSServiceName": "cloudtrail.amazonaws.com" } } } ] }
Role trust policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "controltower.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
The inline policy is AWSControlTowerAdminPolicy
:
{ "Version": "2012-10-17", "Statement": [ { "Action": "ec2:DescribeAvailabilityZones", "Resource": "*", "Effect": "Allow" } ] }
AWSControlTowerStackSetRole
AWS CloudFormation assumes this role to deploy stack sets in accounts created by AWS Control Tower. Inline Policy:
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::*:role/AWSControlTowerExecution" ], "Effect": "Allow" } ] }
Trust policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudformation.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
AWSControlTowerCloudTrailRole
AWS Control Tower enables CloudTrail as a best practice and provides this role to CloudTrail. CloudTrail assumes this role to create and publish CloudTrail logs. Inline Policy:
{ "Version": "2012-10-17", "Statement": [ { "Action": "logs:CreateLogStream", "Resource": "arn:aws:logs:*:*:log-group:aws-controltower/CloudTrailLogs:*", "Effect": "Allow" }, { "Action": "logs:PutLogEvents", "Resource": "arn:aws:logs:*:*:log-group:aws-controltower/CloudTrailLogs:*", "Effect": "Allow" } ] }
Trust policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
AWSControlTowerBlueprintAccess role requirements
AWS Control Tower requires you to create the AWSControlTowerBlueprintAccess
role in the designated blueprint hub account, within the same organization.
Role name
The role name must be AWSControlTowerBlueprintAccess
.
Role trust policy
The role must be set up to trust the following principals:
-
The principal that uses AWS Control Tower in the management account.
-
The
AWSControlTowerAdmin
role in the management account.
The following example shows a least-privilege trust policy. When you make your own policy, replace the term YourManagementAccountId
with the actual acccount ID of your AWS Control Tower management account, and replace the term YourControlTowerUserRole
with the identifier of the IAM role for your management account.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::
YourManagementAccountId
:role/service-role/AWSControlTowerAdmin", "arn:aws:iam::YourManagementAccountId
:role/YourControlTowerUserRole
" ] }, "Action": "sts:AssumeRole", "Condition": {} } ] }
Role permissions
You are required to attach the managed policy AWSServiceCatalogAdminFullAccess to the role.
AWSServiceRoleForAWSControlTower
This role provides AWS Control Tower with access to the Log Archive account, Audit account, and member accounts, for operations critical to maintaining the landing zone, such as notifying you of drifted resources.
The AWSServiceRoleForAWSControlTower
role requires an attached
managed policy and a role trust policy for the IAM role.
Managed policy for this role:
AWSControlTowerAccountServiceRolePolicy
Role trust policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "controltower.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
AWSControlTowerAccountServiceRolePolicy
This AWS-managed policy allows AWS Control Tower to call AWS services that provide automated account configuration and centralized governance on your behalf.
The policy contains the minimum permissions for AWS Control Tower to implement AWS Security Hub findings forwarding for resources managed by Security Hub controls that are part of the Security Hub Service-managed Standard: AWS Control Tower, and it prevents changes that restrict the ability to manage customer accounts. It is part of background AWS Security Hub drift detection process that is not directly initiated by a customer.
The policy gives permissions to create Amazon EventBridge rules, specifically for Security Hub controls, in each member account, and these rules must specify an exact EventPattern. Also, a rule can operate only on rules managed by our service principal.
Service principal: controltower.amazonaws.com
The JSON artifact for AWSControlTowerAccountServiceRolePolicy
is the following:
{ "Version": "2012-10-17", "Statement": [ { //For creating the managed rule "Sid": "AllowPutRuleOnSpecificSourcesAndDetailTypes", "Effect": "Allow", "Action": "events:PutRule", "Resource": "arn:aws:events:*:*:rule/*ControlTower*", "Condition": { "ForAnyValue:StringEquals": { "events:source": "aws.securityhub" }, "Null": { "events:detail-type": "false" }, "StringEquals": { "events:ManagedBy": "controltower.amazonaws.com", "events:detail-type": "Security Hub Findings - Imported" } } }, // Other operations to manage the managed rule { "Sid": "AllowOtherOperationsOnRulesManagedByControlTower", "Effect": "Allow", "Action": [ "events:DeleteRule", "events:EnableRule", "events:DisableRule", "events:PutTargets", "events:RemoveTargets" ], "Resource": "arn:aws:events:*:*:rule/*ControlTower*", "Condition": { "StringEquals": { "events:ManagedBy": "controltower.amazonaws.com" } } }, // More managed rule permissions { "Sid": "AllowDescribeOperationsOnRulesManagedByControlTower", "Effect": "Allow", "Action": [ "events:DescribeRule", "events:ListTargetsByRule" ], "Resource": "arn:aws:events:*:*:rule/*ControlTower*" }, // Add permission to publish the security notifications to SNS { "Sid": "AllowControlTowerToPublishSecurityNotifications", "Effect": "Allow", "Action": "sns:publish", "Resource": "arn:aws:sns:*:*:aws-controltower-AggregateSecurityNotifications", "Condition": { "StringEquals": { "aws:PrincipalAccount": "${aws:ResourceAccount}" } } }, // For drift verification { "Sid": "AllowActionsForSecurityHubIntegration", "Effect": "Allow", "Action": [ "securityhub:DescribeStandardsControls", "securityhub:GetEnabledStandards" ], "Resource": "arn:aws:securityhub:*:*:hub/default" } ] }
Updates to this managed policy are summarized in the table, Managed policies for AWS Control Tower.