Malware Technology

Personal Journal on Defensive Cybersecurity, DevOps, and anything that comes to mind


Using AWS CLI or Terraform with Credentials from Google Workspace SSO

The final product



In my current lab environment, I AWS to provide services that would otherwise be difficult for myself to handle (while trying to follow best practices), such as key management and replicated file storage. I use Google Workspace in order to provide a single sign-on experience across applications, whether they support only LDAPS or more modern Auth N&Z flows like OIDC and SAML.

With such a combination of services, I have my lab configured such that I can log into the Google Workspace user dashboard and assume a preconfigured role for a particular account from a selection page. I do this through setting up a SAML trust relationship with each AWS IAM role that I wish for users of my lab organization to be able to access. Once the role is assumed, the user is able to access the AWS console with the permissions of the role.

Through this method, I can focus on scoping permissions to roles instead of to users. This subtle difference can help prevent permission creep whereby a user may over time become overprivileged. Applying permissions directly to users can create an issue with not knowing what each individual can access. This method of granting authorization prevents that mishap by enabling organizations to easily see the permissions to which a user has been assigned via the roles they can assume.

The Issue

This setup has worked great, but there is one gaping problem that has not been seriously addressed by AWS for years (and it’ll be easy to guess why that is the case).

That problem is enabling API access (via the CLI or Terraform) through credentials assumed after authenticating to the Google Workspace IdP.

Multiple Sources of Identity: An Anti-Pattern as a Workaround

How do people and organizations work around this?

One anti-pattern that I have seen is long-term utilization of IAM users for engineers or people who otherwise need access to AWS. In doing so, multiple sources of identity are created in their system; at least one for access to SSO via their IdP, and one for AWS via their IAM user. By doing this, they can create api keys that can be used in the configuration of the AWS CLI. While the ease in doing so can be alluring, and even if the organization tends toward the usage of roles via policies applied directly, having multiple sources of identity always becomes problematic in auditing user permissions and granting/removing access.

Possibilities?

The AWS API supports assuming a role via a SAML response. As previously mentioned, I have integrated Google Workspace with AWS by setting up trust relationships in roles that I wish users to be able to assume. This should, in theory, be easy to do.

However, we run into an issue because Google Workspace does not provide a supported solution to getting a SAML response programmatically. Unsupported workarounds do exist such as aws-google-auth. Because they are not officially supported by either Google or Amazon, I steered clear of it.

Solution

As a result, I solved the problem by utilizing AWS SSO with Google Workspace as an external IdP. It’s not a perfect solution (and I’ll detail the issues below), but it was the best available.

You might ask: what is AWS SSO?

AWS Single Sign-On (AWS SSO) is a cloud service that allows you to grant your users access to AWS resources, such as Amazon EC2 instances, across multiple AWS accounts. By default, AWS SSO now provides a directory that you can use to create users, organize them in groups, and set permissions across those groups. You can also grant the users that you create in AWS SSO permissions to applications such Salesforce, Box, and Office 365. AWS SSO and its directory are available at no additional cost to you.

Essentially, the service can act as a SAML IdP and provides minimal support for OIDC (integrated only with AWS API and tooling). We can configure it to use an external identity provider, but a user must exist in AWS SSO with a username matching the Name ID attribute passed (*sigh*). AWS SSO also doesn’t support SCIM (essentially user replication from the external IdP) with Google Workspace (to nobody’s surprise). This unfortunately means that every user we want to be able to use AWS programmatically will need a user provisioned for them in AWS SSO.

Note that AWS SSO accounts will only work if there is a user with a matching email address as the username in Google Workspace. Essentially, to use AWS, a user will have to authenticate to Google, which will then sign a message that will be relayed to AWS by the user proving that they are in control of the user with the matching email address. This shouldn’t be a cumbersome task as the number of users that will probably need such access should be limited; changes to the system should be relegated almost entirely to CI/CD tooling. However, this is still a very slippery slope to having multiple sources of identity and so is not an ideal solution. Attribute based access control (ABAC) is supported in AWS SSO, but permission sets (IAM policies) cannot be applied to users on it alone, and so utilizing AWS SSO groups (another source of identity) is still required, unfortunately.

