The new features are still flooding in! With less than a week to go before Re:Invent 2019 it is almost overwhelming how much AWS has released in the last week or two! It’s usually an exciting time of year for all things AWS but this year feels extra special!

One of the many new features announced is the improved support for Attribute-Based Access Control or ABAC via SAML to control access to various resources and accounts within AWS based on your existing Identity Providers attributes assigned to your users (such as department, cost code etc).

In this post, I am going to dive how you can set up Single Sign-on via Google GSuite and how we can leverage this new capability from AWS to allow or deny access to IAM calls based on information managed directly within GSuite.

The logic in this article will apply to any SAML compatible identity providers and I’ll link to a few articles about those later on.

SSO to AWS via GSuite

It may be obvious, but the first major requirement of this process is… Google GSuite . To make use of SSO & SAML you’ll need to have a GSuite (vs normal Google) account

I have used GSuite for many years and it, to me, is by far one of the best cloud productivity platforms. It’s Sheets, Docs & Slides offering has become more and more powerful over the last 5 or so years and It’s collaboration features are still king!

I highly recommend. Can you tell?!?

Setting Up SSO

SSO via GSuite is easy to configure. It will require a few tweaks to your GSuite user configurations so you can add allowed roles to individual users.

To start, log into the GSuite admin console with a Super Admin user

Once we’ve completed these steps you’ll be adding something like this to your users:

1. Get your GSuite SAML Info

We first need to get some info about our GSuite estate to provide AWS later and so we can configure our users correctly (next bit)

Once you’ve logged in, go to your GSuite SSO Settings Take note of the of your Customer ID at the end of the SSO URL Next Click DOWNLOAD IDP METADATA - We’ll need this shortly to supply to AWS

2. Adding new Attributes to your GSuite users

Out the box, GSuite Users don’t have any appropriate attributes to map to IAM roles. So we need to add this using Google Developer APIs. We will add an SSO section with role as an attribute we can update.

Whilst still logged in to GSuite, go to this page This will open a Google Developer page which provides us with a way to add new fields to your GSuite users (Bookmark this for future work if needed) In the customerId field, provide the Customer ID you noted earlier ^ In the Request Body, paste the following

{ "fields" : [ { "fieldName" : "role" , "fieldType" : "STRING" , "readAccessType" : "ADMINS_AND_SELF" , "multiValued" : true } ] , "schemaName" : "SSO" }

Click Execute If you’ve not run this before, you’ll likely be asked to Authorise the API first. Follow any prompts and check the execution went through You should now get a successful response. To double-check it worked, you can try to execute again and you should get an error showing the new field, SSO -> role already exists



What’s going on? The API above will add a new section to your user attributes called SSO which in turn will have a field you can add more values to. We will update our applicable users later on with the AWS IAM roles and Identity Provider info once we’ve set up AWS

3. Create an SSO App in GSuite

Next up, we are going to create an SSO App in GSuite. This will be the way we get our GSuite users to make use of the IAM Roles and use SSO.

Go to the SAML Apps section under Apps in GSuite Click the + icon in the bottom right-hand corner to create a new App. Search for Amazon Web Services and select it We already have the info from the next screen so we can ignore this. Click Next Hit Next again Now you should see a screen with AWS SAML URLs listed under ACS URL and Entity ID There is a field with Start Url - this will be the URL you’ll get redirected to once you’ve successfully signed in.



TOP TIP: Set this to the console page for the region you normally use. So for me, https://eu-west-1.console.aws.amazon.com/console/home?region=eu-west-1# . This makes things neat and tidy when Signing in and getting put into a random region. Keep Name ID set to Basic Information > Primary Email - This is the value you’ll see in CloudTrail and will be included as the users “name” within AWS when logged in. Hit Next

Attribute Mapping

On this next screen, we need to tell GSuite which Attributes to map to SAML attributes.

The two populated here are RoleSessionName and Role .

For RoleSessionName set the value to Basic Information > Primary Email

And for Role set the value to SSO > role (created earlier)

Adding ABAC Attributes

