AWS Service Control Policies That Actually Work in Production: Enforce Security Without Locking Out Incident Response

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
AWS Service Control Policies have two failure modes. The first is not having them: an attacker who compromises an account with administrative access can disable GuardDuty, stop CloudTrail, and pivot to other accounts in the organization without any preventive control stopping them. The second failure mode is having SCPs written from security guides that have not been tested against production operations: a region restriction that breaks IAM calls globally, a CloudTrail protection rule that blocks the log archival rotation your SIEM tool runs nightly, or a GuardDuty lockout SCP that prevents the security team's cross-account assume-role from working during an active incident.
This guide covers the production-safe versions of the four most critical AWS security SCPs, with the specific break-glass exemption patterns that preserve incident response access.
OU hierarchy: test SCPs safely before applying to production
Never apply a new SCP directly to the Organization root or to a production OU. The correct testing sequence uses an OU hierarchy where each level has progressively stricter controls.
Recommended structure: Root (attach only the FullAWSAccess managed policy, no custom deny SCPs), Security OU (strict SCPs for logging and security tooling accounts), Workload OU (standard SCPs for production and staging accounts), Sandbox OU (minimal SCPs for development and test accounts).
Apply a new SCP to the Sandbox OU first. In the Sandbox account, manually walk through every operation that could be affected: assume the break-glass role, run CloudTrail operations, attempt cross-region API calls. If the SCP does not block legitimate operations in Sandbox, apply it to Workload with a 48-hour observation period. Only promote to the Security OU or Root after two promotion cycles without operational incidents.
For each new SCP, document: what it denies, which roles are exempt via condition keys, and which AWS service calls were verified not to be affected. This documentation becomes the runbook for the next person who modifies the SCP.
SCP 1: region restriction with global service exemptions
The goal of a region restriction SCP is to prevent resources from being created in regions the organization does not operate in, limiting the blast radius of a compromised account. The common failure is a deny using Condition: StringNotEquals aws:RequestedRegion that also denies AWS global services, which do not have a regional endpoint and return null for the RequestedRegion condition key.
Global services affected include: IAM (all API calls), STS (AssumeRole, GetCallerIdentity), AWS Support, CloudFront, Route 53, AWS Organizations, AWS Billing, S3 bucket policy operations (the control plane, not data plane), and AWS WAF Classic.
The production-safe region restriction SCP uses NotAction to exempt global services: { "Effect": "Deny", "NotAction": [ "iam:", "sts:", "organizations:", "cloudfront:", "route53:", "support:", "budgets:", "waf:" ], "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": ["us-east-1", "us-west-2", "eu-west-1"] } } }
Update the region list to match your approved operating regions. Test by attempting to create an EC2 instance in a non-listed region (should be denied) and by running aws iam list-users from a non-listed region (should succeed, because IAM is in NotAction).
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
SCP 2: CloudTrail and GuardDuty protection with break-glass exemption
Protecting CloudTrail from being stopped or deleted is one of the highest-value SCPs because attackers who gain admin access reliably attempt to disable logging as a first step. The failure case is an overly broad protection SCP that blocks the security team's legitimate log archival operations.
Production-safe CloudTrail protection SCP: { "Effect": "Deny", "Action": [ "cloudtrail:StopLogging", "cloudtrail:DeleteTrail", "cloudtrail:UpdateTrail", "cloudtrail:PutEventSelectors" ], "Resource": "", "Condition": { "StringNotLike": { "aws:PrincipalArn": [ "arn:aws:iam:::role/SecurityAuditRole", "arn:aws:iam::*:role/BreakGlassRole" ] } } }
The StringNotLike condition with a wildcard account ID (the * in the ARN) exempts the named roles across all accounts in the organization. The security team's audit role and the break-glass role can still perform CloudTrail operations; all other principals in all member accounts cannot.
Apply the same pattern to GuardDuty protection: deny guardduty:DeleteDetector, guardduty:DisassociateFromMasterAccount, guardduty:StopMonitoringMembers with the same exemption for SecurityAuditRole and BreakGlassRole.
SCP 3: root account lockout with emergency access path
AWS root account credentials should never be used for routine operations. An SCP that denies all actions except from the root account itself prevents compromise of member account root credentials from being used to bypass SCPs.
However, root account access is required for certain account recovery operations: changing the root email address, enabling or disabling hardware MFA for root, accessing billing information when IAM billing access is disabled, and closing the account. An SCP that completely locks out root access leaves no recovery path for these operations.
The production-safe approach is not to deny root access via SCP (SCPs cannot restrict root-only actions as defined in the AWS documentation for each service), but to ensure root MFA is enforced and root credentials are stored in a hardware MFA device that is physically secured. The preventive control for root is MFA enforcement, not SCP denial.
For non-root privilege escalation prevention, apply an SCP that denies creation of new IAM users with administrative policies and denies creation of new IAM roles with AdministratorAccess unless the principal is in the designated Platform Engineering role: { "Effect": "Deny", "Action": ["iam:AttachUserPolicy", "iam:PutUserPolicy"], "Resource": "", "Condition": { "ArnLike": { "iam:PolicyARN": "arn:aws:iam::aws:policy/AdministratorAccess" }, "StringNotLike": { "aws:PrincipalArn": "arn:aws:iam:::role/PlatformEngineering" } } }
Responding to an SCP that locked out your team
If an SCP is applied and immediately causes access issues, the recovery path depends on which account applied it. SCPs are managed from the AWS Organizations management account (the root payer account). Any IAM principal in the management account with organizations:DetachPolicy permission can remove the SCP.
Recovery procedure: log into the management account using credentials that are stored separately from the member accounts (the management account should not run workloads and should have its own break-glass credentials). Navigate to AWS Organizations > Policies > Service control policies, find the problematic SCP, and either detach it from the affected OU or edit it to add the necessary exemption.
The management account's root credentials (with hardware MFA) are the ultimate recovery path if IAM access to the management account is also affected. This is why the management account root credentials must be stored separately from all other account credentials and tested for accessibility at least quarterly.
The bottom line
SCPs are the correct preventive control for protecting CloudTrail, GuardDuty, and regional resource sprawl in AWS Organizations. Every SCP that uses a broad deny pattern needs a StringNotLike condition on aws:PrincipalArn that exempts the security team's audit role and the organization's break-glass role. Test every SCP in a Sandbox OU before promoting to production, and verify that your incident response runbook still works with the new SCP in place before applying it to workload accounts.
Frequently asked questions
Can an SCP block the AWS root account from performing actions?
SCPs cannot restrict certain root-only actions that AWS explicitly reserves for the account root, including changing the root email address, enabling MFA for root, closing the account, and restoring IAM access if it has been revoked. For all other actions, an SCP deny does apply to the root account of member accounts in an AWS Organization. The management account root is never subject to SCPs.
What is the safest way to test an SCP before applying it to production accounts?
Create a dedicated Sandbox OU in AWS Organizations that contains non-production accounts. Apply the new SCP to the Sandbox OU and manually verify that all legitimate operations your teams perform still work, including: assuming cross-account roles, running CloudTrail operations, making API calls in all approved regions, and simulating your incident response runbook. If all operations succeed in Sandbox, apply to a Workload OU with a 48-hour monitoring window before promoting further. Never apply a new SCP directly to the Organization root or to a OU containing production accounts.
Why does my AWS region restriction SCP break IAM operations?
AWS global services including IAM, STS, CloudFront, and Route 53 do not pass a value for the aws:RequestedRegion condition key because they do not have regional endpoints. A region restriction SCP that uses StringNotEquals on aws:RequestedRegion without a NotAction exemption for these services will evaluate to null for the condition, which AWS treats as a condition that does not match, causing the deny to apply even to legitimate IAM calls. Fix this by adding IAM, STS, and other global services to the NotAction list in your region restriction SCP.
How do I write an SCP that allows break-glass incident response without creating a permanent backdoor?
Use a condition-based deny that blocks restricted actions for all principals except a specifically named break-glass role ARN. Example structure: Deny actions in the restricted list unless aws:PrincipalArn matches the break-glass role. The break-glass role itself should have MFA required for assumption (Condition: aws:MultiFactorAuthPresent: true), be in a dedicated security OU that is excluded from the deny SCP, and have CloudTrail alerting configured on every AssumeRole call to that ARN. The break-glass role should not have credentials pre-positioned: require the incident response team to retrieve them from a sealed process at incident time.
What is the difference between an SCP deny and an IAM policy deny in AWS?
An SCP sets the maximum permissions boundary for all IAM principals in an AWS Organizations account or OU: even if an IAM policy grants an action, an SCP deny overrides it. An IAM policy deny is applied at the principal level and overrides any Allow in IAM policies for the same principal within the same account. SCPs do not grant permissions: they only restrict what the maximum possible permissions are. A principal needs both a permissive IAM policy and the action allowed by the SCP to successfully make an API call. SCP denies are evaluated before IAM policy denies in the authorization decision.
How do I test an SCP in a non-destructive way before deploying it to production accounts?
Use AWS Organizations policy simulation: create the SCP on a test OU containing a single non-production account, then use the IAM policy simulator (IAM console > Policy Simulator > select a principal and the relevant actions) to verify the SCP produces the expected deny. For incident response guardrails specifically, test every action your IR runbook requires (EC2 snapshots, Security Hub findings retrieval, GuardDuty exports, CloudTrail log access, IAM temporary credential creation for forensic roles) against an IR simulation role in the test account. Only after all required IR actions pass and all restricted actions are denied should you attach the SCP to production OUs. AWS CloudFormation StackSets can deploy validated SCPs across all accounts in a controlled, auditable rollout.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
