Give Your Account a Security Blanket with SCPs

Service Control Policies are a powerful tool to limit activities within an AWS account.

Prerequisites

  • Complete the Organizations lab

    • Have your AWS Organization

    • Have the Security OU and SecurityAudit account

The Lesson

Today we’ll expand our knowledge of IAM and dig into a cool feature of Organizations called Service Control Policies (SCPs). This is an entirely new policy type which lives outside an AWS account but limits actions within it.

In Write a Simple IAM Policy we learned about identity-based policies. They are entitlements granted to… identities. They determine which users and roles can do what within an AWS account. AWS actually supports 6 major policy types. Of the 6, we’ll spend most of our time on 3 with the greatest impact: the identity-based policies, resource-based policies (we’ll get there) and organization policies (SCPs). Identity-based policies manage who can do what, resource-based policies manage direct interaction with resources (which might be from an entity outside your control, where an identity-based policy isn’t an option) and service control policies limit what actions are allowed in accounts, no matter who is trying to take the action.

Thee other policies add nice security, but we don’t always need or use them. The “Big 3 Policy Types” (my quotes) are essential and should be used consistently. We don’t have any resources yet (aside from that one lonely S3 bucket holding our logs), so we can skip ahead to SCPs.

As you can tell from the headline, I call SCPs the security blanket of AWS because they ‘live’ in your organization, outside your accounts, but restrict actions within accounts. We wrap our accounts in a nice comfy SCP so we can sleep better at night. They’re also great for self-soothing when you have a suspected breach. Like whiskey, but healthier.

SPONSOR SHOUTOUT! Sonrai Security

🔒Never Write an SCP Again

SCPs have the power to secure your cloud… and break your cloud.

That’s why everyone wants to learn how to use them, but with limited time, space, and the risk of breaking something, many organizations shy away from actually using them.

That’s where the Cloud Permissions Firewall comes in. Rather than writing new policies for every identity in your cloud, we automate the creation and deployment of one global policy that removes excess sensitive permissions, quarantines zombie (unused) identities, and disables unused regions and services.  

The best part? You can re-enable any access needed on-demand in Slack, Teams, or email.

The Cloud Permissions Firewall - hands-free SCP management.

SCPs are rather simple in concept. the tl;dr is that they are policies which look and work like an IAM Policy, but live within the organization’s hierarchy. An SCP restrict which actions are allowed in accounts. It doesn’t provide an identity any permissions — it just limits which actions can happen in an account. You still need to provide permission to do the thing separately. SCPs are a preventative guardrail, to use snooty security pro terminology.

Here’s the detail to know about Service Control Policies:

  • SCPs are defined within the Organizations service.

  • They use the same policy structure as identity-based policies, but have certain differences in terms of what’s supported. We won’t hit these for a bit — We’ll cover them later when we handle those cases.

  • SCPs do NOT grant anyone permissions, they only restrict what actions are allowed in an account! Service Control Policies are guardrails which restrict what can happen in an account — they cannot grant permissions to anyone or anything in an account.

    • But there’s a trick! Because SCPs are default-deny, like all the AWS policy types, you need to add Allow permissions. The trick is that these allow (service control) policies say “these actions are allowed in an account, but we aren’t defining who is allowed to use them.” No one can unlock a permission unless they also have an identity-based policy that allows it. I’ll go over this again in a sec.

  • SCPs do not affect your management account, even when applied to your Organization’s root. This is another good reason to limit use of management accounts.

  • You can attach SCPs to OUs or to accounts. There is a limit of 5 SCPs attached to any OU/account. There is also a size limit, based on the number of characters, but it’s large enough we don’t need to worry about it yet.

  • SCPs are inherited. As with identity-based policies, total permissions are everything granted and not denied within the aggregate of all policies in the tree. Since OUs can nest 5 deep, that’s 25 SCPs, plus another 5 at the root, plus another 5 at the account, for a maximum of 35 applicable policies. If you need 35 SCPs it’s time to rethink your life decisions — or at least re-architect a bit.

  • Accounts can move between OUs, and the new SCPs take over. Want the perfect use case for this? Many places have an account nursery OU where they provision and configure new accounts under less restrictive SCPs. Then they kick them out of the cradle into an OU with more restrictive policies, when it’s time to turn them into fully-grown production accounts.

  • SCPs can restrict the root (but not management) account! Guess what we are doing today!

  • But they can’t restrict access to resources from entities outside your account. We will have an in-depth lab on this one, but a simple example is that if you make an S3 bucket public, the SCP won’t evaluate that API call — because it happens outside your account — so you cannot block access that way.

  • SCPs can’t restrict service linked roles (like the one created when we enabled organizations). This is to prevent customers from breaking AWS Services, calling the help desk yet again, and being angry at AWS for letting customers shoot themselves in the foot.

  • Once you turn them on, you need an SCP attached to every OU and account.

That’s a lot of words, and you don’t need to remember it all yet. We’ll keep reviewing and referring to these concepts as we go. Here’s a diagram from AWS, because I’m too lazy to draw my own picture. I’m leaving resource-based policies out for now, since we haven’t discussed them yet.

There are two strategies for using SCPs. You can start with an allow all policy and then start blocking actions through the hierarchy you want to deny (a deny list). Or you can start with no permissions and then build out your allow list. Personally I tend to use, and see, the deny list approach more because it’s more forgiving. You block what you don’t like and leave the rest. An allow list is harder because you need to understand every action and related permission needed for something to work. That said, for high-value accounts you might consider that approach once you have it built out, and know what you need to allow.

And a final warning:

Service Control Policies break things. That’s their job. We use them to break the things we don’t want to happen, but if you aren’t careful you can break the wrong things. Like my cat — he’s a real turdmuffin some days. Never deploy an SCP anywhere in the hierarchy of a production account without testing and fully understanding the implications. Also make sure you check all the SCPs attached to the entire OU branch, before moving a running account into that branch.

These labs help minimize the chances of breaking things and teach techniques to test SCPs and other security controls in a safe place.

Unless you are testing them from my house. Then you have to deal with Goose. He’s just the worst after midnight. Did you know cats are largely nocturnal? I love him, but you’ve been warned.

Today’s Lesson Key Points

  • SCPs restrict actions allowed in an account.

  • They do not grant permissions to anyone or anything — they just wrap guardrails around an account.

  • SCPs are applied at the Organizational Unit or account level.

  • An account inherits all SCPs in the hierarchy above it.

  • SCPs do not limit the management account.

The Lab

We already have an OU and a new account inside it. We will write an SCP that locks out use of the root account, which addresses that lingering concern about not having MFA. We will also add a statement to protect the roles and API calls needed to keep the account in the organization (for example, it protects the service linked role AWS uses to enable all features of organizations). This is a very common policy to apply high up in your hierarchy.

Video Walkthrough

Step-by-Step

First go to https://console.aws.amazon.com and sign in. Then head over to Organizations. You can search for it as usual, or just click it in the upper right corner. This is the last time I’ll screenshot how to get to a service — you all should have that down cold by now. Organizations is a Global service so we don’t set the region.

The first thing we need to do is enable service control policies. Once we do this, AWS will apply the FullAWSAccess policy to every Organizational Unit (OU) and account. Why? All policy mechanisms in AWS are default-deny. If you didn’t have an allow policy, all your accounts would crash and burn like the ending of Scooby Doo Mystery Incorporated (which had two incredible, surreal seasons and a mind-boggling total-Cthulhu ending for a kids show!) On the left menu click Policies and in the main window click Service Control Policies.

This will drop you into the SCP dashboard and show that you have exactly one policy in place: FullAWSAccess, which is allow-all. That policy is by default applied to every OU and account in your organization.

You can see this by clicking AWS Accounts, then picking any level in your hierarchy, then Policies (in the main window). Here I show it for our SecurityAudit account so you can see it has that policy applied directly, at the OU level (inherited), and also at the org root (inherited). Yes, 3 copies. Can I remove it from the account? Nope… not without substituting another policy. Once you enable SCPs, every OU and account must have one. But it does not need to be the FullAWSAccess policy.

When SCPs were first released I learned you need the FullAWSAccess policy the hard way in my test accounts. I read that SCPs don’t grant permissions, they create guardrails. I misinterpreted that to mean they would just add restrictions on top of, and outside of, IAM. My first policy attempt was some deny statements without any policy allowing all. Everything broke. Instantly.

This is the trick to understanding SCPs, and while I said it earlier I’ll say it again. While they don’t grant any users or roles permissions, they take them away. Without an allow-all policy, they take them all away, and you can’t do anything. So they define what actions can run in an account in the first place.

Now go to Policies > Service control policies and click Create policy.

Set the name ProtectRootAndOrg and copy the description “Restrict the root account and the ability to leave AWS Organizations”.

Copy the SCP below, and paste it over the existing JSON policy, then click Create policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "organizations:LeaveOrganization"
      ],
      "Resource": "*",
      "Effect": "Deny"
    },
    {
      "Action": "*",
      "Resource": "*",
      "Effect": "Deny",
      "Condition": {
        "StringLike": {
          "aws:PrincipalArn": [
            "arn:aws:iam::*:root"
          ]
        }
      }
    }
  ]
}

Here’s a quick summary of what that policy does: it denies the API call to leave the Organization, and denies any action by the root user account. We haven’t covered conditions yet, but that should still be pretty easy to understand. And remember, this does not apply to the management account (that first one we created and set the root user MFA for). If we ever do need to use the root account, we can move it someplace without this policy attached — a different OU.

Let’s start by applying this policy to our entire organization. We will actually move it in a later lab, once we get more structure built out. The one problem with attaching it to our org root is that if we ever do need the root user account, we don’t have anywhere in the hierarchy to move it outside the policy’s scope. Later we will set up an incident response OU, then move this policy off the root. You can then move the root account into the IR OU if you need to use it.

Reminder- AWS uses “root” in too many places. When I say “root account” I mean the root user account that is the email you used to create your first AWS account, which is now the management account. “Root” is also the root of your account hierarchy and I will rarely reference it. That root is NOT an account so I’ll refer to it as the “root of your org” or similar.

Now scroll down and paste it into the JSON box:

Then click Create policy.

We have our policy but it’s just in the library now. It’s time to unleash it on the world! Click the checkbox next to the new policy, Actions, and then Attach policy.

Click the checkbox next to Root, then Attach policy.

Boom. Now the root account is fully protected, and even a full admin in an account can’t remove it from the Organization.

If an attacker managed to take control over the root account email for any of your non-management accounts, they could perform password recovery and log in, but they wouldn’t be able to take any action. Later we will set alerts for any use of a root account, which would set off all sorts of alarm bells without any bad outcomes (well, unless you count an attacker pwning your email account).

Lab Key Points

  • You need to enable Service Control Policies in the Organizations dashboard to use them.

  • Once you do, AWS will attach the FullAWSAccess policy to every OU and account. This ensures nothing breaks — without that policy many would.

  • Although we used a policy to protect root and prevent every account from leaving the org, later we will move that policy so sometimes we can use root and remove accounts from an org. But for now they’re great protections as we learn.

-Rich

Reply

or to participate.