This is where we will now setup which extra attributes we wish to use in IAM policies as PrincipalTag keys/values.

You can add what you like here but the rest of the post is based on a department tag which will come from the built-in GSuite attribute for Department.

So,

Click Add New Mapping Enter the following:

Application Attribute Category User Field https://aws.amazon.com/SAML/Attributes/PrincipalTag:department Employee Details Department

Click Finish!

If you wish to add other attributes later, you can come back to your SSO Apps and Click Attribute Mapping

Now, when you see the AWS SSO App listed, select the three dots on the right of the listing and click ON for everyone

We’re done with GSuite for now. We’ll come back to it in a bit to map our IAM roles we’re about to create to our users.

Setting Up AWS

Next up, we need to configure a few things in AWS itself to make use of what we’ve just done in GSuite.

1. Setup a new Identity Provider in AWS

First, on the list, we need to set up a provider in IAM that will recognise our GSuite account.

Login to your AWS account with sufficient IAM permissions to setup Identity Providers Go to Idenity Providers under IAM Click Create Provider From the Provider Type drop-down, select SAML Within Provider Name put what you like - I’ve gone for the creatively named GoogleApps Upload the IDP Metadata file you downloaded from GSuite earlier Click Next Step then Create on the following Screen Once you’ve created for Identity Provider, Select it and grab its ARN -(We’ll need this later to tell GSuite which Account we wish to access)

Multiple Accounts Keep in mind that the above steps would need to be completed in all AWS accounts if you want to provide an SSO experience to them all. There are ways to simplify this, such as using IAM Switch Role to access other accounts from a single place but your mileage will vary.

2. Create IAM Roles to assume with SAML

Here we will create the actual IAM roles we want our SSO users to work as. The purpose of this article is to show how we can make use of restricted access with different SAML attributes I would also recommend you create a couple of levels of access for your use whilst getting things set up at scale.

I find it useful to have a Read-Only role, a general use role and an admin role. This way I can give myself an appropriate level of access but still have an easy path to elevate this if needed.

I am going to talk you through creating two roles, 1 for general account usage so you can make sure you’re happy with SAML/SSO without having to worry about ABAC and the more interesting role, one that is restricted to only EC2 actions but only if the resources are tagged with a Team that matches my GSuite users department tag

Creating the Normal Role

Admin Role

Go to IAM > Roles and click Create Role Select SAML 2.0 Federation as your Role Trust Entity From the SAML Provider dropdown, Select your Identity Provider from before And then Check the Allow programmatic and AWS Management Console access radio button. You’ll see the console pre-fill the attribute and value fields.

Now from the list of Policies, select the AdministratorAccess policy and hit Next If you wish to spend some time crafting a different level of access based on your needs go ahead and Click Create Policy and work from there. Alternatively, you can use any previously created policies. Tag your role as you wish and hit Next See an article I’ve linked below for an example of ABAC with IAM roles based on role tags Give your role a Name - I’m going to go for GoogleAppsSU then hit Create

You should now have a new role, we’ll come back to it shortly

ABAC Role

Follow the same steps as above but this time pause on the Policy Selection Click Create Policy I am going to base this policy on permissions being permitted to GSuite users that have a Department of Cloud Engineering. So my Policy below will reflect that

{ "Version" : "2012-10-17" , "Statement" : [ { "Effect" : "Allow" , "Action" : "ec2:*" , "Resource" : "*" , "Condition" : { "StringEquals" : { "ec2:ResourceTag/Team" : "${aws:PrincipalTag/department}" } } } , { "Effect" : "Allow" , "Action" : "ec2:Describe*" , "Resource" : "*" } , { "Effect" : "Deny" , "Action" : [ "ec2:DeleteTags" ] , "Resource" : "*" } ] }

The key to all of this is:

"ec2:ResourceTag/Team": "${aws:PrincipalTag/department}"

You can change the ResourceTag/Team to be any tag key you like and in this case, we’ve picked the department PrincipalTag we defined earlier. If you want to change the PrincipalTag to something else, just remember to update both the GSuite attribute mappings and the trust policy to include new attributes.

