AWS Service Control Policies (SCPs): Multi-Account Guardrails Guide
AWS Service Control Policies (SCPs): Multi-Account Guardrails Guide
What Are Service Control Policies?
Service Control Policies (SCPs) are a feature of AWS Organizations that let you centrally control the maximum available permissions across accounts in your organization. Unlike IAM policies, SCPs do not grant permissions -- they set permission boundaries that apply to every principal in the affected accounts, including the root user.
SCPs are essential for any multi-account AWS strategy because they prevent even administrators from performing actions that violate your organization's security posture. If an SCP denies an action, no IAM policy in the member account can override it.
How SCP Inheritance Works
SCPs follow a hierarchical inheritance model through your AWS Organizations structure:
- Root level: SCPs attached here apply to every account in the organization
- Organizational Unit (OU) level: SCPs apply to all accounts in the OU and its child OUs
- Account level: SCPs apply only to the specific account
The effective permissions for an account are the intersection of all SCPs applied at every level from the root down to the account. This means a permission must be allowed (or not denied) at every level in the hierarchy for it to be available.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllOutsideApprovedRegions",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"us-east-1",
"us-west-2",
"eu-west-1"
]
},
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/OrganizationAdmin"
]
}
}
}
]
}
This SCP restricts all API calls to three approved regions while exempting an administrative role that may need to operate globally (for example, to clean up resources in unapproved regions).
Deny-Based Patterns: The Foundation of Effective Guardrails
The most reliable SCP strategy is deny-based: start with the default FullAWSAccess policy that AWS Organizations attaches, then layer on explicit deny statements for actions you want to prohibit. This approach is safer than allow-listing because new AWS services and actions are available by default, and you only need to block what is dangerous.
Prevent Disabling CloudTrail
CloudTrail is your audit log. If an attacker compromises an account, their first move is often to disable logging. This SCP prevents that:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCloudTrailModification",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail",
"cloudtrail:PutEventSelectors"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAutomation"
}
}
}
]
}
Restrict Root User Actions
The root user in member accounts should never be used for routine operations. This SCP locks it down while preserving the ability to manage the account itself:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyRootUserActions",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringLike": {
"aws:PrincipalArn": "arn:aws:iam::*:root"
}
}
}
]
}
Common Guardrail Examples
Beyond the examples above, here are additional SCPs that most organizations should consider:
Prevent Leaving the Organization
An attacker who can remove an account from your organization removes all SCP protections at once:
# Verify this SCP is in place across your org
aws organizations list-policies --filter SERVICE_CONTROL_POLICY \
--query 'Policies[*].[Name,Id]' --output table
Deny Public S3 Access
Even with S3 Block Public Access, an SCP provides an additional layer:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyS3PublicAccess",
"Effect": "Deny",
"Action": [
"s3:PutBucketPublicAccessBlock",
"s3:PutAccountPublicAccessBlock"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAutomation"
}
}
}
]
}
Testing SCPs Safely
SCPs can break production workloads if applied carelessly. Follow this testing protocol:
- Create a Sandbox OU with a non-critical account. Attach the new SCP there first.
- Use CloudTrail Dry Runs: After attaching the SCP, attempt the actions you expect to be blocked and confirm they are denied. Also verify that normal workloads continue to function.
- Check for Collateral Damage: Some deny statements can inadvertently block AWS service-linked roles or automation. Always include condition keys to exempt trusted roles.
- Monitor
AccessDeniedEvents: After rollout, filter CloudTrail forerrorCode: AccessDeniedto catch unintended blocks.
# Search CloudTrail for SCP-related denials in the last 24 hours
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin \
--start-time "$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)" \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`)].{Time:EventTime,User:Username,Event:EventName}' \
--output table
- Roll Out Incrementally: Dev OU first, then staging, then production. Allow at least 48 hours between each stage to catch issues.
SCP Limitations to Know
SCPs have important constraints that affect your design:
- Maximum 5 SCPs per target (root, OU, or account) by default. Request a quota increase if needed.
- Maximum 5,120 characters per SCP. Use multiple SCPs if you hit the limit.
- SCPs do not affect the management account. The organization's management account is always exempt from SCPs.
- SCPs do not affect service-linked roles. Actions performed by service-linked roles bypass SCPs.
- SCPs apply only within the organization. They do not affect external accounts that assume roles into your accounts.
Securing Multi-Account Governance with AccessLens
SCPs are a critical layer of defense, but managing them across dozens or hundreds of accounts introduces complexity and blind spots. AccessLens provides IAM visibility and risk analysis that complements your SCP strategy:
- Cross-Account Trust Visualization: See which external accounts can assume roles in your organization, identifying trust relationships that your SCPs may not cover.
- Policy Drift Detection: AccessLens scans IAM policies across all accounts and flags overprivileged roles that should be constrained by SCPs but are not.
- Risk Scoring: Every finding is scored by severity, helping you prioritize which guardrails to implement first.
- Compliance Reporting: Generate reports that map your SCP coverage against compliance frameworks like CIS AWS Foundations Benchmark.
SCPs define what is not allowed; AccessLens shows you what is actually happening. Together, they give you both preventive and detective controls for your multi-account environment.