Skip to main content
Back
DateRead11 min

AWS Resource Control Policies (RCPs) Explained: What They Are and How They Work

Resource Control Policies (RCPs) are an authorization policy type in AWS Organizations that set the maximum available permissions on AWS resources across your entire organization. Introduced in November 2024, they let central security and platform teams restrict external access to supported resource types at the organizational level, independent of what individual resource-based policies or IAM identity policies allow.

Where Service Control Policies (SCPs) constrain what principals can do, RCPs constrain what can be done to resources. The two are complementary controls that address the same data perimeter problem from opposite directions.

Key Takeaways

  • RCPs are resource-centric preventive controls managed in AWS Organizations. Any access request that doesn't satisfy the applicable RCPs is blocked, regardless of what the resource-based policy or calling principal's IAM policies allow.
  • RCPs are deny-only. All customer-authored RCPs must use "Effect": "Deny". The only RCP permitted to use Allow is the AWS-managed RCPFullAWSAccess policy, automatically attached to every entity in your organization when RCPs are enabled.
  • RCPs don't apply to the management account or to calls made by AWS service-linked roles. They also don't restrict access to AWS managed KMS keys or the kms:RetireGrant action.
  • Attachment is capped at 5 policies per entity (root, OU, or account). Since RCPFullAWSAccess is permanently attached and counts toward this limit, you have 4 usable slots for custom deny policies at each attachment point.

RCPs vs. SCPs: Two Sides of the Data Perimeter

