Choose Your Own SAML Adventure: A Self-Directed Journey to AWS Identity Federation Mastery

Automating federation setup across multiple accounts and roles (open-source variant)

In most situations, AWS customers move towards a multiple AWS account strategy as their maturity on the AWS platform increases. While there are many different reasons for doing so, blast radius reduction ranks among the most common, especially regarding human operators. In these scenarios, it is not uncommon for a single AWS customer to have hundreds or even thousands of AWS accounts. In this exercise, we implement a solution for automating the required federation components, both within AWS and the back-end OpenLDAP directory, across any number of accounts and associated roles. This automation, in concert with the AWS-<Account Number>-<Role Name> naming convention you implemented in the first exercise, allows your cloud identity infrastructure to scale to any number of AWS accounts.

Architecture

The following image provides a visual representation of what you are about to construct during this advanced use case exercise. The core components include:

Exercise architecture

Note: The EC2 instance for trusted automation that can be deployed during this advanced use case has been configured with an EC2 instance profile that is associated with a powerful IAM role. This role necessarily and deliberately allows the resident automation to perform sensitive API calls (e.g. iam:PutRolePolicy, iam:CreateRole). As such, you must carefully control SSH access to this machine. You should not grant access to individuals who do not have equivalent IAM permissions.

Note: You should use this architecture and associated AWS CloudFormation template for demonstration and learning purposes ONLY. The template contains default passwords and has not been hardened in any way beyond the default configuration provided by the Amazon Machine Image (AMI). Furthermore, the IdP infrastructure has been simplified to focus on the learning objectives and is not set up for availability and scalability, and is not appropriate for production use.

Prerequisites

The following list identifies the prerequisites for this exercise. If you have not completed these tasks, please do so now:

Benefits of direct federation

Finally, before we begin, it is worth noting why we've opted for the direct federation approach. The other main alternative that is often considered is the "hub & spoke model" in which a user federates into one account and then utilizes (from an end-user perspective) cross-account trusts to move into the AWS account on which they are interested in operating. While there are merits to the hub & spoke model in some cases, most federation customers should opt for the direct federation model implemented here for the following reasons.

Deploy Exercise Infrastructure

To get started, we will first start by deploying the necessary infrastructure to each of the AWS accounts.

Deploy cross-account role template in the child account

Let's start by deploying the necessary CloudFormation template into your second AWS account. You can review the full template here. In summary, this template creates an AWS IAM role that can be assumed from your first AWS account. This role is then configured with the following policy.

{
            "Action": [
                     "iam:CreateRole",
                     "iam:CreateSAMLProvider",
                     "iam:DeleteRole",
                     "iam:DeleteRolePolicy",
                     "iam:DeleteSAMLProvider",
                     "iam:GetRole",
                     "iam:GetRolePolicy",
                     "iam:GetSAMLProvider",
                     "iam:ListRolePolicies",
                     "iam:ListRoles",
                     "iam:ListSAMLProviders",
                     "iam:PutRolePolicy",
                     "iam:UpdateSAMLProvider"
              ],
              "Effect": "Allow",
              "Resource": "*"
}

This role will be used by the trusted automation to configure the IAM elements necessary for federation in the child account. Start by logging in to the AWS Management Console of your second AWS account, and select CloudFormation.

AWS Management Console

If you aren't already there, switch to the Tokyo (ap-northeast-1) region, and then choose Create Stack.

AWS CloudFormation Console

On the first step, Select Template, choose Specify an Amazon S3 template URL, enter the following, and then choose Next.

https://s3.amazonaws.com/federationworkshopreinvent2016/cloudformation/MultiAccountChildAccount.json

AWS CloudFormation Create Stack

On the second step, Specify Details, enter the parameters according to the following table, and then choose Next.

Configuration Element Value
Stack name FederationWorkshopXARole
MasterAccount The 12 digit AWS account number of your first AWS account. This is the account where you deployed the identity provider in the initial exercise.

Note: If you need help finding your account number, please refer to the documentation.

AWS CloudFormation Create Stack

On the third step, Options, you may proceed with the defaults by choosing Next.

AWS CloudFormation Create Stack

Finally review the information to ensure it is correct, acknowledge the creation of of IAM resources, and then choose Create.

