5.1.3. Multi-Account Security: Organizations and SCPs
💡 First Principle: In a multi-account organization, account-level guardrails are more reliable than per-account IAM policies. An SCP (Service Control Policy) applied at the organizational level is in effect for every account in the OU — even if someone creates a new IAM user with AdministratorAccess, the SCP prevents actions it doesn't allow. This makes SCPs the highest-leverage security control in a multi-account environment.
AWS Organizations Structure:
SCPs — What They Do and Don't Do:
| SCP Fact | Detail |
|---|---|
| Applied to | OUs and accounts (not the management account) |
| Effect | Restrict maximum permissions — even AdministratorAccess is bounded by SCPs |
| Do NOT grant | Permissions — only restrict |
| Affect | All principals in the account (IAM users, roles, root user) |
| Do NOT affect | Management account (SCPs have no effect there) |
| Default SCP | FullAWSAccess — allows everything; restricts nothing |
| Inheritance | An action must be allowed by the SCPs at every level: root, each OU on the path, and the account. The effective result is the intersection, so an SCP on a child OU cannot re-allow a service that a parent SCP leaves out |
| Deny list vs. allow list | Deny list (the default strategy): keep FullAWSAccess attached and add SCPs that Deny specific actions. Allow list: remove FullAWSAccess and attach SCPs that Allow only the approved services |
Common SCP Patterns:
| Goal | SCP Approach |
|---|---|
| Prevent disabling CloudTrail | Deny cloudtrail:StopLogging, cloudtrail:DeleteTrail |
| Restrict to approved regions | Deny all actions with Condition: aws:RequestedRegion NotIn [approved list] |
| Prevent leaving the organization | Deny organizations:LeaveOrganization |
| Require encryption | Deny s3:PutObject without s3:x-amz-server-side-encryption condition |
| Require encrypted EBS volumes | Deny ec2:CreateVolume and ec2:RunInstances (volume resource) when ec2:Encrypted is false, and Deny ec2:DisableEbsEncryptionByDefault so the account-level default stays on |
| Prevent root user actions | Deny the restricted actions with Condition: StringLike aws:PrincipalArn = arn:aws:iam::*:root (applies to member-account root users) |
Tag conditions: aws:RequestTag/<key> matches tags passed in the request (for example, tags applied as a resource is created). aws:ResourceTag/<key> (or a service form such as ec2:ResourceTag/<key>) matches tags already on the resource being acted on. An action on an existing resource (stopping, modifying or deleting it) carries no request tags, so a condition written with the request-tag key never matches it.
AWS Control Tower builds on Organizations to provide a landing zone — a pre-configured, multi-account AWS environment following best practices. Control Tower:
- Creates the account structure (Management, Log Archive, Audit accounts)
- Deploys SCPs (guardrails) automatically
- Enrolls new accounts via Account Factory
- Provides a compliance dashboard showing guardrail status
Guardrail Types:
| Type | Behavior |
|---|---|
| Preventive | SCP-based; prevents non-compliant actions |
| Detective | Config rule-based; detects and reports non-compliance |
| Mandatory | Always enabled; cannot be disabled |
| Elective | Optional; enabled per OU |
⚠️ Exam Trap: SCPs only affect member accounts — the management account is immune to SCPs. This is why AWS recommends keeping minimal resources in the management account. If an SCP denies ec2:RunInstances for an OU, member accounts can't launch EC2 instances — but the management account can. Also, SCPs must be enabled in Organizations (they're not active by default — you must enable "All features" in Organizations, which replaces the default "Consolidated billing only" mode).
Reflection Question: A company wants to ensure that no AWS resources can be created outside of us-east-1 and eu-west-1 across all accounts in their organization. What type of control do you implement, where do you attach it, and what condition key restricts the allowed regions?