Service Control Policies (SCPs)Resource Control Policies (RCPs)
What they governPrincipals (IAM roles and users)Resources (S3 buckets, KMS keys, etc.)
DirectionOutbound: limits what your identities can doInbound: limits who can access your resources
Supported effectsAllow or DenyDeny only (customer policies)
Management accountDoes not applyDoes not apply
Service-linked rolesDoes not applyDoes not apply
Principal elementImplicit (applies to the attached account's principals)Must be "*" (use Conditions to narrow)
NotPrincipal / NotActionSupportedNot supported
Attachment limit per entity105 (1 slot consumed by RCPFullAWSAccess)
Max policy size10,240 characters5,120 characters
Introduced2017November 2024

The data perimeter use case requires both. An SCP can prevent your identities from accessing S3 buckets outside your organization, but it can't prevent an external identity from accessing your S3 buckets if a misconfigured bucket policy inadvertently allows it. An RCP closes that second gap. Neither policy type grants permissions; they only restrict what other policies can grant.

Where RCPs Sit in the AWS Policy Hierarchy

When an API call reaches AWS, the request moves through a deterministic evaluation chain. RCPs operate on the resource side of that chain, which is what distinguishes them from SCPs and resource-based policies.

Code
1. Explicit Deny check (any policy type)
2. Organizations SCPs: constrain what the calling principal can do
3. Organizations RCPs: constrain what can be done to the resource
4. Resource-based policies (S3 bucket policy, KMS key policy, etc.)
5. IAM identity-based policies (attached to the calling role or user)
6. Permission boundaries (if any)
7. Session policies (if any)

An explicit deny at any layer terminates the request. A permissive S3 bucket policy that grants access to Principal: "*" doesn't override an RCP, because an RCP caps the permissions available on the resource and an explicit deny in any applicable policy wins. It isn't a question of which policy is read first. When you enable RCPs, AWS automatically attaches RCPFullAWSAccess to every entity in your organization, a managed policy that allows all requests to pass through RCP evaluation untouched. Your custom deny policies layer on top of that baseline.

How RCPs Evaluate

Effect. Customer-authored RCPs must use "Effect": "Deny". The Allow effect is reserved exclusively for RCPFullAWSAccess. You cannot author a custom RCP that grants access.

Inheritance. RCPs propagate downward through the organization hierarchy. A deny attached at the root applies to every account in the organization. A deny attached to an OU applies to every account under that OU. Any RCP in the path from root to the target account can trigger a deny.

Principal. The Principal element must be "*". RCPs can't target specific principals by ARN in the Principal element directly. To restrict or exclude specific principals, use the Condition element with keys like aws:PrincipalOrgID or aws:PrincipalIsAWSService.

Unsupported elements. NotPrincipal and NotAction aren't supported in RCPs. NotResource is supported, so don't assume every Not* element is off the table.

Service-linked roles. RCPs do not restrict calls made by AWS service-linked roles. If your RCP denies all external access to S3 but an AWS service uses a service-linked role to write to a bucket, those calls are not blocked.

Management account. RCPs have no effect on the management account. Resources there are outside the RCP perimeter entirely.

Other documented exclusions. AWS doesn't document an RCP carve-out for RAM-shared resources. The exclusions it does document are AWS managed KMS keys and the kms:RetireGrant action, neither of which an RCP can restrict.

Supported Services

RCP support is expanding quickly. As of August 2026 the AWS Organizations documentation lists 44 service entries, up from five at launch. Service coverage determines where your RCP-based perimeter applies and, by implication, where it doesn't.

ServiceSupport Added
Amazon S3November 2024
AWS Security Token Service (STS)November 2024
AWS Key Management Service (KMS)November 2024
Amazon Simple Queue Service (SQS)November 2024
AWS Secrets ManagerNovember 2024
Amazon Elastic Container Registry (ECR)June 2025
Amazon OpenSearch ServerlessJune 2025
AWS Sign-InJune 2026
Amazon DynamoDBFebruary 2026
Amazon CloudWatch LogsJanuary 2026
Amazon Cognito (Identity and User Pools)January 2026

The table covers the launch set and the most notable additions since, not all 44 entries. For services with no RCP support, enforcing access boundaries still requires resource-based policies, SCPs, or other controls. Check the AWS Organizations documentation for the current list. The service set changes independently of this page's update cycle.

Console Navigation Path

Verify this path on each content refresh. AWS console navigation changes with product updates.

To enable and manage RCPs in the AWS Management Console:

  1. Open AWS Organizations
  2. In the left navigation pane, choose Policies
  3. Choose Resource control policies
  4. If RCPs are not yet enabled, choose Enable resource control policies

Enabling RCPs automatically attaches RCPFullAWSAccess to the organization root, every OU, and every account. This policy cannot be detached. Enabling RCPs does not immediately restrict any access; existing permissions continue to operate as they did until you create and attach custom deny policies.

To create a new RCP:

  1. From the Resource control policies page, choose Create policy
  2. Enter a policy name and optional description
  3. Paste or write the policy JSON in the editor
  4. Choose Create policy

To attach an RCP to an OU or account:

  1. From the Resource control policies page, choose the policy
  2. Choose the Targets tab
  3. Choose Attach, select the target root, OU, or account, and confirm

Limits and Quotas

These are the current hard limits for RCPs, sourced from AWS Organizations documentation.

LimitValue
Maximum RCPs per organization2,000
Maximum size per RCP5,120 characters
Maximum policies attached to the root5
Maximum policies attached to an OU5
Maximum policies attached to an account5
Minimum policies attached to any entity1 (RCPFullAWSAccess, which can't be detached)
Effective custom policy slots per entity4 (5 total minus the permanently attached RCPFullAWSAccess)
OU nesting depth5 levels under root
Effect values allowed in customer-authored RCPsDeny only

The 5,120-character limit per policy is half the SCP limit of 10,240. For complex perimeter implementations with multiple condition keys and resource ARN patterns, the size constraint becomes a real design consideration. JSON whitespace outside quotation marks is stripped when saved through the console but counts against the limit when saved via CLI or SDK.

Supported Condition Keys

The Principal element in a customer-authored RCP must always be "*". Granular control is achieved through the Condition block. The following condition keys are commonly used with RCPs and should be re-verified against the Service Authorization Reference on each content refresh.

Condition KeyWhat It EvaluatesCommon RCP Use
aws:PrincipalOrgIDThe AWS Organization ID of the calling principalDeny access from principals outside your org
aws:PrincipalOrgPathsThe OU path of the calling principal within an orgRestrict access to principals in a specific OU
aws:PrincipalArnThe ARN of the calling principalExclude specific roles or users from a deny
aws:PrincipalAccountThe account ID of the calling principalRestrict access to principals from specific accounts
aws:PrincipalIsAWSServiceWhether the caller is an AWS service principalCarve out AWS services from org-boundary denies
aws:SourceOrgIDOrg ID of the account making a cross-service requestEnforce org boundary in service-to-service access
aws:ResourceOrgIDThe org ID the target resource belongs toPrevent your principals from reaching external resources
aws:SecureTransportWhether the request was made over TLSEnforce HTTPS across all access to a service
aws:RequestedRegionThe AWS region targeted by the requestRestrict resource access to approved regions

The IfExists variants (StringNotEqualsIfExists, BoolIfExists) are important when a condition key may not be present in all request contexts. Using them instead of bare operators prevents unintended denies when a key is absent.

Policy Examples

Example 1: Restrict S3 access to principals within your organization

Denies all S3 operations on buckets in the attached accounts unless the calling principal is inside your AWS organization or is an AWS service.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyExternalS3Access",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringNotEqualsIfExists": {
          "aws:PrincipalOrgID": "o-exampleorgid"
        },
        "BoolIfExists": {
          "aws:PrincipalIsAWSService": "false"
        }
      }
    }
  ]
}

