Using AWS Service Control Policies To Protect All Your AWS Accounts

If you have multiple AWS accounts, you more than likely are using AWS Organizations. A continually maturing feature of AWS Organizations is AWS Service Control Policies (SCP), which allows you to apply IAM like policies at the organizational level. This does require you to have your AWS Organizations, well, organized (excuse the pun) into OU’s as well as enabled with all features.

This post will take a look at some policies that can go a long way in securing your organization. We are working at the Organizations level though which will immediately affect every AWS account under that OU, so please handle with care.

Pre-Requisities

Image result for aws scp
Courtesy of AWS

AWS SCP: Prevent The Deletion or Stopping of CloudTrails

Note: In this post I've refrained from the use of Whitelist and Blacklists and have moved towards describing the action itself such as Permit, Dissallow, Deny, etc. Thanks to MarcusCarey for raising awareness.

CloudTrail is often our first line of defense when investigating incidents or understanding root cause. Naturally this is something we would not want unavailable. One way to do this is to prevent the disabling or deletion of CloudTrails.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "cloudtrail:StopLogging",
                "cloudtrail:DeleteTrail"
            ],
            "Resource": "*"
        }
    ]
}

Even an administrator in the account would not be able to do so as you can see from the following screenshots:

If your company has a federated model towards AWS, you may want to just have control on specific CloudTrails that are centrally managed by the IAAS team or Information Security. This would allow account admins to create and delete CloudTrails as they wish without affecting the integrity of your critical CloudTrails. Here is an example:

{
     "Version": "2012-10-17",
     "Statement": [
         {
             "Effect": "Deny",
             "Action": [
                 "cloudtrail:StopLogging",
                 "cloudtrail:DeleteTrail"
             ],
             "Resource": "arn:aws:cloudtrail:::trail/securitytrail"
         }
     ]
 }

So if we try to disable a CloudTrail covered by an SCP above, we get the following error:

Error message when trying to delete or stop CloudTrail

Coupled with a CloudTrail applied at the Organization Level this would provide ultimate management of CloudTrail security across the AWS Organization.

AWS SCP: Not Allowing Older Generation Instances

As AWS builds and expands its infrastructure, they continually release newer and newer instance models. To push people into using those instances (as well as capitalize on that infrastructure) they increase the pricing of older and previous generation instances. So utilizing a t3.nano would be more expensive than a t2.nano for example:

t3.nano on-demand pricing – 6/9/19
t2.nano on-demand pricing – 6/9/19

So we’ll use SCP’s to prevent people from launching previous generation instances. They can still start/stop instances, but will not be able to launch new instances.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RequireNewGenerationInstanceType",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:InstanceType": "t2.micro"
                },
                "StringLike": {
                    "ec2:InstanceType": [
                        "m*",
                        "r*",
                        "x1*",
                        "u-*",
                        "z*",
                        "p*",
                        "g*",
                        "f*",
                        "i*",
                        "d*",
                        "h*"
                    ]
                }
            }
        }
    ]
}

This IAM policy guide was super helpful when trying to build an SCP policy to disallow multiple instance types. Specifically the condition blocks:

<condition_block> = "Condition" : { <condition_map> }
<condition_map> = { 
  <condition_type_string> : { <condition_key_string> : <condition_value_list> },
  <condition_type_string> : { <condition_key_string> : <condition_value_list> }, ...
}  
<condition_value_list> = [<condition_value>, <condition_value>, ...]
<condition_value> = ("string" | "number" | "Boolean")

Now when we try to launch a t2 instance we get the following error:

Error when trying to launch a instance not allowed by an SCP

AWS SCP: Not allowing outside West and East

AWS is global, but oftentimes we are operating in only a few regions at most such as us-east-* or us-west-*. If an attacker is trying to fly under the radar, they will launch instances in an obscure region where there is usually a lack of oversight.

To minimize our attack surface and make our lives a little easier, let’s limit where resources can be started in our AWS accounts. In this case let’s limit to just us-east-1 and us-west-2. This is usually more than enough for many companies, especially smaller organizations.

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

Here is an error when trying to launch an instance in a region not covered by the SCP above:

Error when trying to launch from a region no permitted above

Notice the following statement:

            "NotAction": "ec2:describe*"

The reason we may need additional describe capabilities is to have audit capabilities into the account. A lot of applications and tools are running queries against accounts to understand their posture either from a billing, resourcing, or security perspective.

However I still receive some errors even with the describe statement above:

Unfortunately, AWS will not allow you to do the following in IAM:

*Describe*

or

*:Describe*

I don’t want to enumerate all the service desribe clauses possible, so I am fine with the above. Up to you if you want to add additional describe statements.

AWS SCP: Fine Print

Some things worth noting that AWS SCPs do have their limitations. I suggest reading the following references, maybe a couple times, before applying to your Organization.

Managing AWS Organizations Policies

AWS SCP Effects on Permissions

Tasks and Entities Not Restricted by SCPs

SCPs do not apply to service-linked roles

AWS SCP: Conclusion

As you can see AWS SCPs are very powerful. They are an excellent high impact preventative security tool. Preventative security pays dividends above corrective and detective controls and should be employed where possible. However, this does mean we shouldn’t implement detective and corrective controls throughout. It’s good to have a backup as you can imagine. In the end I highly recommend the use of AWS SCPs throughout your AWS organization.

About the Author Ayman Elsawah

Cloud Security | Author | Educator | Coffee Nerd

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: