I was working with a large enterprise customer last week who attached a Service Control Policy (SCP) to deny all EC2 creation in a development OU. They were shocked when developers in member accounts still launched instances. The SCP was clearly attached—they could see it in the console—but it wasn’t working. After 15 minutes of investigation, I found the real culprit. In this post, I’ll walk through exactly what causes this and how to fix it.
The Problem
When an SCP is attached to an Organizational Unit (OU) or account but restricted actions are still allowed, or the SCP shows as attached but has no effect, you’ll see errors like this when trying to perform an action:
User: arn:aws:iam::123456789012:user/developer is not authorized to perform:
ec2:RunInstances on resource: arn:aws:ec2:us-east-1:123456789012:instance/*
(Service: AmazonEC2; Status Code: 403; Error Code: UnauthorizedOperation)
However, the action still completes successfully in the account despite the SCP being attached.
| Issue | Symptom |
|---|---|
| All Features Not Enabled | SCP attached but no effect on any account |
| Management Account Exemption | SCP doesn’t restrict management account |
| Incorrect SCP Syntax | Policy attached but specific actions still allowed |
| FullAWSAccess Override | Broader Allow-All SCP cancels Deny policies |
| Inheritance Conflict | Parent OU policy contradicts child OU policy |
Why Does This Happen?
-
AWS Organizations only uses All Features mode for SCPs: SCPs require the organization to be in “All Features” mode—Consolidated Billing mode doesn’t support SCPs at all. Even if you enable policy types, the deny won’t take effect.
-
The management account is EXEMPT from all SCPs: This is by design. The management account (the one that created the organization) cannot be restricted by SCPs. Many teams forget this and try to apply SCPs to the management account directly.
-
SCP uses incorrect action or resource ARN format: If the action name is misspelled (e.g.,
ec2:RunInstancesvsec2:runInstances), or the resource ARN doesn’t match, the policy won’t work as expected. -
FullAWSAccess SCP is still attached and overrides denies: By default, AWS attaches
FullAWSAccessto the Root and all new OUs. This blanket Allow overrides any Deny policies. You must manageFullAWSAccesswhen using a deny-list strategy. -
Another SCP higher in the hierarchy allows a broader action: SCPs are evaluated as an intersection of all policies from Root to Account. If a parent OU has
"Action": "ec2:*"with"Effect": "Allow", that allows all EC2 actions regardless of child OU denies.
The Fix
Step 1: Verify All Features are enabled
aws organizations describe-organization \
--query 'Organization.FeatureSet' \
--output text
If this returns CONSOLIDATED_BILLING, you need to enable All Features. Go to the Organizations console → Settings → Upgrade Your Organization.
Step 2: List SCPs attached to your target
aws organizations list-policies-for-target \
--target-id ou-xxxx-yyyyyyyy \
--filter SERVICE_CONTROL_POLICY \
--output table
This shows all SCPs attached to the OU. Verify FullAWSAccess is listed if you’re using a deny-list approach.
Step 3: Check the effective policy on the actual account
aws organizations describe-effective-policy \
--policy-type SERVICE_CONTROL_POLICY \
--target-id 123456789012 \
--output text
This returns the actual combined policy that applies to the account after inheritance is resolved. Compare this to your expectations.
Step 4: Verify your SCP JSON is valid
Ensure actions are capitalized correctly (e.g., "ec2:RunInstances", not "ec2:runinstances"). Test the policy in the IAM Policy Simulator from the account that’s not respecting the SCP.
How to Run This
- Run the
describe-organizationcommand to confirm All Features is your feature set. - List the policies on your target OU using
list-policies-for-target. - Check the effective policy on the member account with
describe-effective-policy. - If
FullAWSAccessis attached and you want to enforce denies, either remove it or ensure your custom SCP uses allow-list logic for the exceptions. - Test a restricted action from the member account to verify the SCP is now enforced.
Is This Safe?
Absolutely. Checking SCPs with the AWS CLI is read-only and safe. If you modify SCPs, test in a non-production OU first. SCPs take effect immediately, so verify your policy logic before attaching to production OUs.
Key Takeaway
SCPs don’t work unless your organization is in All Features mode, and the management account is always exempt. Start by verifying All Features is enabled, then check the effective policy on the target account—that’s the truth of what’s actually restricting actions. Remember that FullAWSAccess is attached by default and must be actively managed when using deny-list strategies.
Have questions or ran into a different AWS Organizations issue? Connect with me on LinkedIn or X.