The Challenges of Securing Data Access in the Cloud, Part 2 (of 4)

Part 2 (of 4): A closer look at IAM policies

Arick Goomanovsky By Arick Goomanovsky
The Challenges of Securing Data Access in the Cloud, Part 2 (of 4)

In this second post of our series, I will continue to share and examine my view on why identity and data security in the cloud is so complicated, and why many organizations get it wrong.

In the last post, I introduced AWS IAM - a powerful tool leveraging more than 2500 permission configurations (and counting), to enable fine-grained control over which actions can be performed on a given resource in the AWS environment. Not surprisingly, this degree of control introduces an unacceptable level of complexity for developers and DevOps teams. Rather than focusing on getting their application to run correctly, they need to learn precisely which AWS permissions the system needs. If they don’t grant the necessary permissions, the application will fail, leading to overly permissive deployments (“role shopping”) that provide attackers with a large foothold from which to further penetrate a cloud environment and jeopardize AWS cloud security.

But let’s take it one step at a time. Let’s first look at the basic elements of the AWS IAM mechanism - the IAM policies. I will assume that you are familiar to some extent with the concept of AWS IAM policies. In case you are not, there is plenty of available AWS documentation. In some cases, the long and detailed AWS documentation can over-complicate concepts, so you may need to read from other sources as well.

AWS policy
An AWS IAM policy allowing the principal to list an S3 bucket

To understand why IAM policy is complex, let’s revisit our ultimate goal: achieving least privilege by reducing excessive permissions. To this end, let’s start with a simpler task: mapping all the resources within our AWS organization that a specific IAM user can access. To do that, we have to map out all of the policies related to the user and deduce the associated access limitations by following the 8-step process.

1. Examine policies

Examine the policies attached directly to the user. Specifically, examine:

  • Managed policies – These are standalone policies that come in two varieties:
    • AWS managed policies that are created and managed by the CSP
    • Customer managed policies that you create and manage in your AWS account. Customer managed policies usually provide more precise control over your policies than AWS managed policies.
  • Inline policies – These are policies that you create and manage, and that are embedded into the user identity directly.

2. Examine IAM groups

Examine the IAM groups the user belongs to. These might also have policies attached to them which, indirectly, may grant the user access permissions to additional resources. Just as with the user itself, groups may have both managed and inline policies attached.

3. Map IAM roles

Map all the IAM roles a user may assume. And IAM role is another IAM identity that you can create in your account and grant specific permissions (by attaching policies, of course). It is similar to an IAM user, but instead of being uniquely associated with one person, a role can be assumed by anyone who needs it. Roles are often used to grant access permissions to applications.

Now that we understand that a user may assume a role, we have to map all such roles and their respective policies (think of this as similar to the previous step, just replace groups with roles).

4. Grab a coffee

Think we are done? Not quite. But I suggest you make a cup of coffee before we go on. The most exciting part is still ahead of us, and you’ll definitely need the energy.

Grab a coffee

5. Examine AWS resources

Now we will leave our user alone and examine (all) the resources available in our AWS organization. You might wonder why we are doing this. The answer is resource-based policies: IAM policy documents that you attach to a specific resource such as an AWS S3 bucket. Such policies may grant a user permission to perform actions on that bucket directly, independent of all the directly and indirectly attached policies we have discussed so far.

Therefore, we have to review all resource-attached policies. To do this comprehensively, we should go over all the relevant resources across our organization. This may sound tedious but, hey, we never promised you a walk in the park.

AWS S3 bucket

6. Review ACLs

Continue examining the resources. This time we review Access Control Lists (ACLs). These are similar to resource-based policies and allow control over which identities in other  accounts may access the resource. Since ACLs cannot be used to control access for identities within the same account, you can skip all resources in the same account as the user. But don’t forget resources in other accounts within your AWS organization. By the way, this is the only IAM policy type that does not use the JSON policy format, and not all resources support ACLs.

Access Control Lists (ACLs)
A default ACL that grants an S3 bucket owner full control over the resource.

7. Review user permissions boundaries

Review the user’s permissions boundary. Reviewing cloud IAM user permissions boundaries is an advanced feature that lets you set the maximum permissions a user, group or role might have. Plainly put, when you set a permission boundary, the user can perform only the actions allowed by both the attached policies AND the permissions boundaries. Be extremely careful with the details since permissions boundaries do not affect every IAM policy in the same way. For example, resource-based policies are not limited by the permissions boundary and an explicit deny in any of these policies overrides the allow.

8. Review service control policies

Finally, take a quick look at your service control policies. These are conceptually similar to permission boundaries defined on all the identities (i.e. users, groups, and roles) within your account. An SCP is defined at the AWS organization level and you may choose the specific accounts the IAM policy applies to.

Remember: All of these policies may have both ALLOW and DENY statements, so be very careful when combining the various statements and deciding the exact type of access an IAM user has to a specific resource.

What about automation?

Clearly, this is not something anyone wants to do manually. Fortunately, a few years back, AWS released a tool called IAM Policy Simulator. This tool can be very helpful in automating elements of our process. As you can see below, the tool allows you to select an AWS entity - an IAM user, group or role.

IAM Policy Simulator.
Selecting an entity type in IAM Policy Simulator.

Here we’ve selected the user dorki. Once the entity is selected, select a service type. This could be, for example, a Relational Database Service (RDS) or an S3 bucket service, and here we choose the AWS Secrets Manager. Next, select the specific (or all) actions you’d like to check. Once you hit the Run Simulation button, each action will be marked as allowed or denied based on the list of policies attached to the specific entity.

Identifying allowed and denied actions in Policy Simulator
Identifying allowed and denied actions in IAM Policy Simulator.

At first, it seems that AWS has made it easy for us. It appears that all we have to do to understand what resources our IAM user dorki can access, is to review all the resources in IAM Policy Simulator and we are done. Well, not quite… Although AWS IAM Policy Simulator is a good tool to start with, it is far from mature. For example, remember Step 3 suggested to review all the roles our user may assume and their policies? Well, the IAM Policy Simulator doesn’t do this. It also does not take into account ACLs (Step 7), or permission boundaries (Step 8). If you decide to reverse your query and ask which users may directly or indirectly access a specific resource (e.g. S3 bucket with sensitive data), then the IAM Policy Simulator becomes even less useful. Eventually, you are back to doing things manually, or writing your own scripts. Alternatively, you can call my colleagues at Ermetic and learn how we can help.

Now that you have mastered this process, you can move on to more complex use cases. For example, you might want to know which resources a federated user may access. But we will leave this to my next post.

Read Part 3 now...