AWS Cloud Operations Blog
How to implement a read-only service control policy (SCP) for accounts in AWS Organizations
Customers who manage multiple AWS accounts in AWS Organizations can use service control policies (SCPs) to centrally manage permissions in their environment. SCPs can be applied to an organization unit (OU), account, or entire organization to restrict the maximum permissions that can be applied in the scoped AWS accounts.
In this post, we are going to explore the use of SCPs to restrict an AWS account to read-only access. This can be useful in a number of scenarios, including:
- To quarantine an account before conducting a security review.
- To avoid the creation of new resources when an account is staged for deletion.
- To lock down a production account to prevent accidental or unscheduled changes.
Another use case for a read-only SCP is on a suspended OU that contains AWS accounts that have been closed and are waiting to be deleted from an organization. A suspended OU forms part of the AWS Organizations best practices described in the Getting Started Guide. Using SCPs allows an administrator to easily enable or disable a policy without making any changes to AWS Identity and Access Management (IAM) permissions at the AWS account level.
Prerequisites
To follow along with the steps in this blog post, you will need the following:
- An organization in AWS Organizations. For more information, see Creating an organization – AWS Organizations.
- Multiple AWS accounts registered in the organization to test the policy.
- Access to the management or root account in the organization to create the SCP.
In our example, we refer to AWS Single Sign-On (AWS SSO) as a conditional statement in the policy. AWS SSO is used to centrally manage user access to multiple AWS accounts in one place once it is set up in the organization. However, AWS SSO is not required to create SCPs.
Important: SCPs can potentially block access to all IAM users and service roles, including the root user. If SCPs are used incorrectly, they can impact your production workloads. We recommend testing SCPs in non-production environments before enabling them in production.
SCP evaluation
Before we dive into the example, let’s learn more about SCPs in the context of IAM. SCPs are similar to IAM permission policies and use a common syntax. The difference being, an SCP never grants permissions. Instead, SCPs are JSON policies that specify the maximum permissions for the affected accounts.
Any account has only those permissions granted by every parent above it. If a permission is blocked at any level above the account, either implicitly (by not being included in an Allow
policy statement) or explicitly (by being included in a Deny
policy statement), a user or role in the affected account can’t use that permission, even if the account administrator attaches the AdministratorAccess
IAM policy.
When an SCP is present, identity- and resource-based IAM policies grant permissions to principals in member accounts only if those policies and the SCP allow the action. For more information, see the Effects on permissions in the AWS Organizations User Guide and Determining whether a request is allowed or denied within an account in the IAM User Guide.
Figure 1: Determining whether a request is allowed or denied in an account
Using IAM permissions
Before we get to creating a read-only SCP, let’s look at how we would use IAM policies to set an account to read-only. Here is the default AmazonS3ReadOnlyAccess policy in IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
This policy provides read-only access to S3 by defining allowed actions, Get and List. The policy implicitly denies other modification or delete actions, such as Put, Create, or Delete. However, because this policy applies to S3 only, you must list the Get, List, and Describe operations of every AWS service in the Action section to create a complete read-only policy.
The built-in AWS managed policy for job functions, arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
, can be used to address this issue. However, there are no explicit deny statements, which means that if you attached the policy to a principal who already has full administrator access, there would be no effect, no read-only access. To achieve the desired read-only result, you must remove existing permission policies from every IAM user, role, and group, which can be difficult to manage.
One option is to create an explicit deny policy with a NotAction that can be attached to users, groups, or roles in the event the account requires quarantine. The following JSON policy shows what this might look like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"NotAction": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
This policy denies access to all actions except those listed (in this example, the S3 Get and List actions). Here, again, you must maintain a long list of actions for every service you want to allow access to, which can become difficult to manage. You can also quickly hit the managed policy character limit of 6,144.
Read-only SCP
SCPs provide an easy way to control the maximum permissions at an AWS account level so you don’t need to change policies at the IAM level for individual users, groups, or roles. In Figure 2, the policy is applied at the Organizational Unit (OU) level. An OU is a group of accounts, and any account under that OU is in read-only mode.
Figure 2: OU and account structure example with read-only SCP applied to a suspended OU
Here is an example SCP that can be used to deny all actions to all users, except those listed in the conditional statement. You will notice a condition in the example related to AWS SSO. We do this because AWS SSO is set up in our organization and already has a read-only permission set associated with assigned users, so the SCP does not need to override the permission already set by SSO.
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"DenyWriters",
"Effect":"Deny",
"Action":"*",
"Resource":[
"*"
],
"Condition":{
"StringNotLike":{
"aws:PrincipalArn":[
"arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_AWSReadOnlyAccess_*"
]
}
}
}
]
}
Here is the same example, but this one also excludes an IAM role. We exclude an IAM role in this policy because we have production application roles and do not want to block the application’s access. (Remember, SCPs impact all users and roles).
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"DenyWriters",
"Effect":"Deny",
"Action":"*",
"Resource":[
"*"
],
"Condition":{
"StringNotLike":{
"aws:PrincipalArn":[
"arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_AWSReadOnlyAccess_*",
"arn:aws:iam::123456789012:role/mySampleApplicationRole"
]
}
}
}
]
}
In our example, we only allow the IAM role associated with the AWSReadOnlyAccess permission set in AWS SSO. Users must select this permission when they sign in to the console. Figure 3 shows a user with two permission sets for the account named Test-Account-2. The AWSAdministratorAccess permission set no longer works because it is overridden by the SCP deny statement.
Figure 3: AWS SSO sign-in page shows a user with two different permission sets to a single AWS account
Users must have multiple permission sets assigned to them so that when the SCP is enabled, they retain access through AWSReadOnlyAccess. It’s a good practice to give administrators a read-only sign-in option when full access is not required.
Considerations
Although SCPs give an administrator control over a multi-account environment, with great power comes great responsibility! Here are some things to consider when using a read-only SCP:
- The SCP impacts all IAM principals (users and roles) and might therefore impact your running services. This includes roles for Amazon Elastic Compute Cloud (Amazon EC2), AWS Lambda, Amazon Elastic Container Service (Amazon ECS), identity federation, and more. Be sure to exclude any roles that are critical to your running application in the conditional statement.
- All administrator access to the account, including that of the root user, is blocked. Make sure the right people have permission to remove the policy, if required (for example, in the event of an emergency).
- If you are applying the SCP to an OU and using AWS Control Tower, you must move AWS accounts into the OU by updating the AWS Service Catalog item. At the time of this writing, you cannot use AWS Organizations to move an enrolled account to a different OU directly. However, you can use AWS Organizations to apply custom SCPs to your existing OUs created in AWS Control Tower.
- Remember a deny permission will always override an allow, so be aware of the impact and implications.
Conclusion
In this post, we described how SCPs are an efficient way to place an AWS account into a read-only state and prevent modification to any resources by any principal. This approach offers a powerful security response tool and an extra layer of protection for critical production workloads without the need to manage multiple individual IAM policies.
To use SCPs and other advanced governance features, get started with AWS Organizations today!
About the Authors
Amit is a Senior Solutions Architect at AWS. He is passionate about Software-as-a-Service (SaaS) architectures using serverless, analytics and emerging cloud technologies. He has worked on cloud-native development and designing multi-tenant architectures in various industry verticals over a decade, leveraging his experience to help ISV and B2B customers.
Thomas is a Solutions Architect at AWS working with ISVs and B2B organisations within the UK and Ireland. At AWS he helps customers with multi-tenant SaaS transformations. He has over 10 years’ experience in IT infrastructure, particularly with enterprise organisations across aviation, retail and manufacturing industry verticals. He is passionate about automation and working with Serverless technology.