AWS Control Tower orchestrates multi-account governance by deploying a landing zone with guardrails (preventive, detective, proactive), Account Factory, and centralized logging. Compromising the management account or disabling controls grants unrestricted access across the entire organization.
A pre-configured, secure multi-account environment based on AWS best practices. Deploys a Security OU (with Log Archive and Audit accounts) and a user-named additional OU. Managed via the aws controltower API (28 subcommands covering controls, landing zones, baselines, and tagging).
Critical: The management account is exempt from all preventive controls (SCPs and RCPs). Any identity in this account can bypass every guardrail.
Three behavioral types enforce governance: Preventive (SCPs/RCPs), Detective (AWS Config rules), and Proactive (CloudFormation Hooks). Three guidance categories: Mandatory (always on), Strongly Recommended, and Elective.
Attack note: Disabling a detective control does not remediate existing non-compliant resources -- it simply stops detecting them.
Standardized account provisioning via AWS Service Catalog. Creates new accounts with the AWSControlTowerExecution role pre-installed. Account Factory for Terraform (AFT) extends this with IaC-based customization pipelines.
Attack note: The AWSControlTowerExecution role in every member account has AdministratorAccess and trusts the management account root principal with no conditions by default.
AWSControlTowerExecution -- Every member account, full admin access
AWSControlTowerAdmin -- Management account, creates Config aggregators
AWSControlTowerCloudTrailRole -- Management account, centralized CloudTrail
AWSControlTowerStackSetRole -- Management account, deploys StackSets
AuditAdministratorRole -- Audit account, Lambda-only cross-account admin
AuditReadOnlyRole -- Audit account, Lambda-only cross-account read-only
AWS Control Tower is the governance layer for the entire organization. Compromise of the management account means full admin access to every enrolled member account via the AWSControlTowerExecution role. Disabling controls removes guardrails organization-wide. Drift introduced by an attacker can disable security detection without triggering obvious alerts.
aws controltower list-landing-zonesaws controltower get-landing-zone \
--landing-zone-identifier arn:aws:controltower:us-east-1:123456789012:landingzone/LANDING_ZONE_IDaws controltower list-enabled-controls \
--target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyzaws controltower list-enabled-controls \
--target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyz \
--filter '{"driftStatuses":["DRIFTED"]}'aws controltower list-baselinesaws controltower list-enabled-baselinesaws organizations list-accounts \
--query 'Accounts[*].[Id,Name,Status]' \
--output tableaws organizations list-policies-for-target \
--target-id ou-xxxx-xxxxxxxx \
--filter SERVICE_CONTROL_POLICYKey insight: AWSControlTowerExecution in every member account has AdministratorAccess and trusts the management account root with no conditions by default.
aws sts assume-role \
--role-arn arn:aws:iam::MEMBER_ACCOUNT_ID:role/AWSControlTowerExecution \
--role-session-name ct-pivotaws controltower disable-control \
--control-identifier arn:aws:controltower:us-east-1::control/CONTROL_ID \
--target-identifier arn:aws:organizations::123456789012:ou/o-abc1234xyz/ou-abc-xyzaws controltower get-enabled-control \
--enabled-control-identifier arn:aws:controltower:us-east-1:123456789012:enabledcontrol/CONTROL_IDaws controltower list-enabled-baselines{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole"
}]
}Any identity in the management account with sts:AssumeRole and a wildcard resource policy can assume this role. No MFA, no IP restriction, no principal tag condition.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/team": "platform-engineering"
},
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}]
}Restricts role assumption to principals tagged as platform-engineering from a known IP range. Reduces blast radius of compromised management account credentials.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}]
}Allows assumption of AWSControlTowerExecution in every member account. This is the exact pattern that enables pivoting attacks.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/AWSControlTowerExecution"
}
]
}Applied as a Permissions Boundary to all IAM users, roles, and Identity Center Permission Sets in the management account. Prevents unauthorized pivoting to member accounts.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "ProtectControlTowerRoles",
"Effect": "Deny",
"Action": [
"iam:AttachRolePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:UpdateAssumeRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/AWSControlTowerExecution",
"arn:aws:iam::*:role/aws-controltower-*"
],
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/AWSControlTowerExecution"
}
}
}]
}Prevents member account identities from modifying or deleting Control Tower roles. Only AWSControlTowerExecution itself can modify these roles.
Run zero production workloads in the management account. Restrict it to Control Tower administration, Organizations management, and billing only. Apply strict identity controls: hardware MFA on root, minimal IAM users, and short-lived sessions via Identity Center.
Attach Permissions Boundaries to all IAM users, roles, and Identity Center Permission Sets that deny sts:AssumeRole against AWSControlTowerExecution.
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/AWSControlTowerExecution"Modify the trust policy on AWSControlTowerExecution in every member account to require specific principal tags, source IP ranges, or named principal ARNs. Must be reapplied after enrollment.
Do not rely only on mandatory controls. Enable all strongly recommended preventive and detective controls. Evaluate elective controls for your threat model.
Configure CloudTrail alerts via EventBridge for DisableControl, EnableControl, UpdateLandingZone, ResetLandingZone, DisableBaseline, and AWSControlTowerExecution role assumptions.
Deploy an SCP that denies modification or deletion of AWSControlTowerExecution and aws-controltower-* roles by member account identities.
Check landing zone drift status regularly. Enable auto-enrollment to remediate inheritance drift when accounts move between OUs. Alert on drift detection via SNS notifications.
aws controltower get-landing-zone --landing-zone-identifier LANDING_ZONE_ARNAWS Control Tower Security Card • Toc Consulting
Always obtain proper authorization before testing