Identity & Access Management (IAM) remains today one of my favorite services from Amazon Web Services. It’s sort of a Swiss army knife for security, with a tool for almost every challenge you encounter. But I recently encountered one challenge I struggled to solve with IAM: managing read only AWS privileges across multiple accounts is a decentralized environment.

The Problem

Let’s use a fictitious enterprise called Acme for our example. Acme has 200 AWS accounts in use across the organization, each created and managed by different people in different departments (note: a common adoption pattern in the enterprise). The IT team responsible for these accounts does not have administrative / power user access to these accounts, and has only recently convinced the account owners to link them into a single payer account. But now IT would now like to request read only access from each of the account owners to allow them to gather additional data from the accounts that could be used to provide value back to the broader organization (e.g. security monitoring, cost & usage reporting). IT has asked permission from the account holders for enabling this access, and they have only one requirement: the read-only access provided to IT must not provide access to data with these accounts (e.g. fetching objects from S3, directly accessing EC2 instances)

Given the effort IT is about to undertake, they are looking for a way to grant read-only privileges once that will not require future maintenance by the account owners.

Searching for a Solution

Myself and Andi Abes brainstormed this problem the other day, working through all the tools we knew in our IAM Swiss army knife (e.g. cross-linked accounts, roles, delegation). In the end we came up with a simple and obvious solution that can work either with IAM users or IAM roles. The solution leverages a few core features of IAM:

  • AWS default policies - With the introduction of IAM, AWS provided default policy templates. For example they offer a policy ReadOnlyAccess that grants non-destructive read access to everything in an account. Unfortunately for Acme IT, it grants more privileges than their account owners are willing to provide.
  • Managed policies -  In February of this year AWS introduced what they call managed policies. As part of this release, AWS changed their ReadOnlyAccess to a managed policy that can be changed by Amazon as new services are introduced. This means that additional read only privileges created by AWS will automatically be granted to any user / role based on this managed policy.
  • Multiple policies - AWS allows for multiple policies to be associated with a user. We used this feature in a previous post called Denying Destructive Privileges in AWS.

The Solution

The solution Andi and I came up with is not perfect but definitely workable. I will describe the process for doing this via IAM users, but the process is nearly identical if you go with roles. Here it goes:

Login to the AWS Console as a user and go to the IAM service.

Create a new IAM user, download the credentials.

Edit the user and attach an AWS managed policy (e.g. ReadOnlyAccess). By attaching an AWS managed policy that closely mirrors your use case, you will automatically receive the changes made by AWS in future versions of the policy.

Attach an inline policy to this user that explicitly denies the privileges in the managed policy you do not want granted to your user. For example, the below policy will deny privileges in the ReadOnlyAccess policy that provide access to data (e.g. fetching S3 objects).

{ "Version": "2012-10-17", "Statement": [   {     "Action": [       "dynamodb:GetItem",       "dynamodb:Query",       "ec2:GetConsoleOutput",       "elasticbeanstalk:RequestEnvironmentInfo",       "elasticbeanstalk:RetrieveEnvironmentInfo",       "redshift:ViewQueriesInConsole",       "route53:Get*",       "route53:List*",       "route53domains:GetDomainDetail",       "s3:Get*",       "sns:Get*",       "sqs:ReceiveMessage"     ],
"Effect": "Deny", "Resource": "*" } ] }

Now repeat the above steps for each account.

There is one obvious downside of course: the managed policy may in the future grant privileges that could provide the user more privileges than you might want. But if you select the right managed policy with the right inline deny policy, you can minimize the frequency of this occurring.

Related posts: Task Based Access Control in the Cloud, What To Do In Response To Code Spaces