Skip to main content
cd ../config-traps
risk/register/aws-scps-dont-restrict-root-sessions-by-default.html
AWS Organizations Governancecritical severityAWS Organizations

AWS SCPs Don't Restrict Root Sessions by Default

Severity
critical
Reviewed
20 Jul 2026
Remediation
~20 minutes
Overview

A missing explicit deny on aws:PrincipalType Root lets root sessions in member accounts execute unrestricted API calls, and the management account root sits entirely outside SCP enforcement, so a single credential recovery leaves AWS Organizations with no working guardrail.

Operational summary

At a glance

Symptom
A member account root session, recovered or phished via the account email and phone flow, calls an unrestricted API such as organizations:LeaveOrganization or cloudtrail:StopLogging.
Likely cause
Root OU SCPs contain no Deny statement conditioned on aws:PrincipalType Root, and the management account has no root credential hardening.
Impact
Root can detach accounts from the organization, delete CloudTrail trails and disable GuardDuty before any IAM-scoped alerting has a chance to fire.
Verification signal
Re-run the detection test and a controlled negative-path test.
Safe correction
Attach an explicit Deny SCP scoped to aws:PrincipalType Root at the Root OU and enforce hardware MFA with no access keys on the management account root user.
Rollback or recovery
Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

The Trap

Service Control Policies attached to the Organizations Root OU without an explicit Deny statement conditioned on aws:PrincipalType equalling Root. Teams assume the standard FullAWSAccess baseline SCP, layered with a handful of preventive Deny SCPs targeting services, automatically constrains root sessions the same way it constrains IAM users and roles. It does not, because AWS evaluates SCPs against the principal type, and Allow statements never restrict anything on their own.

The Default State

Landing zone deployments attach FullAWSAccess to the Root OU by default and layer service-scoped Deny SCPs beneath it, but almost none of those Deny statements include a Condition block matching aws:PrincipalType: “Root”. Separately, and structurally rather than as a misconfiguration, AWS never applies any SCP to the organization’s management account, regardless of where that SCP sits in the hierarchy. Engineers who verify SCP coverage against member accounts often extrapolate that coverage upward and stop hardening the management account root user, leaving it with no MFA device registered and, occasionally, live access keys.

The Blast Radius

Root is the only principal SCPs are specifically designed to constrain in member accounts, because IAM policies cannot touch root at all. Without a scoped Deny, a phished or account-recovery-hijacked root session in a member account can call organizations:LeaveOrganization to detach itself from central logging and SCP enforcement, run cloudtrail:StopLogging or cloudtrail:DeleteTrail to blind the security team, and call guardduty:DeleteDetector to remove detection entirely, all before any IAM-based alerting fires. In the management account, none of this even requires bypassing an SCP, because no SCP was ever in scope: a compromised management account root session has unconditional control over every linked account, every SCP, and every StackSet.

The Lead Mechanic Fix

Attach a Deny SCP at the Root OU with a Condition block: {“Effect”:”Deny”,”Action”:[“organizations:LeaveOrganization”,”cloudtrail:StopLogging”,”cloudtrail:DeleteTrail”,”guardduty:DeleteDetector”,”iam:DeleteAccountPasswordPolicy”],”Resource”:”*”,”Condition”:{“StringEquals”:{“aws:PrincipalType”:”Root”}}}. Enforce a hardware MFA device on the management account root user, delete any root access keys, and configure the centralised root access feature in IAM so member account root sign-in requires management account approval. Add an EventBridge rule matching CloudTrail’s userIdentity.type Root against RootAccountUsage to page on-call immediately, since this is the only account where an SCP cannot save you.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Control to implement

Attach an explicit Deny SCP scoped to aws:PrincipalType Root at the Root OU and enforce hardware MFA with no access keys on the management account root user.

Validate the vendor-specific syntax in official documentation before applying it.

04

Verify, roll back or escalate

Verify

Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.

Rollback

Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources