AWS Security Blog
Unlock new possibilities: AWS Organizations service control policy now supports full IAM language
Amazon Web Service (AWS) recently announced that AWS Organizations now offers full AWS Identity and Access Management (IAM) policy language support for service control policies (SCPs). With this feature, you can use conditions, individual resource Amazon Resource Names (ARNs), and the NotAction
element with Allow
statements. Additionally, you can now use wildcards at the beginning or middle of the Action
element strings and implement the NotResource
element in both Allow
and Deny
statements in SCPs. This feature is now available across AWS commercial and AWS GovCloud (US) Regions.
In this blog post, we walk through a set of newly supported SCP language capabilities that simplify permission management cases. These enhancements enable more intuitive and concise policy designs. We explore how these capabilities address past limitations to reduce operational overhead and improve policy readability. We also show what the previous implementation looked like and provide an example of how the new capability makes the intent clearer and implementation simpler.
Overview of the newly supported elements
The following table lists the supported SCP language elements along with their purpose and applicable effects. Elements and effects shown in bold indicate newly supported capabilities.
Element | Purpose | Supported effects |
Version | Specifies the language syntax rules to use for processing the policy. | Allow , Deny |
Statement | Serves as the container for policy elements. You can have multiple statements in an SCP. | Allow , Deny |
Statement ID (Sid) | (Optional) Provides a friendly name for the statement. | Allow , Deny |
Effect | Defines whether the SCP statement allows or denies access to the IAM users and roles in an account. | Allow , Deny |
Action | Specifies the AWS service and actions that the SCP allows or denies. | Allow , Deny |
NotAction | Specifies the AWS service and actions that are exempt from the SCP. Used instead of the Action element. |
Allow , Deny |
Resource | Specifies the AWS resources that the SCP applies to. | Allow , Deny |
NotResource | Specifies the AWS resources that are exempt from the SCP. Used instead of the Resource element. |
Allow , Deny |
Condition | Specifies the conditions for when the statement is in effect. | Allow , Deny |
Additionally, you can now use the wildcard characters * and ? anywhere in the Action or NotAction element. Previously, these wildcards were only allowed by themselves or at the end of an element. For example, all of the following are now valid:
"servicename:action*"
"servicename:*action"
"servicename:some*action"
"servicename:*"
Navigating new SCP language capabilities
Let’s explore recommended policy strategies and best practices by walking through some examples.
Using Deny
with NotResource
You can use the NotResource
element to apply a policy across resources except those explicitly listed. This is especially useful for implementing broad deny-by-default policies with scoped exceptions, simplifying policy structure while enforcing strong boundaries.
Example 1:
The goal of this example is to enforce a resource perimeter that blocks access to resources outside the organization, except for a defined set of service-owned resources.
- Previous implementation: The policy used a tag-based approach to manage exceptions. It required tagging IAM principals with
dp:exclude:resource:s3=true
to grant access to external resources. This created operational overhead in tag management and introduced potential security risks if tags were incorrectly applied. - Improved implementation: With support for
NotResource
inDeny
statements, the updated SCP uses a single, consolidatedDeny
statement denying the action except for a defined set of AWS-owned resources.
Policy structure before NotResource support | Policy structure after NotResource support |
Example 2:
This example denies access to Amazon Bedrock models except for one specific model.
- Before this change: SCP relied on a broad permission baseline for AWS accounts within the organization by allowing access to Amazon Bedrock actions by default, while explicitly denying invocation of three specific models (examples:
Deepseek
,Anthropic
, andmeta
). However, this approach requires continuous operational overhead to make sure policies are updated to deny access to newly added models to avoid exposure to potentially unwanted models. - Improved implementation: With support for
NotResource
inDeny
statements, the updated SCP uses a single, consolidatedDeny
statement that denies actions except Amazon models.
Policy structure before NotResource support | Policy structure after NotResource support |
Using Allow
with conditions
By using the Condition
element, you can specify the circumstances under which a policy statement is in effect. While optional, this element is now supported in Allow
statements within SCPs, enabling more precise and scalable access control.
Note: We recommend using explicit Deny
statements when authoring SCPs in most cases. Using Deny
statements help make sure that each control works independently and remains enforceable. Relying solely on allow statements and the implicit deny-by-default model can lead to unintended access, because broader or overlapping Allow
statements can override more restrictive ones.
The following example allows access to specific AWS services in certain AWS Regions.
- Before this change: The policy uses a single
Allow
statement under the Sid:AllowSpecificServices
. It lists broad service-level actions (for example,"ec2:"
,"s3:"
, and so on) in theAction
element and applies them across resources ("Resource": "*"
). Because AWS SCPs operate under a deny-by-default model, this setup effectively permits actions across the listed services while implicitly denying access to other services not included. For example, an explicitDeny
restricts actions outsideus-east-1
,us-west-2
, andeu-central-1
using a Region condition. - Improved implementation: In the updated example, the policy allows the same services, but only when they are requested in specific Regions (for example,
"us-east-1"
,"us-west-2"
, and"eu-central-1"
). This is achieved using the aws:RequestedRegion condition key in theAllow
statement. This enhancement allows organizations to retain basic Allow logic while introducing contextual boundaries—such as limiting access by Region, account, or resource tag—previously only possible withDeny
conditions.
Note: We recommend using one broad Allow
statement and multiple targeted Deny
statements in your policies. Avoid writing additional Allow
statements that might overlap, because doing so could lead to unintended access. The recommended approach is to start with a broad Allow
statement and then use Deny
statements to refine and restrict access as needed.
Policy structure before support for Allow with conditions | Policy structure after support for Allow with conditions |
Other newly supported elements
To bring SCPs to full IAM policy language support, additional elements are now supported. While technically valid, some of these constructs require additional considerations and testing in practice because of their potential for unintended access if not carefully managed.
Newly supported feature | Important considerations |
Action with wildcards (* , ? ) |
Can help shorten policies but use with caution—new actions added by AWS will match existing wildcard patterns as designed, potentially granting unintended permissions. |
NotAction with wildcards (* , ? ) |
We recommend using NotAction with a Deny statement if you want to deny all actions except those listed, which helps future-proof your controls (for example, denying everything in Amazon EC2 except actions that don’t match “*vpn*” . |
Allow with NotResource |
Limited use cases. While supported, Allow with NotResource can default to including all resources—potentially allowing access to new resources added later. Use with caution and prefer explicit Deny statements when possible. |
Allow with NotAction |
Limited use cases. While supported, Allow with NotAction can unintentionally permit access to new actions added by AWS. Use with caution and prefer explicit Deny statements to maintain control as services evolve. |
Allow with Resource other than wildcard “*” . |
When using Allow with specific resources (not "*" ), make sure your policy design avoids conflicting or overlapping Allow statements. Start with a broad Allow , then use targeted Deny statements to restrict access—this helps prevent unintended access from overlapping Allow statements. |
Validate your policies with IAM Access Analyzer
You can use AWS IAM Access Analyzer to validate your SCPs before applying them, using both policy validation and custom policy checks.
IAM Access Analyzer validates your policy against IAM policy grammar and best practices. You can view policy validation check findings that include security warnings, errors, general warnings, and suggestions. These findings provide actionable recommendations to help you author policies that are both functional and aligned with security best practices.
Custom policy checks are an IAM Access Analyzer capability that security teams can use to help them accurately and proactively identify critical permissions in their policies. Custom policy checks can determine whether a new version of a policy is more permissive than the previous version. They use automated reasoning—a form of static analysis—to provide a higher level of security assurance in the cloud.
Custom policy checks can be embedded into continuous integration and continuous delivery (CI/CD) pipelines, so that policies can be checked without being deployed. Developers can also run custom policy checks from their local development environments and receive fast feedback on whether the policies they are authoring comply with your organization’s security standards. For more information refer to introducing IAM Access Analyzer custom policy checks.
Conclusion
The latest enhancements to AWS service control policies improve policy expressiveness and precision while reducing operational effort. By enabling constructs like Allow
with conditions and specific resource ARNs, supporting NotResource
in Deny
statements, and expanding wildcard flexibility, you can simplify your policies and avoid layered or complex policies to achieve your goals. These updates bring SCPs in parity with IAM policy capabilities and empower organizations to implement cleaner, more intuitive access controls. As a best practice, it’s important to use these capabilities carefully—especially wildcard use—to avoid unintended permissions as AWS services evolve. We also encourage the implementation of explicit Deny
statements as a best practice and using Allow
statements when needed.
If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, contact AWS Support.