StringNotEqualsIfExists fires when the key is present and the value doesn't match your org ID. The BoolIfExists condition for aws:PrincipalIsAWSService is the critical carve-out: omitting it will break CloudTrail delivery, S3 replication, and any other AWS service that writes to S3 using its own principal rather than an IAM role in your account.

Example 2: Enforce HTTPS for all S3 operations

Denies any S3 request that doesn't arrive over TLS, regardless of what the bucket policy allows.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyNonTLSS3Access",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

AWS services use HTTPS by default, so no service principal carve-out is needed here. This policy is low-risk enough to attach at root with relatively minimal blast-radius concern, though testing in a non-production OU first is still the right approach.

Example 3: Prevent external principals from assuming IAM roles via STS

Prevents principals outside your organization from assuming roles in member accounts, regardless of what the role trust policy allows.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyExternalRoleAssumption",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sts:AssumeRole",
      "Resource": "*",
      "Condition": {
        "StringNotEqualsIfExists": {
          "aws:PrincipalOrgID": "o-exampleorgid"
        },
        "BoolIfExists": {
          "aws:PrincipalIsAWSService": "false"
        }
      }
    }
  ]
}

Common Mistakes

Forgetting aws:PrincipalIsAWSService. AWS services that access your resources on your behalf (CloudTrail, Config, Backup, S3 replication) don't always use principals inside your organization. Without an exclusion for service principals, an org-boundary RCP on S3 or KMS will break these integrations silently or with cryptic access-denied errors.

Conflating RCPs with resource-based policies. RCPs set the ceiling; they don't replace the floor. A deny in an RCP blocks access even when a bucket policy would allow it, but a permissive RCP doesn't grant access on its own. Resource-based policies or identity-based policies still need to authorize requests.

Miscounting attachment slots. The 5-policy attachment limit per entity is a hard limit. RCPFullAWSAccess is permanently attached and counts as one of those five, leaving four slots for custom deny policies per attachment point.

Assuming full wildcard Actions work. In SCPs, "Action": "*" is valid. In RCPs, the Action element must include the service prefix. "Action": "*" is not valid in a customer-authored RCP; you need at least a service abbreviation like "s3:*" or "kms:*".

Attaching to the management account. RCPs don't apply there. If workloads run in your management account and you're relying on an org-level RCP to protect them, those resources are unprotected.

Deploying to production without scoped testing. An RCP attached to the root applies to every account in the organization simultaneously. Testing in an isolated OU before promoting is the standard mitigation, and AWS explicitly recommends it.

