AWS Organizations: Multi-Account Governance and SCPs
A comprehensive guide to AWS Organizations: Multi-Account Governance and SCPs on AWS, covering core concepts, configuration, best practices, and real-world use cases..
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
- ✓Basic understanding of AWS services and cloud computing concepts.
AWS Organizations: Multi-Account Governance and SCPs is like having a smart assistant that handles the heavy lifting so you don't have to manage servers yourself.
You're managing 50 AWS accounts manually. One engineer accidentally grants full S3 access to a production account. That's not a security incident—it's a Tuesday. AWS Organizations exists to prevent this chaos by letting you govern accounts at scale. Forget 'best practices'—this is about survival. Without Organizations, you're one misconfigured IAM policy away from a breach. The real power? Service Control Policies (SCPs) that act as a permission guardrail, not a suggestion. They can block actions even from the root user. Yes, you read that right. In this article, we'll dissect how to structure accounts, apply SCPs like a pro, and avoid the pitfalls that cost companies millions.
Why Multi-Account Governance Matters
In production environments, a single AWS account is a liability. It creates a single blast radius, makes cost allocation impossible, and violates the principle of least privilege. AWS Organizations solves this by providing a hierarchical structure to manage multiple accounts under a single governance umbrella. The key is to treat accounts as security boundaries: each account should host a single application, environment, or business unit. This isolation limits the impact of a breach and simplifies compliance audits. Without Organizations, you end up with manual IAM role management, inconsistent policies, and no centralized logging. The cost of not adopting multi-account governance is measured in incident response hours and failed audits. Start by defining your organizational units (OUs) based on workload sensitivity and compliance requirements. For example, separate OUs for production, staging, development, and security tooling. This structure allows you to apply different guardrails via Service Control Policies (SCPs) at the OU level, ensuring that even if an admin has full access to a child account, they cannot violate organization-wide rules.
Organizational Units: Designing Your Hierarchy
Organizational Units (OUs) are the backbone of policy inheritance. Design your OU tree to reflect your security and compliance needs, not your org chart. Common patterns include: (1) Environment-based: Production, Staging, Development, Sandbox. (2) Workload-based: PCI, HIPAA, Internal. (3) Business unit-based: Engineering, Finance, Marketing. The best practice is a hybrid: top-level OUs for environment, then sub-OUs for compliance tiers. For example, Production/PCI, Production/Non-PCI. This allows you to apply broad SCPs at the environment level (e.g., deny all non-encrypted EBS volumes) and stricter SCPs at the compliance level (e.g., deny access to non-approved regions). Avoid deep nesting beyond 5 levels as it becomes hard to debug policy inheritance. Use tags to add metadata, but don't rely on them for security decisions. Remember that SCPs apply to all accounts in the OU, including the management account if you enable that (not recommended). Always test SCPs on a small OU first using the SCP testing feature or by creating a test account.
Service Control Policies: The Guardrails
Service Control Policies (SCPs) are JSON policies that define the maximum permissions for accounts in an OU. They are not IAM policies; they are boundary policies that restrict what IAM policies can allow. Think of them as a safety net: even if an IAM policy grants full access, an SCP can deny specific actions. SCPs can be either allow lists or deny lists. Deny lists are easier to start with: you deny specific high-risk actions (e.g., deleting CloudTrail trails, disabling AWS Config, modifying VPC flow logs) across all accounts. Allow lists are more restrictive: you explicitly allow only certain services and deny everything else. Most production environments use a hybrid: a base deny list for all accounts, then allow lists for specific OUs. For example, deny all accounts from leaving the organization, deleting backup vaults, or modifying SCPs themselves. Always include a statement to deny access to the management account from child accounts. SCPs are evaluated before IAM policies, so they can't be overridden by account admins. They apply to all principals in the account, including root users. Test SCPs using the AWS Organizations policy testing feature or by creating a test account in a sandbox OU.
Writing Effective SCPs: Allow Lists vs. Deny Lists
The choice between allow lists and deny lists depends on your risk tolerance and operational complexity. Deny lists are simpler: you block known bad actions and let everything else through. They are easier to maintain because you only add new denies as threats emerge. However, they can miss novel attack vectors. Allow lists are more secure: you explicitly permit only the services and actions required for business operations. They require deep knowledge of each workload's needs and are harder to maintain. In practice, most organizations use a deny list for the root OU (e.g., deny leaving organization, deny disabling logging) and allow lists for sensitive OUs like PCI. When writing SCPs, avoid using broad wildcards like "Action": "*" unless you fully understand the implications. Use conditions to scope policies, such as "aws:RequestedRegion" to restrict regions, or "aws:SourceIp" to limit access to corporate IP ranges. Remember that SCPs cannot grant permissions; they only set boundaries. Always test SCPs on a small set of accounts before rolling out broadly. Use the AWS Organizations policy testing feature to simulate the effective permissions for a principal.
SCP Inheritance and Evaluation Logic
SCPs are inherited from the root OU down to child OUs and accounts. If you attach an SCP to the root, it applies to all accounts in the organization. If you attach an SCP to an OU, it applies to that OU and all its children. The effective SCP for an account is the union of all SCPs attached to its parent OUs and the account itself. However, the evaluation is not additive; it's a logical AND of all allows and OR of all denies. Specifically, an action is allowed only if there is at least one allow statement and no deny statement across all applicable SCPs. This means that a single deny in any SCP blocks the action, even if another SCP allows it. This is why deny lists are powerful: one deny statement in the root SCP can block an action across the entire organization. To debug SCP issues, use the AWS Organizations policy testing feature or the IAM policy simulator. Remember that SCPs do not affect the management account unless you explicitly enable that (not recommended). Also, SCPs apply to all IAM users, roles, and the root user in child accounts. They cannot be overridden by account admins.
Automating Account Creation and Baseline Configuration
Manual account creation is error-prone and slow. Automate it using AWS Organizations APIs, AWS CloudFormation, or Terraform. The typical workflow: (1) Create the account via Organizations API. (2) Move it to the appropriate OU. (3) Apply baseline SCPs. (4) Provision initial resources like a VPC, CloudTrail, and AWS Config. Use AWS Control Tower for a managed solution, but be aware of its opinionated defaults. For custom automation, use a combination of AWS Lambda and Step Functions. For example, a Lambda function triggered by an SNS topic can create the account, wait for it to be ready, then apply SCPs and launch a CloudFormation stack. Ensure that the automation itself is protected by SCPs to prevent tampering. Also, automate the removal of accounts: when an account is no longer needed, close it via the Organizations API and clean up any resources. Store account metadata (e.g., owner, cost center) in a DynamoDB table or AWS Organizations tags. This automation reduces the time to provision a new account from days to minutes.
Monitoring and Auditing SCP Compliance
SCPs are only effective if you monitor their enforcement. Use AWS CloudTrail to log all API calls, including SCP changes. Set up CloudWatch Events (or EventBridge) to trigger alerts when an SCP is modified or when an account attempts a denied action. For example, create a rule that sends an SNS notification when an SCP is attached or detached. Also, use AWS Config rules to evaluate resources against your SCPs. For instance, a Config rule can check that all S3 buckets have encryption enabled, which aligns with your SCP that denies unencrypted buckets. However, Config rules are reactive; SCPs are preventive. Use both for defense in depth. Regularly review SCP effectiveness by running the IAM policy simulator across all accounts. Generate a report of actions that are allowed but should be denied, and vice versa. Use AWS Organizations' policy testing feature to simulate changes before applying them. Finally, audit account compliance with your OU structure: ensure accounts are in the correct OU and that no account has been moved to a less restrictive OU without approval.
Common Pitfalls and How to Avoid Them
Even experienced teams make mistakes with SCPs. Here are the top pitfalls: (1) Attaching SCPs to the management account: This can lock out the root user. Never attach SCPs to the management account unless you have a break-glass procedure. (2) Overly permissive SCPs: Using "Effect": "Allow" with "Action": "*" on the root OU effectively disables SCPs. Always use deny lists or specific allow lists. (3) Not testing SCPs: Always test on a non-production OU first. Use the policy simulator to verify effects. (4) Ignoring service-linked roles: Some AWS services create service-linked roles that require specific actions. Denying those actions can break the service. For example, denying "iam:PassRole" can break Lambda functions. (5) Forgetting about the root user: SCPs apply to the root user in child accounts. If you deny all actions, the root user cannot even access the billing console. (6) Not documenting SCPs: Without documentation, teams forget why a policy exists and may request its removal. Maintain a changelog and rationale for each SCP. (7) Not planning for exceptions: Sometimes a workload needs a temporary exception. Have a process to grant time-limited exceptions via a separate OU or by detaching the SCP for a short period.
Advanced SCP Techniques: Conditions and Resource Restrictions
SCPs support conditions that allow fine-grained control. Use global condition keys like "aws:RequestedRegion" to restrict which regions can be used. For example, deny all actions outside of us-east-1 and eu-west-1. Use "aws:SourceIp" to restrict API calls to corporate IP ranges. Use "aws:PrincipalArn" to apply different policies to different roles. You can also use resource-level restrictions: for example, deny deleting specific S3 buckets that contain logs. However, SCPs cannot use IAM tags as conditions (that's a limitation). Another advanced technique is to use SCPs to enforce encryption: deny creating unencrypted EBS volumes or S3 buckets. Combine SCPs with AWS Config to detect violations that SCPs miss. For example, an SCP can deny creating an unencrypted bucket, but if a bucket was created before the SCP, Config can remediate it. Also, use SCPs to enforce the use of instance metadata service version 2 (IMDSv2) by denying ec2:RunInstances without the condition that requires IMDSv2. This is a powerful way to harden EC2 instances.
Integrating SCPs with CI/CD Pipelines
SCPs can be managed as code using Infrastructure as Code (IaC) tools like Terraform or AWS CloudFormation. Store SCPs in a Git repository and use CI/CD pipelines to deploy them. This ensures version control, peer review, and automated testing. For example, a GitHub Actions workflow can validate SCP syntax, simulate the policy against a set of test accounts, and then deploy to the organization. Use tools like cfn-lint or terraform validate to catch errors early. Also, integrate SCP deployment with your change management process: require approvals for changes to production OUs. When deploying SCPs, use a canary approach: first apply to a test OU, verify no breakage, then roll out to broader OUs. Automate the rollback: if a CloudWatch alarm triggers after deployment, automatically revert the SCP change. This is critical because a bad SCP can block all operations in an account. Remember that SCPs are global; a mistake can affect hundreds of accounts. Treat SCPs as critical infrastructure code.
Disaster Recovery and Break-Glass Procedures
Even with SCPs, you need a plan for when things go wrong. The most critical scenario is losing access to the management account. To mitigate, create a break-glass IAM role in the management account that is not subject to SCPs (since SCPs don't apply to the management account by default). Store the credentials securely, e.g., in a password manager with multi-person approval. Also, have a secondary administrator account in a different AWS organization? No, that's not possible. Instead, use AWS Support's account recovery process, but that can take hours. Better: enable AWS Organizations delegated administrator for a trusted account that can manage SCPs. This account can detach a problematic SCP. Also, regularly test your break-glass procedure. Another scenario: an SCP accidentally denies critical actions like CloudTrail or Config. Have a monitoring system that alerts if those services stop working. If an SCP breaks a production workload, the fastest recovery is to detach the SCP from the OU. Automate this: have a Lambda function that can detach a specific SCP from an OU when triggered by a CloudWatch alarm. Document the process and practice it in a non-production environment.
Future-Proofing Your Multi-Account Strategy
AWS Organizations and SCPs are evolving. Keep an eye on new features like AWS Organizations delegated administrator for more services, and the ability to apply SCPs to the management account (use with caution). Also, consider using AWS Control Tower for a managed landing zone, but be aware that it imposes its own SCPs and guardrails. For large organizations, consider using AWS Organizations with AWS Single Sign-On (SSO) for centralized identity management. This allows you to assign permissions based on groups and enforce SCPs at the same time. Another trend is using SCPs to enforce the use of ephemeral environments: deny creating resources that are not tagged with an expiration date, and use Lambda to clean up expired resources. Finally, regularly review your OU structure and SCPs. As your organization grows, your governance needs will change. Conduct quarterly reviews to ensure your SCPs still align with your security posture. Remove unused SCPs and consolidate where possible. The goal is to have a governance framework that is both secure and agile, allowing teams to move fast without compromising safety.
| File | Command / Code | Purpose |
|---|---|---|
| create-org.sh | aws organizations create-organization --feature-set ALL | Why Multi-Account Governance Matters |
| create-ous.sh | ROOT_ID=$(aws organizations list-roots --query 'Roots[0].Id' --output text) | Organizational Units |
| base-deny-scp.json | { | Service Control Policies |
| allow-list-scp.json | { | Writing Effective SCPs |
| test-scp.sh | aws organizations list-policies-for-target --target-id ou-xxxx-xxxxxxxx --filter... | SCP Inheritance and Evaluation Logic |
| create_account.py | org = boto3.client('organizations') | Automating Account Creation and Baseline Configuration |
| cloudtrail-event-rule.json | { | Monitoring and Auditing SCP Compliance |
| iam-passrole-exception.json | { | Common Pitfalls and How to Avoid Them |
| region-restriction-scp.json | { | Advanced SCP Techniques |
| scp-terraform.tf | resource "aws_organizations_policy" "deny_leave_org" { | Integrating SCPs with CI/CD Pipelines |
| detach_scp.py | def lambda_handler(event, context): | Disaster Recovery and Break-Glass Procedures |
| tag-expiration-scp.json | { | Future-Proofing Your Multi-Account Strategy |
Key takeaways
AccessDenied events caused by SCPs. Silent denials are a common source of debugging frustration.Common mistakes to avoid
2 patternsOverlooking aws organizations scp basic configuration
Ignoring cost implications
Interview Questions on This Topic
What is AWS Organizations: Multi-Account Governance and SCPs and when would you use it?
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
That's AWS. Mark it forged?
8 min read · try the examples if you haven't