Each AWS account enables cellular design – it provides a natural isolation of AWS resources, security, partitions access, and establishes billing boundaries. Separation of concern through multi-account setup is a key design principle that customers use to experiment, innovate, and scale quickly on AWS. The basis of a multi-account AWS environment is AWS Organizations, which lets you centrally manage and govern multiple accounts. This central governance of multiple accounts is best done using service control policies (SCPs).

In this post, I will discuss what SCPs are, why you should create SCPs, and the strategy you can use to implement SCPs. I will also discuss how to continue iterating and improving SCPs as your workloads and business needs change. In Part 2 of this blog, I will discuss how you can create SCPs using constructs from AWS Well-Architected.

What are service control policies?

Simply put, SCPs are preventive guardrails. You can use SCPs to define the maximum allowable permissions for AWS Identity and Access Management (IAM) users or roles within your organization across member/linked accounts. As a guardrail, an SCP doesn’t grant permissions. You must create identity- or resource-based policies and attach those to IAM users or roles to grant permissions. Additionally, there are tasks and entities that cannot be restricted by SCPs. SCPs affect only IAM users or roles in the member accounts in an organization, and they have no effect on the management account or service-linked roles. You can refer to effects of SCPs on permissions and IAM policy evaluation logic for further details.

SCPs can be attached to the organization root, OUs, or individual accounts. However we recommend you attach SCPs at OUs rather than to individual accounts to ease policy management and troubleshooting. If you are familiar with the best practice guidance for OUs, and use an Exceptions OU (for those special case workloads that may warrant an exception from security or auditing conditions), it is recommended to attach SCPs directly to such accounts instead.

Note that every OU and account in an organization must have at least one directly attached SCP, if SCPs are enabled. For more details see how the inheritance of SCPs works. SCPs are available in All features mode of AWS Organizations.

Why should I create service control policies?

Using SCPs lets you set preventive guardrails and stop worrying about new or existing member accounts assigning permissions that you don’t want them to assign. SCPs can also help implicitly codify the rules for what you consider to be the best practices for your workloads. For example, if you do not want to incur database snapshot charges for development stage databases on RDS, then you can create a deny SCP for rds:CreateDBSnapshot and attach it to your SDLC OUs. On the other hand, you may not want anyone to accidentally delete RDS database snapshots in production OUs or accounts. In that case, you can attach a deny SCP for rds:DeleteDBSnapshot. If a development team asks for permissions to remove these SCPs, then you can dive deep on why they want that access to see if an exception can be made. These guardrails will instill best practices for your workloads and help your business adhere to generally accepted design principles.

There are two main strategies that customers can use to create SCPs:

  • deny list strategy
  • allow list strategy

Deny list strategy

A deny list strategy works off of the premise that an explicit Deny will always override both explicit and implicit Allow. A deny list strategy starts with a FullAWSAccess SCP (an AWS managed policy), which is by default attached to every OU and account when an organization is created.

If you took no additional action, then the effect of this SCP will let users and roles with appropriate privileges within your accounts grant all IAM permissions. As such, you should create and attach an explicit deny SCP at an appropriate OU or account to deny permissions. Once applied to the OU, accounts within the OU are not able to use the denied API, and permissions cannot be added back lower in the hierarchy.

In the following example, consider DenyAllIAMAccess as an SCP that denies access to IAM APIs. This is a commonly used SCP that improves your security because it limits the ability for users to create IAM roles or permissions. If this SCP is attached at the Workloads OU, then it will deny access to all IAM APIs for accounts and OUs under it while retaining access to other APIs based on the direct attachment of FullAWSAccess SCP to all accounts and OUs from root to leaf.

Permission inheritance in deny list strategy showing every OU and account starting out with FullAWSAccess which is a AWS Managed Policy. Then attaching additional Deny SCPs to OUs or Accounts as needed.

Figure 1: Deny List strategy example with effects of a deny SCP set at an OU level