Best Practices

Build incrementally. Start with the services carrying the highest-sensitivity data in your environment, typically S3, KMS, and Secrets Manager, and establish the org boundary on those first. Expand service scope as you develop confidence in each policy's behavior under your actual workload patterns.

Test in a scoped OU before attaching at root. A single misconfigured deny at root cascades across every account simultaneously. AWS IAM Access Analyzer can evaluate the effect of an RCP on your current resource permissions before deployment, which is the right pre-deployment check before attaching to a broad organizational scope.

Keep SCP and RCP review cycles synchronized. Because they're two sides of the same perimeter, a change to trust policy behavior on one side should prompt a review of the other. Organizations that audit them independently tend to develop blind spots between the two control planes.

Document and track exemptions explicitly. Conditions that carve out specific principals or resources should be documented with an owner and a review date. Undocumented exemptions that survive policy rotation become drift, and drift in a perimeter policy is a gap.

Use IfExists condition operators for keys that may be absent. Bare operators like StringNotEquals will deny requests where the condition key is missing from the request context. StringNotEqualsIfExists only evaluates when the key is present, which prevents unintended denies.

FAQ

What is an AWS Resource Control Policy?

An RCP is an authorization policy managed through AWS Organizations that sets the maximum permissions available on AWS resources across your organization. It's a preventive control that restricts which principals can access your resources, evaluated independently of IAM identity policies and resource-based policies. All customer-authored RCPs use "Effect": "Deny" and cannot grant access.

How are RCPs different from Service Control Policies?

SCPs restrict what principals in your organization can do. RCPs restrict who can access the resources in your organization. SCPs constrain outbound permissions from your identities; RCPs constrain inbound access to your resources. Together they form the identity and resource sides of a data perimeter. Neither can grant permissions; both only reduce what other policies are allowed to grant.

What is RCPFullAWSAccess and can I remove it?

RCPFullAWSAccess is an AWS-managed policy automatically attached to every entity in your organization when you enable RCPs. It allows all requests to pass through RCP evaluation by default, preserving existing access patterns until you add deny statements. It cannot be detached, and it counts toward the 5-policy attachment limit per entity, leaving 4 slots for custom deny policies.

Do RCPs apply to the management account?

No. RCPs only affect member accounts. The management account is outside the RCP perimeter.

Can RCPs block AWS services from accessing my resources?

RCPs don't affect calls made by AWS service-linked roles. However, service principals used by CloudTrail, Config, S3 replication, and similar services are not service-linked roles and can be affected. Most org-boundary RCPs need a BoolIfExists: aws:PrincipalIsAWSService: false condition to carve these out.

What AWS services support RCPs?

As of August 2026 the AWS Organizations documentation lists 44 service entries. The launch set was Amazon S3, AWS STS, AWS KMS, Amazon SQS, and AWS Secrets Manager. Amazon ECR, Amazon OpenSearch Serverless, Amazon Cognito, Amazon CloudWatch Logs, Amazon DynamoDB, Amazon EventBridge, AWS WAF, and AWS Sign-In are among the additions since. Check the AWS Organizations documentation for the current list, as service support changes independently of this page's update cycle.

How many RCPs can I attach to a single OU or account?

Five total, including the mandatory RCPFullAWSAccess policy. In practice, this gives you four slots for custom deny policies at each attachment point.

Can I use NotPrincipal or NotAction in an RCP?

No. Both elements are unsupported in RCPs. Use the Condition element to achieve equivalent targeting logic.

Native is built to help security teams define and enforce the architectural intent behind controls like RCPs and SCPs across AWS, Azure, Google Cloud, and OCI, connecting the controls already in your environment to the perimeter they're supposed to maintain. See how Native approaches enforcement, or explore how RCPs fit into a broader cloud security guardrails strategy and the architecture of zones, boundaries, and baselines that governs them.

Ready to enforce secure-by-design?