AWS CloudFormation Create Stack

The template requires 1-2 minutes to complete. You can choose Refresh during this time to view the creation status in real time.

AWS CloudFormation Create Stack

Note: To support any number of AWS accounts, you would simply deploy the FederationWorkshopXARole CloudFormation stack in each additional child account.

Deploy cross-account role template in the master account

Next, log out of the child account, and log in to the AWS Management Console of your first AWS account. Once you have done so, repeat the directions above to deploy the FederationWorkshopXARole CloudFormation stack in master account.

AWS CloudFormation Create Stack

Download and modify the CloudFormation template for trusted automation

Our next CloudFormation template creates an EC2 instance for trusted automation and an associated IAM instance profile and role. This role defines the other half of the cross-account trust relationship established above. The template must be customized slightly before deployment. Start by using curl to download the generic template to your local workstation using the following command.

curl -o MultiAccountMasterAccount.json http://federationworkshopreinvent2016.s3-website-us-east-1.amazonaws.com/cloudformation/MultiAccountMasterAccount.json

Download AWS CloudFormation Template

Then, open this CloudFormation template within your favorite text editor and modify it in the following two ways:

vim MultiAccountMasterAccount.json

Modify AWS CloudFormation Template

Note: To support any number of AWS accounts, you would simply add one additional line to this policy per additional child account.

Deploy trusted automation template in the master account

Now that the trusted automation template has been modified to fit your environment, we deploy it into the master AWS account. Start by logging in to the AWS Management Console, and select CloudFormation.

AWS Management Console

If you aren't already there, switch to the Tokyo (ap-northeast-1) region, and then choose Create Stack.

AWS CloudFormation Console

On the first step, Select Template, choose Upload a template to Amazon S3, browse to the copy of the template that you modified above, and then choose Next.

AWS CloudFormation Create Stack

On the second step, Specify Details, enter the parameters according to the following table and then choose Next.

Configuration Element Value
Stack name FederationWorkshopTrustedAutomation
InstanceType m3.medium
KeyName Select an existing EC2 key pair within the ap-northeast-1 region. If you do not have an existing key pair refer to the documentation here to create a new one.
PublicSubnetId Select the same public subnet where you deployed the identity provider in the initial exercise.
SourceCidrForSSH The CIDR notation for the IP range that SSH should be restricted to. The workshop facilitators will advise how to best configure this for the conference wifi. For static environments, http://checkip.amazonaws.com/ can be used to determine your current IP address.
VPC Select the VPC that contains the public subnet above.

AWS CloudFormation Create Stack

On the third step, Options, you may proceed with the defaults by choosing Next.

AWS CloudFormation Create Stack

Finally, review the information to ensure it is correct, acknowledge the creation of of IAM resources and IAM resources with custom names, and then choose Create.

AWS CloudFormation Create Stack

The template requires 2-3 minutes to complete. You can choose Refresh during this time to view the creation status in real time.

AWS CloudFormation Create Stack

After the stack creation has completed, use the Outputs tab to determine the public IP address of the Trusted Automation instance. Copy down this value because you need it in the following steps.

AWS CloudFormation Create Stack

Adjust automation configuration files and populate OpenLDAP

Now that you have deployed the additional infrastructure, you can make use of the set of automation scripts that we've provided. You already utilized some of these scripts, particularly the ones focused on openldap group creation, during the first exercise. In the steps below we review the purpose and operation of each script.

Note: These scripts are intended to provide a starting point upon which production grade automation could be built. In their current form, they have been simplified to focus on the learning objectives and do not implement full exception processing. Not appropriate for production use.

Log in via SSH (Shibboleth instance)

Log in using SSH to your Shibboleth instance from the initial exercise using the public IP address. See directions for how to use SSH according to your client platform. If you are familiar with the use of ssh-agent, you may wish to use the '-A' parameter to forward your available SSH keypairs for transient use from that instance. This is not required but allows you to ssh & scp directly from the Shibboleth instance to the trusted automation instance as a convenience.

SSH to identity provider

Adjust automation configuration files

This bundle of scripts uses several configuration files that help them understand your environment. The first file, accounts.txt is a file that defines all of the AWS accounts on which you want to operate. The format for this file is:

<ACCOUNTNUMBER>,<ROLEPREFIX> (one line per AWS account)

Now that we've added a second AWS account to our environment we need to edit the accounts.txt file and add a second entry using the following command sequence.

cd policies/
cp accounts.txt accounts.txt.initial
vim accounts.txt

Edit accounts.txt

The second file, roles.txt is a file that defines a standard set of IAM roles that are to be deployed into each of the AWS accounts defined in the accounts.txt file. The format for this file is:

<ROLENAME>.json

The automation further expects that a valid IAM policy document is resident in the same directory that matches each entry in roles.txt. In the first exercise, this file was populated for you using two roles, ReadOnly and PowerUser. Use the following command sequence to expand this to include two additional roles, SecurityAudit and SuperUser.

cp roles.txt roles.txt.initial
cp roles.many.txt roles.txt

Edit roles.txt

Note: For your safety during this learning exercise, all of the provided IAM policy documents have been modeled after the ReadOnlyAccess AWS managed policy. In practice, you would attach a more meaningful and appropriate policy.

Automatically define and load the additional openldap groups

Now that you've adjusted the configuration files, we'll re-run the ldap automation from the initial exercise to define and load the additional openldap groups necessary to support our expanded set of AWS accounts & roles according to the AWS-<Account Number>-<Role Name> naming convention. Start with the generateldifs script to create the necessary LDAP Data Interchange Format (ldif) files.

cd ../automation/
./generateldifs.py

Generate ldifs

If you would like to examine the resulting LDIF files, you can find them in the /home/ec2-user/ldifs directory. There you'll find two LDIF files per AWS account: one that adds the associated groups and one that deletes them (if necessary). Now use the next script, loadldifs, to load these new group definitions into OpenLDAP.

./loadldifs.sh

Load ldifs

Note: Recall that the password for cn=Manager,dc=example,dc=com has been set to Pass@123.

Note: No action is taken on the first two groups since they already exist.

Populate users into the additional OpenLDAP groups

Now that the additional back end groups have been created, we need to provision alice and bob into these groups in a way that reflects the level of AWS access we want them to have. As we did in the initial exercise, we'll do this "cooking show" style. Switch to the ldifs directory and edit the moregroupmemberships.ldif file. Replace <ACCOUNT2> with your second AWS account number.

cd ../ldifs/
vim moregroupmemberships.ldif

Prepare ldif

Finally, load these additional group memberships using the loadmoreldapgroupmembers helper script.

cd ../automation
./loadmoreldapgroupmembers.sh

Load ldif

Automate AWS IAM entity creation and management

Next, we'll focus on the creation and management of the necessary IAM entities using our newly provisioned trusted automation instance. In practice, you may want to alternatively implement these mechanisms as AWS Lambda functions for cost optimization purposes and to reduce operational burden. We've chosen Amazon EC2 here for simplicity in order to focus on the learning objectives.

Synchronize automation configuration files

The automation utilities found on the trusted automation instance rely on the same two static configuration files, accounts.txt and roles.txt. In practice, these files would be kept in a centrally accessible location, such as in Amazon S3, but we've kept them locally for simplicity in this exercise. As such, we need to synchronize the proper copies of these files over to the trusted automation instance using the following command sequence.

cd ../policies/
scp accounts.txt ec2-user@<TrustedAutomationIP>:~/policies/
scp roles.txt ec2-user@<TrustedAutomationIP>:~/policies/

Synchronize configuration

Note: If you did not enable ssh-agent forwarding earlier in the exercise, simply copy these files to your local workstation first before uploading them to the trusted automation instance.

Login via SSH (trusted automation instance)

Login using SSH to your trusted automation instance using the public IP address you noted above. See directions for how to use SSH according to your client platform. If you enabled ssh-agent forwarding above, the ssh client would automatically provide your keypair for authentication.

ssh <TrustedAutomationIP>

SSH to trusted automation instance

Note: If you did not enable ssh-agent forwarding earlier in the exercise, simply SSH to the trusted automation instance from your local workstation.

Configure host file entry

To compensate for the lack of proper DNS, we again need to provide resolution for idp1.example.com in the form of a host file entry. Add an entry to the trusted automation instance for idp1.example.com that points to the Public IP address of your Shibboleth instance from the initial exercise.

sudo vim /etc/hosts

Configure host file entry

Execute trusted automation

You are now ready to execute the trusted automation that creates and manages the IAM entities necessary for federation. Specifically, you invoke automation that facilitates the creation of the IAM identity provider and the IAM roles for identity provider access. In the initial exercise, you created these entities manually using the AWS Management Console. In this advanced use case, you'll use automation to scale this creation effortlessly across all of your AWS accounts.

The first script, federationproviderdeploy, retrieves the SAML metadata from Shibboleth and then configures an IAM identity provider for each account in the accounts.txt file. It does so by sequentially performing an Assume Role call into each of the accounts using the cross-account trust roles we deployed at the beginning of this exercise. Take a second to review the contents of the script and then execute it, as shown in the following screenshot.

cd automation
./federationproviderdeploy.py

Deploy federation provider

Note: The script has detected that idp1 already existed in our first account and did not mangle this configuration.

The second script, federationrolesdeploy, is used to configure a set of IAM roles for federation. These roles reference the identity provider configured above. It does so by inspecting both the accounts.txt file and the roles.txt file and producing all of the resulting permutations. The resulting IAM roles are named using the concatenation of ROLEPREFIX (accounts.txt) and ROLENAME (roles.txt) (e.g. FederationWorkshop-ReadOnly). Recall that the ROLENAME portion matches exactly 1:1 to the AWS-<Account Number>-<Role Name> naming convention we implemented for the OpenLDAP groups.

After the roles are created, the final step of the script takes the json policy document in the same directory and applies it as an inline policy on the role. This script also utilizes the Assume Role pattern described above. Take a second to review the contents of the script and then execute it, as shown in the following screenshot.

./federationrolesdeploy.py

Deploy federation roles

Note: The script has detected that the original two roles existed in our first account and did not mangle these configurations.

Inspect the result

Before we test the outcome of this automation, let's first inspect things. Log in to the AWS Management Console for your second AWS account, and select Identity & Access Management.

AWS Management Console

Choose Identity Providers from the left hand navigation menu. We can see that our identity provider has been created using the idp1 name our configuration expects.

AWS Management Console

Now, choose Roles from the left hand navigation menu, and type FederationWorkshop into the search bar. Note that all of the IAM roles have been configured.

AWS Management Console

You can explore these roles to see how the automation has properly established the trust policy necessary for federation and bound an inline policy that matches the policy document on the trusted automation instance.

Testing

Finally, it is now time to test our revised configuration. Open a new browser window, and enter the IdP initiated login URL for Shibboleth.

https://idp1.example.com:8443/idp/profile/SAML2/Unsolicited/SSO?providerId=urn:amazon:webservices

When presented with the authentication form, login with bob's credentials.

Shibboleth login page

Note: You may need to utilize a private browser window to force Shibboleth to re-authenticate you.

Note that the role selection page automatically reflect's bob's new roles. It is also important to notice that no adjustments to the IdP configuration were required, this was entirely handled by the regular expression transformation we configured in the initial exercise.

AWS Role Chooser Page

Select the FederationWorkshop-ReadOnly role under your 2nd AWS account, and choose Sign In.

AWS Role Chooser Page

You are now logged into your 2nd AWS account as bob. For our last test, let's assume the bob wishes to switch back to your first AWS account. Within the same browser window, again enter the IdP initiated login URL for Shibboleth.

https://idp1.example.com:8443/idp/profile/SAML2/Unsolicited/SSO?providerId=urn:amazon:webservices

Shibboleth does not ask you to authenticate because you are already signed in. Instead, you are immediately returned to the role selection page. From here, you can select any one of bob's other roles to assume. This process can be repeated any number of times so that Bob can easily switch between his various roles throughout the course of his duties.

AWS Role Chooser Page

If time permits

If time permits, you can extend the learning of this advanced use case by performing these additional steps on your own.

Exercise complete

Congratulations! You have completed the advanced use case of automating federation setup across multiple accounts and roles.

With this use case complete, you are now ready to continue your journey through more of the advanced use cases. To continue, return to the index of advanced use cases.