Mastering AWS Organizations Service Control Policies

Service Control Policies (SCPs) are IAM-like policies to manage permissions in AWS Organizations. SCPs restrict the actions allowed for accounts within the organization making each one of them compliant with your guidelines.

SCPs are not meant to grant permissions; you should consider them as advanced Deny/Allow list mechanisms that restrict the set of actions allowed within an organization. The only way to grant permissions to IAM Users or Roles is by attaching IAM permissions policies.

AWS Service Control Policies

Service Control Policies can be used in a Defense in Depth strategy adding an additional layer of protection to mitigate unknown vulnerabilities on complex infrastructures. From one perspective, Organizations policies like SCPs could be considered unnecessary but according to AWS’s strategy, redundant security controls in different layers are the key to minimize attacks if a vulnerability in another layer is exploited.

At the account level, IAM Permissions + IAM Permission Boundaries overlap with SCP. You could even consider SCP unnecessary because the boundaries are already defined using IAM Permission Boundaries. But what if a user is able to perform a permission escalation exploiting a vulnerability in your policies?

Let’s assume you granted specific permissions to Billy with an IAM user. Billy can now manage multiple EC2 instances in Oregon. Billy is creating a new EC2 instance and, by exploiting a vulnerability that you haven’t noticed before, he is able to create a new Role and attach the PowerUser policy to it. Billy is violating several of AWS Organizations’ guidelines, and he is breaking the least privilege principle introducing a serious flaw, but your security controls are ineffective because they are applied to the user assigned to Billy, not to other IAM users/roles within the account. A Service Control Policy could prevent Billy from violating the guidelines and best practices. In effect, the policy acts as a redundant layer; with the right statements, you can prevent permission escalations and enforce best practices.

At Cloud Academy, we manage AWS Organizations with thousands of accounts, and we identified the following use cases as a good starting point for our Service Control Policies adoption.

  • Deny root user access: prevent takeover attacks using the root user account.
  • Enforce MFA: require MFA enabled for specific actions.
  • Disable expensive services: deny any action for services that won’t be part of the infrastructure.
  • Protect monitoring, auditing, and security tools: prevent users from disabling or modifying AWS CloudWatch, Config, GuardDuty, CloudTrail.
  • Restrict regions: restrict regions allowed in your Organization for geographical proximity or regulatory needs.
  • Restrict EC2 AMI sharing and visibility: prevent AMIs to be public or shared with other AWS accounts.

Structure

The Service Control Policies structure is similar to IAM Policy and composed of multiple statements. Each statement could define Effect, Action, Resource, and Conditions.

{
  "Statement": [{
    "Effect": "Deny",
    "Action": "ec2:*",
    "Resource": "*"
  }]
}

Deny any EC2 action for all resources.

Scope

A Service Control Policy can be applied to all accounts (Root of the Organization), Organization Units (OU), or single accounts. SCPs attached to the Root of the Organization are applied to every account within the organization.

Limitations: Service-Linked roles and management account are not affected by SCPs.

Evaluation

An action performed by an IAM User/Role could be considered allowed if all the following conditions are satisfied:

  • The action is allowed with an IAM permission policy.
  • The action is allowed by the permission boundary attached.
  • The action is allowed by the SCPs attached.

If any of the conditions listed above are not satisfied, the action is not allowed.

Advanced Conditions

Because Service Control Policies are policies applied at the organizational level, you are likely to use conditions operators and conditions keys that you may not be super familiar with, working with standard IAM policies.

These are the most frequent operators and keys that we used during our SCP adoption.

ArnEquals/ArnLike: restrict access based on comparing a key to ARNs. String operators like StringEquals don’t work!

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Deny",
    "Action": ["iam:*"],
    "Resource": "*",
    "Condition": {
      "ArnEquals": {
        "aws:PrincipalARN": "arn:aws:iam::*:user/guest"
      }
    }
  }]
}

Deny any IAM action for all resources performed by the user called guest. 

aws:PrincipalARN: compare the ARN of the principal that made the request with ARNs specified in the policy.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Deny",
    "Action": ["iam:*"],
    "Resource": "*",
    "Condition": {
      "ArnNotEquals": {
        "aws:PrincipalARN": "arn:aws:iam::*:role/Admin*"
      }
    }
  }]
}

Deny any IAM action for all resources performed by the IAM Roles that don’t have Admin prefix. 

aws:RequestedRegion: compare the AWS region that was called in the request with regions specified in the policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "us-east-1",
            "us-east-2",
            "us-west-1",
            "us-west-2"
          ]
        }
      }
    }
  ]
}

Deny any action for all resources performed outside the U.S. regions. 

More operators and keys are in the official documentation: AWS Reference Policies Elements Conditions Operators, AWS Reference Policy Conditions Keys.

Deny list and Allow list approaches

Deny list: any action on every resource is allowed by default; additional policies restrict actions/resources with explicit denies.

Allow list: any action on every resource is denied by default; additional policies allow actions/resources.

AWS applies the least privilege principle for both IAM policies and AWS SCP. As a result, no policies mean no actions allowed; consequently, the deny list approach requires an explicit SCP policy that allows actions by default as a foundation. The allow list approach can be implemented without an additional policy — any action is not allowed by default.

By default, AWS Organizations creates a Service Control Policy called FullAWSAccess that allows every action putting the foundation of a Deny list approach.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}

The above SCP, attached to the root of the organization, allows every action in every member account. Keeping in mind that explicit Deny overrides Allow, new SCPs could be introduced to restrict the set of actions allowed.

SCP Deny list approach

The Deny list approach is desirable in most cases, since allowed actions within an organization are likely to be greater than not permitted actions, and corner cases can be covered with Conditions.

In the Cloud Academy implementation of AWS Organizations, the variance of actions performed in Organizational Units is too high, and the Allow list approach is not a sustainable solution for us. Moreover, introducing SCPs in an existing organization could lead to unpredictable permission issues working with several Organization Units and accounts. The Deny list approach is often the easiest solution and leaves more freedom with fewer operations.

Testing and debugging

Service Control Policies are powerful and must be properly tested before attaching them to the root of the organization or critical Organization Units. If applicable, the Deny list approach can be introduced progressively without disruptions and represent the recommended option.

SCPs can be easily attached to one or a small number of member accounts to test impacts before rolling out to the entire organization. Once attached, policies are immediately applied to the accounts.

AWS suggests using service last accessed data in IAM and AWS CloudTrail to monitor and understand usage at the API level. Either of these tools could be used to find actions not allowed by mistake and detect potential vulnerabilities.

Conclusion

At Cloud Academy, we manage AWS Organizations with thousands of accounts that can be categorized based on the use case. Service Control Policies have been quite effective to enforce guidelines and limit the actions allowed once we defined the right categorization. SCPs applied to the Root of the Organization are likely to be too generic and ineffective, but with solid categorization on Organization Units with clear boundaries, you could introduce strong restrictions and minimize potential vulnerabilities exploited at the account level.

Cloud Academy