Service Control Policies occupy a unique position in AWS access control: they're evaluated before IAM policies, they apply to every principal in an account including the root user, and they can't be overridden by any action taken within the account. This makes SCPs the highest-trust guardrail in AWS — the right place to implement organization-wide constraints that should never be bypassed regardless of what individual accounts configure.
With that power comes risk. An overly broad SCP deny can break production workloads across every account in an OU. Testing SCPs before deployment and maintaining a systematic approach to SCP management is essential for organizations relying on SCPs as a control layer.
How SCPs Work
SCPs don't grant permissions — they define the maximum permissions available in an account. An SCP that allows ec2:* doesn't mean any principal in the account can take any EC2 action. It means EC2 actions are available in principle, subject to IAM policies that may further restrict them.
The practical interpretation: an action requires both an allowing SCP (explicitly allowing the service and action, or the absence of a deny) and an allowing IAM policy. If either denies the action, or if there's no allow in both, the action is denied. AWS evaluates in this order: Organizations SCPs, then resource-based policies, then IAM permission boundaries, then identity-based policies.
The default SCP applied to every account is FullAWSAccess — it allows all actions. This means Organizations is additive by default: adding accounts to an OU doesn't restrict them unless you explicitly add deny policies. Most organizations implement an "allow list" model (explicitly listing permitted services) or a "deny list" model (allowing everything except specific prohibited actions) depending on their risk tolerance and operational complexity preferences.
Deny-List vs. Allow-List Models
Deny-list (recommended for most organizations): Keep the FullAWSAccess SCP applied and add explicit deny statements for prohibited actions. This is less disruptive — new services are available by default, and you only deny what you've specifically decided to prohibit. Suitable for organizations where teams need flexibility and the primary SCP goal is preventing specific dangerous actions (disabling logging, creating public S3 buckets, leaving the organization).
Allow-list: Remove FullAWSAccess and explicitly list every allowed service and action. This is more secure (new services require explicit approval) but operationally expensive — every time AWS releases a new service feature, you need to update SCPs for teams to use it. Suitable for highly regulated environments where explicit approval of every service is a compliance requirement.
Essential Guardrail SCPs
These deny statements should be present in every production organization:
Prevent leaving the organization:
{"Effect": "Deny", "Action": ["organizations:LeaveOrganization"], "Resource": "*"}
Prevent disabling CloudTrail:
{"Effect": "Deny", "Action": ["cloudtrail:DeleteTrail", "cloudtrail:StopLogging", "cloudtrail:UpdateTrail"], "Resource": "*"}
Deny access to restricted regions: Limit AWS usage to approved regions to prevent unauthorized resource provisioning in regions outside your monitoring scope.
{
"Effect": "Deny",
"NotAction": ["iam:*", "organizations:*", "route53:*", "budgets:*", "waf:*", "cloudfront:*", "sts:*", "support:*", "trustedadvisor:*"],
"Resource": "*",
"Condition": {
"StringNotEquals": {"aws:RequestedRegion": ["us-east-1", "us-west-2", "eu-west-1"]}
}
}
Note the NotAction pattern — global services (IAM, Route 53, CloudFront) must be excluded from region restrictions because they operate from us-east-1 regardless of where you're working. This is a common source of SCP bugs that break IAM and DNS operations.
Deny root account actions: Prevent root account usage except for specific emergency scenarios by denying all root actions (use this carefully — it can lock you out of root recovery scenarios).
SCP Testing Process
Never deploy an SCP change to production OUs without testing. The testing process:
Create a test account in a test OU that mirrors the structure of your target OU but contains no production workloads. Apply the candidate SCP to the test OU. Test all actions that the SCP should allow and all actions it should deny. Use AWS IAM Policy Simulator to evaluate the policy logic, but note that the simulator doesn't fully replicate SCP evaluation — actual testing in a real account is more reliable.
After testing in the test account, deploy to your least critical OU first (sandbox or development). Monitor CloudTrail for permission-denied errors related to the new SCP for 24-48 hours. If no unexpected denials appear, deploy to staging, then production, waiting between each stage.
Maintain SCP change records with justification, testing evidence, and rollback procedures. An SCP that breaks production at 2 AM needs to be reverted quickly — having a documented rollback procedure (remove the deny statement or revert to the previous SCP version) is the difference between a 5-minute fix and a 2-hour incident.
SCP Exceptions and Bypass Patterns
Some legitimate operations require bypassing SCP deny statements. Handle exceptions through conditions rather than by weakening the global policy:
{
"Effect": "Deny",
"Action": ["ec2:RunInstances"],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {"ec2:InstanceType": ["t3.micro", "t3.small", "t3.medium"]},
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/InfrastructureAutomation"
}
}
}
This pattern denies large instance launches except when the principal is the InfrastructureAutomation role. The automation role is trusted to launch large instances; other principals are restricted. Use ArnNotLike and StringNotEquals condition operators for exception logic rather than removing the deny for all principals.
Related Reading
- AWS Organizations best practices — SCP strategy in organizational context
- AWS Control Tower setup — managed SCP guardrails through Control Tower
- IAM security best practices — IAM policies that work alongside SCPs
- CloudTrail best practices — protecting the audit trail that SCPs guard
FAQ
Can the management account be affected by SCPs?
No. SCPs do not apply to the management account. Actions taken from the management account are not subject to SCP restrictions in member accounts. This is both a feature (the management account can always recover from misconfigured SCPs in member accounts) and a risk (the management account has elevated effective permissions). Restricting management account access to only the personnel who need it is critical.
What happens if an SCP accidentally denies all IAM actions?
This is a serious incident. With IAM actions denied by SCP, you cannot modify IAM policies in affected accounts, and you cannot assume roles. Recovery requires removing or modifying the SCP from the management account, which is not affected by member account SCPs. This is one reason the management account must remain functional — it's your recovery path for organization-wide SCP accidents.
Can I use SCPs to enforce tagging requirements?
Yes. You can deny resource creation actions when specific tags are not present using the aws:RequestTag condition key. For example, deny ec2:RunInstances unless the Environment and Application tags are set. This enforces tagging at creation time. Some services have more complete tagging condition coverage than others — check the service's documentation for which actions support aws:RequestTag conditions.
Protect your AWS accounts before it's too late
Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.
Written by Vigilare Engineering
Platform Team