To make matters a little more annoying, AWS doesn’t provide an adequate public API for the SSO service. AWS SSO groups and users cannot be codified, making the utilization of identity-as-code near impossible and so making auditing more difficult. As a result, the Terraform resources are limited, and doesn’t support the codification of users. So much of what we’ll do here will be manual.

Bill of Materials

In order to build the solution, we’ll need to set up several things:

  • AWS SSO
    • Create user(s) with username matching their email in Google Workspace
    • Create an SSO group to which they are assigned
    • Assign a permission set to the group allowing members to assume specific roles to which they should be authorized.
  • Google Workspace
    • Create a SAML application configured to allow AWS SSO as a client

Steps

First, go to the AWS SSO service page.

SSO Service


Next to Identity source, click the Change button and select the option for the External identity provider. Take note of the different URLs listed as they’ll be required for the SAML application created next.

External provider option


In a new tab, go to your Google Workspace admin dashboard and start creating a new custom SAML application.

Add a SAML app


After choosing a name, download the IdP metadata file.

Download IdP metadata


On the next page, apply the URLs previously retrieved from AWS earlier.

Use URLs



AWS URL Google Workspace URL
AWS SSO ACS URL ACS URL
AWS SSO issuer URL Entity ID
AWS SSO Sign-in URL Start URL


Set the Name ID options as follows:

Name ID options


After creating the SAML application in Google Workspace, it may be disabled by default for all users.

SAML app disabled by default


You’ll need to enable it if that is the case.

Enabling SAML app access


Back in AWS SSO, upload the metadata file downloaded from Google Workspace to configure it to use the SAML application just created.

upload metadata


Next, we’ll need to create a group to manage the permissions for our users. I created a group called Command-Line-Users as follows.

Create AWS SSO group


For each user, you’ll have to create a new AWS SSO user.

Creating SSO user


Add each user to the group(s) required:

Add user to group


Next, go to the AWS SSO > AWS Accounts page. Select an account to which you wish to grant access. As odd as it may sound, click the Assign users button. Now, select the group you just created.

Select group


Create a new permission set (IAM policy) on the next page.

Create permission set

Create permission set


The permissions policy will be an IAM policy that will grant the ability to assume role(s). It’s advisable to not allow users to directly assume a managed policy as they have had the history of being over-privileged (see Scott Piper). Additionally, the permissions assigned to such policies can shift under your feet as they are modified by AWS. Instead, create your own role that you have the ability modify through code. Even if it starts as only a proxy for the managed policy, if you need to change permissions across accounts or resources in the future, you will only need to change them in specific roles.

Elevated role


Ensure that the role to which you’re granting access has a trust policy allowing both your IdP and your AWS account root the ability to access

trust


After creating the permission set, go back to AWS SSO and assign it to the group.

Assign permission set to group

Verify permission set


In a terminal window, run the command aws configure sso. You should be presented with a prompt with a URL and a temporary code. Navigating to the URL should force you to authenticate to your IdP.

verify

verify


Following that, you will be redirected to an AWS page so that you can verify the request with the code given.

verify


verify


After verifying, you should receive a message like:

verify


Now, you can use the AWS CLI with your SSO profile!

use cli


To get credentials you can use with Terraform, you can assume a role to get a temporary keypair, and then export those credentials as environmental variables.

$ aws sts assume-role --role-arn <role arn> --role-session-name <pick your own>
{
	"Credentials": {
		"AccessKeyId": "xxx",
		"SecretAccessKey": "xxx",
		"SessionToken": "xxx",
		"Expiration": "xxx"
	},
	"AssumedRoleUser": {
		"AssumedRoleId": "xxx",
		"Arn": "xxx"
	}
}


With the access keypair, you can then export environmental variables as follows:

export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"
export AWS_SESSION_TOKEN="xxx"


When this keypair or your SSO session expires, you may start to receive error messages.

error


To fix this, you’ll need to log in once again over the command line as follows:

login


With all this in place, you should now be able to utilize your CLI, scripts, or Terraform that depend on AWS credentials!



If you’re interested in learning how to use AWS, Cloudflare, Google Workspace and more with modern DevOps practices in order to create a hybrid cloud/on-prem malware lab, check out my book on Cyber Range Essentials!