|
Today, I’m happy to introduce Resource Control Policies (RCPs)—a new authorization policy managed in AWS organizations that can be used to set the maximum available permissions to resources across your entire organization. They are a type of preventive control that helps you create a data perimeter in your AWS environment and limit external access to resources at scale. Enforced centrally within organizations, RCPs provide confidence to central management and security teams that access to resources within their AWS accounts complies with their organization’s access control guidelines.
RCPs are available in all AWS commercial regions and the following services are supported at launch: Amazon Simple Storage Service (Amazon S3), AWS Security Token Service (AWS STS), AWS Key Management Service (AWS KMS), Amazon Simple Queue Service (Amazon SQS) and AWS Secret Manager.
There are no additional fees for activating and using RCP.
How is it different from Service Control Policy (SCP)?
Although similar in nature, RCPs complement Service Control Policies (SCPs) but operate independently.
Service control policies (SCPs) allow you to limit the permissions granted to principals in your organization, such as AWS Identity and Access Management (IAM) roles. By restricting these permissions centrally within organizations, you can limit access to AWS services, specific resources, and even under what conditions requests can be made across multiple AWS accounts.
RCPs, on the other hand, allow you to limit the permissions granted to resources in your organization. Because you implement RCP centrally across organizations, you can enforce consistent resource access control across multiple AWS accounts. For example, you can restrict access to S3 buckets in your accounts so that only directors who belong to your organization can access them. RCPs are evaluated when your resources are accessed, regardless of who is requesting the API.
Note that neither SCP nor RCP grant any permissions. They only set the maximum permissions available to directors and resources in your organization. You still need to grant permissions using the appropriate IAM policies, such as identity-based or resource-based policies.
The quotas for SCP and RCP are completely independent of each other. Each RCP can contain up to 5,120 characters. You can have up to five RCPs attached to the organization root, each organizational unit, and account, and you can create and store up to 1000 RCPs in your organization.
How to start
To start using RCPs, you must first enable them. You can do this using the Organizations console, the AWS SDK, or using the AWS Command Line Interface (AWS CLI). Make sure you are using an Organization Management or Delegated Administrator account, as these are the only accounts that can enable or disable policy types.
Make sure you use organizations with “all functions” option. If you use “Consolidated invoicing feature”, then you must switch to using all functions before you can activate RCP.
For console users, first go to the Organization console. Choose Principles and you should see an option to enable Resource management principles.
After activating RCP, you will notice v Resource management principles a page called the new policy RCPFullAWSAccess
is now available. This is an AWS-managed policy that is automatically created and attached to every entity in your organization including the root directory, every organizational unit, and AWS account.
This policy allows all principals to take any action against the organization’s resources, meaning that until you start creating and attaching your own RCPs, all of your existing IAM permissions will continue to work as they did.
This is what it looks like:
Creation of RCP
We are now ready to create our first RCP! Let’s look at an example.
By default, AWS resources do not allow access to external objects; resource owners must explicitly grant such access by configuring their policies. While developers can flexibly set resource-based policies according to the needs of their applications, RCPs enable central IT teams to maintain control over effective permissions across resources in their organization. This ensures that even when developers grant broad access, external identities still have limited access in accordance with the organization’s security requirements.
Let’s create an RCP to restrict access to our S3 buckets so that only directors in our organization can access them.
On Resource control policies page, choose Create a policy which will take you to a page where you can create a new policy.
I’ll call it politics EnforceOrgIdentities
. I recommend entering a clear description so it’s easy to understand at a glance what the policy does and label it appropriately.
In the next section, you can edit the policy statement. I replace the pre-populated policy template with my own:
Here is the full JSON policy document:
Let’s break it down:
Version – This is a standard and required element of IAM policies. AWS maintains backward compatibility, so using the latest version, currently 2012-10-17, does not violate existing policies, but allows you to use newer features.
Declaration – An array that can contain one or more command objects. Each of these command objects defines a single permission or a set of permissions.
Sid – This is an optional field that can be useful for policy management and troubleshooting. Must be unique within this JSON policy document.
Effect – As you may remember from before, by default we have an RCP that allows access to all principals, actions, and AWS resources attached to every entity in our organization. That’s why you should use Deny
apply restrictions.
Main – For RCP this field must always be set to "*"
. If you want this policy to apply only to specific objects, use the Condition field.
Action – Specifies the AWS service and actions to which this policy applies. In this case, we want to deny all interactions with Amazon S3 if they don’t meet our access control guidelines.
Resources – Specifies the resources to which the RCP applies.
State – A collection of conditions that will be evaluated to determine whether or not the policy should be applied for each request.
It is important to remember this all conditions must evaluate to true in order to use RCP. In this case, two conditions apply:
1. Was the application submitted by an external principal?
"StringNotEqualsIfExists":
{
"aws:PrincipalOrgID": "(MY ORG ID)"
}
This condition first checks if the key is aws:PrincipalOrgID
is present in the request. If not, then this condition evaluates to true without further evaluation.
If it exists, it compares the value to our organization ID. If the value is equal, it evaluates to false, which means that RCP will not be applied because all conditions must evaluate to true. This is the intended behavior as we do not want to deny access to principals within our organization.
However, if the value does not match our organization ID, it means that the request was made by a principal that is external to our organization. The condition evaluates to true, meaning that RCP can still potentially be used if the second condition also evaluates to true.
2. Is the request coming from an AWS service?
"BoolIfExists":
{
"aws:PrincipalIsAWSService": "false"
}
This condition tests whether the request contains a special called key aws:PrincipalIsAWSService
which is automatically inserted into the request context for all signed API requests and is set to true when originating from an AWS service such as AWS CloudTrail writing events to your S3 bucket. If the key is not present, then this condition evaluates to true
.
If it exists, it will compare the value to what we declare in our statement. In this case, we test if the value is equal false
. If so, we’ll be back true
as this would mean that the request was not made by AWS and could potentially still be made by someone outside of our organization. Otherwise we’re coming back false
.
In other words, if the request does not originate from a principal within our organization and does not originate from AWS, then access to the S3 bucket is denied.
This policy is an example only, and you should adapt it to meet your unique business and security goals. For example, you may want to modify this policy to allow access to your business partners or restrict access to AWS services so that they can only access your resources on your behalf. For more details, see Creating a Data Perimeter on AWS: Allow Only Trusted Identities to Access Corporate Data.
CPR connection
The RCP connection process is similar to SCP. As mentioned, you can attach it to your organization’s root directory, to an organizational unit, or to specific AWS accounts in your organization.
Once RCP is connected, requests to access the affected AWS resources must comply with RCP restrictions. We recommend that you thoroughly test the impact that RCP has on resources in your accounts before implementing it on a large scale. You can start by connecting RCP to individual test accounts or test OUs.
See it in action
I’ve now created and connected my RCP so I’m ready to see it in action! Suppose a developer has attached a resource-based policy to an S3 bucket in our organization and explicitly granted access to identities in an external account:
RCP does not prevent users from saving resource-based policies that are more permissive than RCP allows. However, the RCP will be evaluated as part of the authorization process, as we saw earlier, so the request for external identities will be rejected regardless.
We can prove this by trying to access the bucket using this external account, this time from the AWS CLI:
Scaling RCP deployment in your environment
So far we have seen how we can manage RCP using the console. However, for large-scale governance, you should look at configuring them as infrastructure-as-code and make sure they are integrated into your existing pipelines and Continuous Integration and Continuous Delivery (CI/CD) processes.
If you use an AWS control tower, you can deploy RCP-based controls in addition to SCP-based controls. For example, you can use AWS Control Tower to deploy an RCP similar to the one we created in the previous example that prevents external principals from accessing S3 buckets in our organization. This ensures that RCPs are consistently applied to resources in managed accounts, simplifying and centralizing access control at scale.
In addition, similar to SCP, AWS Control Tower also supports displacement detection for RCP. If the RCP is modified or removed outside of AWS Control Tower, you will be notified of the shift and provided with remedial steps.
Conclusion
Resource Control Policies (RCPs) offer centralized management over the maximum permissions available to AWS resources in your organization. Along with SCP, RCPs help you centrally establish a data perimeter across your AWS environment and prevent unwanted access at scale. SCP and RCP are independent controls that allow you to achieve a different set of security goals. You can choose to enable only SCP or RCP, or use both types of policies together to create a comprehensive security foundation as part of a security-in-depth model.
For more information, see the Resource Control Policy (RCP) section of the AWS Organizations User Guide.
Matheus Guimaraes | @codingmatheus