Cloud Security Wire
AWS Azure GCP RSS
AWS Hardening Guide high

AWS Organizations SCPs: Preventive Guardrails That Enforce Security Across Every Account

Service Control Policies (SCPs) are the most powerful preventive control in AWS Organizations -- they cap what any principal can do in a member account, including root. This guide covers the essential deny policies every multi-account environment should have.

By Cloud Security Wire · ·
#aws#organizations#scp#guardrails#iam#preventive-controls#multi-account#security-baseline
High Severity

This issue has been assessed as high severity. Review affected configurations immediately.

AWS Organizations Service Control Policies (SCPs) are a category of policy that most teams understand in principle but under-deploy in practice. They are not IAM policies — they don’t grant permissions. Instead, they establish the maximum set of permissions that any identity in a member account can ever have. An SCP that denies cloudtrail:DeleteTrail means no user, role, or even root in that account can delete a CloudTrail trail, regardless of what their IAM policy says.

That’s a fundamentally different security property than anything you can achieve with IAM alone. This guide covers what SCPs are, how to structure them, and the essential deny policies that should exist in every multi-account AWS environment.

How SCPs Work

SCPs are evaluated at the organization level, before IAM policies are evaluated. The effective permissions for any principal are the intersection of what’s allowed by SCPs and what’s granted by IAM. If an SCP doesn’t explicitly allow (or fails to deny) an action, the action is allowed from the SCP’s perspective — the IAM policy still controls actual access.

Two structural points that catch people out:

SCPs don’t apply to the management account. The root organization account is exempt from all SCPs. This is a design limitation — it means the management account must be treated with extreme caution and kept minimal. Do not deploy workloads in the management account.

SCPs apply to the root user. This is the key difference from IAM. You cannot use IAM to prevent root from doing something. An SCP can. This makes SCPs the correct control for protecting critical security services from insider threats and compromised admin credentials.

OU Structure and SCP Inheritance

SCPs attach to the root, organizational units (OUs), or individual accounts. Policies are inherited down the hierarchy — an SCP attached to an OU applies to all accounts inside it.

A minimal OU structure:

Root
├── Security (audit account, security tooling)
├── Infrastructure (networking, shared services)
├── Workloads
│   ├── Production
│   ├── Staging
│   └── Development
└── Sandbox (experimentation, loose controls)

Attach your strictest SCPs to Production; relax them for Sandbox. The Security OU often has additional SCPs that prevent other accounts from modifying security tooling.

The Essential Deny Policies

1. Protect CloudTrail

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCloudTrailModification",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:StopLogging",
        "cloudtrail:UpdateTrail",
        "cloudtrail:PutEventSelectors"
      ],
      "Resource": "*"
    }
  ]
}

Attackers targeting AWS environments routinely attempt to disable CloudTrail before exfiltrating data. This SCP eliminates that vector entirely.

2. Protect GuardDuty

{
  "Sid": "DenyGuardDutyDisable",
  "Effect": "Deny",
  "Action": [
    "guardduty:DeleteDetector",
    "guardduty:DisassociateFromMasterAccount",
    "guardduty:StopMonitoringMembers",
    "guardduty:UpdateDetector"
  ],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalArn": "arn:aws:iam::*:role/SecurityBreakglass"
    }
  }
}

Note the condition: this exempts a named break-glass role (which should have very limited use and full logging). Without a break-glass exemption, legitimate security operations that need to reconfigure GuardDuty will be blocked.

3. Enforce Approved Regions Only

{
  "Sid": "DenyUnapprovedRegions",
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "eu-west-1",
        "eu-west-2",
        "us-east-1"
      ]
    },
    "StringNotLike": {
      "aws:PrincipalArn": [
        "arn:aws:iam::*:role/OrganizationAccountAccessRole"
      ]
    }
  }
}

Data sovereignty requirements and cost control both benefit from restricting which regions accounts can deploy into. Global services (IAM, S3 bucket policies, Route 53, CloudFront) are not affected by region-based deny conditions.

4. Prevent Leaving the Organization

{
  "Sid": "DenyLeaveOrganization",
  "Effect": "Deny",
  "Action": "organizations:LeaveOrganization",
  "Resource": "*"
}

A compromised account that leaves the organization escapes all SCPs instantly. This is a single-statement policy that prevents it.

5. Block Unauthorized IAM Changes in Prod

{
  "Sid": "DenyIAMUserCreation",
  "Effect": "Deny",
  "Action": [
    "iam:CreateUser",
    "iam:CreateAccessKey",
    "iam:AttachUserPolicy",
    "iam:CreateLoginProfile"
  ],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalOrgPaths": "o-xxxx/r-xxxx/ou-xxxx-prod/"
    }
  }
}

In mature environments, production accounts should have no IAM users at all — only roles assumed via SSO. This SCP enforces that requirement. Adjust the PrincipalOrgPaths condition to exempt your platform team’s management roles.

SCP Strategy: Deny-by-Exception vs. Allow-by-Exception

Two approaches exist:

Full AWS access with targeted denies ("Effect": "Allow", "Action": "*" at root, deny policies lower down): simpler to start with, easier to iterate, good for most organizations.

Explicit allowlist (a root SCP that denies *, with per-OU SCPs allowing specific services): maximum restriction, harder to maintain, appropriate for highly regulated environments.

Most teams should start with deny-by-exception and move toward allowlists for specific sensitive OUs (production, security) over time.

Testing SCPs Safely

Never attach an untested SCP directly to a production OU. The workflow:

  1. Create a test account in a sandbox OU.
  2. Attach the SCP to that account only.
  3. Attempt the denied actions with a test IAM user — confirm the deny fires.
  4. Confirm legitimate operations still work.
  5. Use the IAM Policy Simulator with aws:PrincipalOrgPaths to model SCP effects before applying.
  6. Deploy to staging OU, wait 24-48 hours for any friction reports.
  7. Promote to production.

The aws:RequestedRegion and organizations:LeaveOrganization deny policies are safe to deploy broadly without extensive testing. The IAM restriction policies require more care — one missing exemption and you’ll lock your pipeline roles out of the account.

What SCPs Can’t Do

SCPs cannot grant permissions — they only restrict. A permissive SCP and a deny IAM policy: the IAM deny wins. A restrictive SCP and a permissive IAM policy: the SCP deny wins.

SCPs also don’t apply to service-linked roles. If you need to restrict what AWS services themselves can do within your accounts, use resource policies and permission boundaries instead.

Finally, SCPs don’t replace a solid IAM posture. They’re the last line of defense, not a substitute for least-privilege identity design. Get both right.

← All Analysis Subscribe via RSS