Attach this policy to your new ABAC restricted IAM role and name the IAM Role something clear to you. I am going to call mine Cloudy Goodness

So we should now have two roles we can use. Nearly there.

3. Update Trust Policies for each role to include our custom SAML attributes

For each of the two new roles, 1. Find the role in Roles 2. Click the role 3. Select the Trust relationships tab 4. Click Edit trust relationship

Update the trust policy to reflect the below

{ "Version" : "2012-10-17" , "Statement" : [ { "Effect" : "Allow" , "Principal" : { "Federated" : "<YOUR Identity Provider ARN from earlier>" } , "Action" : [ "sts:AssumeRoleWithSAML" , "sts:TagSession" ] , "Condition" : { "StringEquals" : { "SAML:aud" : "https://signin.aws.amazon.com/saml" } , "StringLike" : { "aws:RequestTag/department" : "_" , "aws:RequestTag/<any other attributes you are mapping to SAML>" : "_" } } } ] }

Save your changes

Checkpoint

So we’ve done quite a lot already. Hopefully, you are still with me. To briefly recap what we’ve done…

Configured an SSO App in GSuite set to work with AWS Added new attributes for role to our GSuite users Set up an Identity Provider in our AWS account Created new roles to use with the Idp Configured the roles to include our custom attributes

Lastly, we need to now update our GSuite user to include our new roles in the SSO > role attribute.

To do this, grab the ARN’s of the two new roles.

Adding IAM Roles to GSuite user

Whilst logged in to GSuite Admin, Search for the user you want to work with and select it.

Now Select User Information

Set the Department to a useful value - In this case, I’ve set mine to Cloud Legends .

to a useful value - In this case, I’ve set mine to . Next, you should see a section for SSO . Select it so you can add a role value.

. Select it so you can add a role value. Now, the important part.

For each of your roles put the following format as the role value (you’ll have the option to add another once you fill in the input.

<role arn>,<Idp Arn>

Once you’ve got these added and Saved it should look a little like this:

Phew! That was a lot but we should be done!

Now comes for the moment of truth.

If things have worked correctly, you should now see a new app to load for your GSuite user

.

If you click that App, you should now end up on a screen like below:

.

Select either of the roles and confirm log in works. If you get any errors make sure to step back through all of the previous steps to make sure you’ve not missed something. This process is very specific so all elements need to line up for success.

If all is well then we should now be able to demonstrate ABAC in action.

ABAC in action

How you decide to do this will vary greatly so for this next bit I am going to show a before and after with ABAC set up (as above) against an EC2 Instance. My account features two roles. One with admin access and no ABAC in the IAM policies.

The other is restricted to only permit actions (except describing ec2) for resources tagged with the users matching department.

To show this in action, notice how I get access denied when I try to start an instance:

This is because there is no tag for Team that matches my user which has a department of Cloud Legends .

If I now apply a Team tag (using my other role) and set a value to Cloud Legends you can see I can now successfully start my instance.

And now we see the instance has successfully been Started

Yay! As we can see the difference between the two roles - 1 with no restrictions and 1 with specific requirements for a Team tag matching our user’s department. Our admin user was able to tag a resource which unlocked permissions on that resource for the ABAC restricted role.

Wrap Up

There is clearly a bit of effort required to get SSO via SAML setup and then a few extra steps to make use of ABAC.

I hope this post has been able to demonstrate that although there is a bit of setup, it’s not actually that complicated to set up once you’ve got the building blocks together.

The obvious next steps of this to me is to wrap up the IAM Roles/Policies into a CloudFormation template that we can roll out to more accounts. This post has made no assumptions on how many GSuite users you have but the steps are the same for a simple setup. You may want to think about how you decide who get’s what roles and when which is an incredibly important piece of work if you intend to scale this process out.

Personally, I am happy with the new capabilities on offer here and think it is on the right path to making ABAC incredibly powerful within AWS.

As usual, let me know what you think and provide any feedback on the article if you think I’ve missed something or anything seems inaccurate!

Enjoy!

 Neil

Useful Links