advanced 45 min read aws Updated: 2025-07-25

Organizational Guardrails (SCPs)

Master AWS Organizations with Service Control Policies (SCPs), automated account governance, and multi-account security strategies for enterprise-scale management.

📋 Prerequisites

  • Expert knowledge of AWS Organizations, including OU design and consolidated billing.
  • Advanced proficiency with IAM policies, conditions, and evaluation logic.
  • Strong experience with Terraform for deploying organizational policies.
  • Access to an AWS Organization's management account.

💡 SCPs: The Ultimate Preventive Guardrail

Service Control Policies (SCPs) are the broadest and most powerful preventive controls available in AWS. Applied at the organization root or to specific Organizational Units (OUs), they define a permission boundary for every IAM principal in an account. An explicit `Deny` in an SCP overrides any `Allow` in an IAM policy, making them the ultimate guardrail for enforcing compliance and security baselines.

🏷️ Topics Covered

aws service control policiesaws organizations best practicesscp examplesmulti-account strategy awscentralized iam governanceaws landing zone securityou structure aws

Core SCP Strategy: Deny List vs. Allow List

The first strategic decision is whether to use a "deny list" (also known as a blocklist) or an "allow list" (also known as an allowlist) approach. This choice has significant implications for security and operational flexibility.

🛡️ Deny List Strategy (Recommended Start)

  • How it works: You start with the default `FullAWSAccess` SCP attached and add SCPs with `Effect: "Deny"` for specific high-risk actions.
  • Pros: Safer to implement, lower risk of accidentally breaking applications. New AWS services are available by default.
  • Cons: Less restrictive. You must constantly identify and deny new unwanted actions.

🧱 Allow List Strategy (Maximum Security)

  • How it works: You detach the default `FullAWSAccess` SCP and attach a custom policy that only allows a specific set of services and actions.
  • Pros: Enforces true least privilege at the account level. Highly secure and compliant.
  • Cons: High operational overhead. Can easily break services if not carefully managed. Requires a mature review process for enabling new services.

Advanced & Multi-Statement SCP Examples

Real-world SCPs are often multi-statement documents that combine several security objectives into a single, cohesive policy.

📜 JSON: Foundational Security Guardrails SCP

This is a typical "deny list" SCP that should be applied to most OUs. It combines several critical security restrictions.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyLeavingOrganization",
            "Effect": "Deny",
            "Action": "organizations:LeaveOrganization",
            "Resource": "*"
        },
        {
            "Sid": "DenyTamperingWithSecurityServices",
            "Effect": "Deny",
            "Action": [
                "cloudtrail:DeleteTrail",
                "cloudtrail:StopLogging",
                "config:DeleteConfigurationRecorder",
                "config:StopConfigurationRecorder",
                "guardduty:DeleteDetector",
                "guardduty:UpdateDetector"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenyRootUserAccessKeys",
            "Effect": "Deny",
            "Action": "iam:CreateAccessKey",
            "Resource": "arn:aws:iam::*:user/root"
        },
        {
            "Sid": "DenyPasswordPolicyChanges",
            "Effect": "Deny",
            "Action": "iam:UpdateAccountPasswordPolicy",
            "Resource": "*"
        }
    ]
}

🌍 JSON: Data Residency & Service Control SCP

This policy enforces data residency by denying access to unapproved AWS regions, while carefully exempting necessary global services.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyUnapprovedRegions",
            "Effect": "Deny",
            "NotAction": [
                "iam:*",
                "organizations:*",
                "route53:*",
                "cloudfront:*",
                "support:*",
                "budgets:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestedRegion": [
                        "us-east-1",
                        "eu-west-2"
                    ]
                }
            }
        }
    ]
}

Managing SCPs as Code with Terraform

Manually managing SCPs across a large organization is not scalable or auditable. You must define and deploy them using Infrastructure as Code.

🏗️ HCL: Managing OUs and SCPs with Terraform

This Terraform configuration defines two different SCPs and attaches them to their respective Organizational Units (OUs).

# 1. Define the Foundational Security SCP
resource "aws_organizations_policy" "foundational_security" {
  name        = "FoundationalSecurity"
  description = "Denies high-risk actions like leaving the org or disabling security tools."
  content     = file("policies/foundational_security.json")
}

# 2. Define a more restrictive SCP for Sandbox accounts
resource "aws_organizations_policy" "sandbox_restrictions" {
  name        = "SandboxRestrictions"
  description = "Denies access to expensive and production-oriented services."
  content     = file("policies/sandbox_restrictions.json")
}

# 3. Define the Organizational Units
resource "aws_organizations_organizational_unit" "production_ou" {
  name      = "Production"
  parent_id = aws_organizations_organization.main.root[0].id
}

resource "aws_organizations_organizational_unit" "sandbox_ou" {
  name      = "Sandbox"
  parent_id = aws_organizations_organization.main.root[0].id
}

# 4. Attach the policies to the OUs
resource "aws_organizations_policy_attachment" "attach_foundational_to_prod" {
  policy_id = aws_organizations_policy.foundational_security.id
  target_id = aws_organizations_organizational_unit.production_ou.id
}

resource "aws_organizations_policy_attachment" "attach_foundational_to_sandbox" {
  policy_id = aws_organizations_policy.foundational_security.id
  target_id = aws_organizations_organizational_unit.sandbox_ou.id
}

resource "aws_organizations_policy_attachment" "attach_sandbox_restrictions" {
  policy_id = aws_organizations_policy.sandbox_restrictions.id
  target_id = aws_organizations_organizational_unit.sandbox_ou.id
}

Troubleshooting Common and Complex SCP Issues

Because SCPs act as an invisible ceiling on permissions, they can be a common source of "Access Denied" errors that are difficult to debug.

❌ "My Admin Role is Denied Access!"

  • Symptom: An IAM administrator in a member account, who has `AdministratorAccess` in their IAM policy, is suddenly unable to perform actions they could before.
  • Root Cause: An explicit `Deny` in an SCP always overrides an `Allow` in an IAM policy. A new or modified SCP has been attached to the OU containing the account, which denies the action the admin is trying to perform.
  • Solution:
    1. Start in the member account and use the **IAM Policy Simulator** to confirm the user's IAM policies allow the action.
    2. If IAM allows it, the issue is almost certainly an SCP. Log into the **management account**.
    3. Navigate to AWS Organizations -> Select the account -> Policies tab. View all effective SCPs.
    4. Carefully read the JSON of each SCP to find the statement with `Effect: "Deny"` that is blocking the action. Remember to check SCPs attached to parent OUs, as they are inherited.

🛡️ "The SCP Isn't Working in the Management Account"

  • Symptom: You apply an SCP to the root of your organization to deny a specific action, but an admin in the management account is still able to perform that action.
  • Cause: This is by design. **SCPs do not affect any users or roles in the management account.** They are designed to constrain member accounts only.
  • Solution: The management account must be protected by traditional IAM policies. Do not use it to host workloads. Keep its use limited to organizational management and billing, and apply strict, least-privilege IAM policies to any principals within it.

🔑 Expert-Level SCP Best Practices

  • Protect the Management Account: SCPs do not apply to your management account. Protect it with strict IAM policies and use it only for organization-level tasks.
  • Start with a Deny List: Begin your SCP strategy by denying a small number of high-risk actions. This is much safer than an allow list, which can accidentally break critical services.
  • **Test in a Dedicated OU:** Never attach a new or modified SCP directly to your production OU. Create a separate "Testing" OU with a non-critical member account to validate the impact of your policies.
  • **Remember Inheritance:** Policies attached to a parent OU are inherited by all child OUs and accounts. The effective policy is the union of all inherited policies.
  • **Exempt Global Services in Region Policies:** When creating SCPs to restrict regions, be sure to add `NotAction` statements for global services like IAM, Route 53, and CloudFront to prevent unintended consequences.

You've Set Your Foundational Guardrails!

With strong organizational boundaries in place, the next step is to master fine-grained identity and access controls within your accounts.