Allow list strategy

On the other hand, the allow list strategy works off of the premise that an explicit allow overrides an implicit deny. In this strategy, you start by removing the default FullAWSAccess SCP that is attached when an organization is created. Then, you create your own SCPs with an explicit allow, and attach those to accounts and every OU above it, up to and including the root. Every SCP in the hierarchy, starting at the root, must explicitly allow the APIs that you want to be usable in the OUs and accounts below it.

In the following diagram, AllowAllIAMAccess is an SCP that allows access to IAM APIs (iam:*). AllowAllEC2Access is an SCP that allows access to Amazon Elastic Compute Cloud (EC2) APIs (ec2:*). When you attach AllowAllIAMAccess to the organization root, Security OU, Prod-S, and SDLC-S accounts, it allows Prod-S and SDLC-S accounts to grant permission to IAM APIs.  Similarly, AllowAllEC2Access allows access to Prod-W and SDLC-W accounts to grant EC2 related permissions. Even though the Infrastructure branch inherits both of the SCPs from Root, unless those SCPs are explicitly added to the Infrastructure branch, then Prod-I and SDLC-I accounts cannot access any AWS APIs.

Permission inheritance in allow list strategy showing every OU and account starting by removing FullAWSAccess which is a AWS Managed Policy. Then attaching Allow SCPs to OUs or Accounts from the appropriate level up to the root.

Figure 2: Allow List strategy example with effects of allow SCPs set at OU levels

SCPs are JSON policies and follow almost the same syntax as IAM permissions policies. You can review the syntax here. All of the AWS global condition context keys can be used within the Condition element of an SCP based on their availability context.

Using a deny list strategy, account administrators can delegate all services and actions until you create and attach an SCP that denies a specific service or set of actions. Deny statements require less maintenance, because you don’t need to update them when AWS adds new services. Deny statements usually use less space, thus making it easier to stay within the maximum size for SCPs.

Patterns of functional “allowances” for your OUs

As you will see in the best practices for organizational units post, you create OUs following a functional or a control dimension, rather than mirroring your company’s reporting structure. OUs are your way to enforce a cellular structure large enough not to overwhelm policy management and governance, but small enough to contain issues arising from common failure modes. After you have created OUs, you can invest time in creating patterns or decisions of functional “allowances” that will help define your initial SCPs.

Considering permissions governance is an on-going effort, you should index on starting with the least privilege permissions. However, even with the least privilege approach, you may add extra permissions without first knowing if your constituents will use them. You can iterate periodically to review and remove permissions based on actual permissions usage to reduce guesswork. AWS Identity and Access Management (IAM) access advisor can help you easily do that by showing the service permissions granted to an entity (user, role, group) and when those services were last accessed. You can use this information to revise your policies.

Testing effects of SCPs

AWS strongly recommends that you don’t attach SCPs to the root of your organization without thoroughly testing the impact that the policy has on accounts. It is easy to test policy impacts. Simply create a PolicyStagingOU and add non-production member accounts in this OU. Attach your proposed SCP to this OU and test the impacts on member accounts. This helps an administrator with the ability to build and apply changes that they want to make, and in a non-production-impacting way.

Conclusion

As you have seen above, SCPs provide a centralized mechanism for codifying best practices and letting your builders innovate while staying within your security guidelines. You should spend time creating acceptable patterns of permissions based on your business needs, team skills, and security invariants. Iterate often and improve/expand on these patterns as your cloud adoption matures. This will help you build a secure cloud foundation.

To get started with building your own organization, refer to the AWS Organizations Getting Started Guide and create your first SCP. You can also learn more about AWS Control Tower, a AWS-managed governance solution built on AWS Organizations, which includes a number of built-in managed policies.

About the author

Som Chatterjee

Som is a Technical Program Manager at AWS and is based in New Jersey, USA. He likes to create content that our customers can leverage in everyday use. He is passionate about databases, security, and distributed systems.