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

First-hour exercise (open-source variant)

AWS supports identity federation using SAML (Security Assertion Markup Language) 2.0. Using SAML, you can configure your AWS accounts to integrate with your identity provider (IdP). Once configured, your federated users are authenticated and authorized by your organization's IdP, and then can use single sign-on (SSO) to access AWS.

In this workshop, you will walk through an evolutionary set of steps that will guide you through the setup and configuration of basic to increasingly more advanced SAML federation use cases. This journey will necessarily start with several required configurations that are covered in this specific exercise:

After you establish this minimum baseline, you can then select the advanced SAML use cases that appeal to you. You can progress through these additional use cases in any order you wish, focusing specifically on those which you find to be the most relevant for you and your organization. These advanced use cases include:

Finally, there are two versions of this workshop, this variant implements all of the above using an open source software stack, namely the Shibboleth 3.x IdP with an openldap backing identity store. The alternative variant implements all of the above using a Microsoft based software stack (Active Directory and Active Directory Federation Services 3.x). Each of these variants implements equivalent use cases, so we encourage you to use the technology set that you are most comfortable with.

Architecture

The following image provides a visual representation of what you are about to construct during this initial exercise.

Exercise architecture

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, scalability, etc., and is not appropriate for production use.

Prerequisites

The following list identifies the prerequisites for this workshop. If you have not assembled these elements, please take time to do so now:

Getting Started

We've created a CloudFormation stack that automates many of the more trivial and time-consuming steps so that you can focus your time on the true learning objectives. However, there are several important things to note that you will use as you progress through the exercise:

You will have a chance to review the outcome of these configurations in subsequent steps.

Deploy CloudFormation Template

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

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

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

AWS CloudFormation Create Stack

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

Configuration Element Value
Stack name FederationWorkshopShibboleth
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 see the documentation to create a new one.
PublicSubnetId Select an existing public subnet.
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

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

AWS CloudFormation Create Stack

Finally, review the information to ensure that it is correct, 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 Shibboleth instance. Copy down this value as you will need it in the following steps.

AWS CloudFormation Create Stack

Connect to the EC2 instance

Now that you have successfully deployed the CloudFormation stack, you will use SSH to connect to the newly provisioned Amazon EC2 instance.

Login via SSH

Log in using SSH to your newly provisioned Shibboleth instance using the public IP address that you noted in the previous step. See directions for how to use SSH according to your client platform.

Connect via SSH

Inspect the objects in openldap

Now that you've connected, take a second to become familiar with the objects that are in the ldap directory.
Use the ldapsearch command to inspect bob's object in the directory.

ldapsearch -D "cn=Manager,dc=example,dc=com" -W -b "dc=example,dc=com" -H ldap://localhost:389 '(uid=bob)'

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

As shown in the following screenshot, bob's entry has been configured for a number of object classes, including eduPerson. If you aren't familiar with ldap or ldap object classes, you can read more, though this knowledge isn't required to complete this exercise.

Inspect the objects in openldap

Install & Configure Shibboleth

You are now ready to begin installing and configuring the Shibboleth identity provider. In a SAML federation scenario, the IdP is responsible for the authentication and coarse grained authorization of all AWS users. AWS is then able to leverage and consume these identity assertions according to a preestablished cryptographic trust.

Initial installation

To get started, use sudo to switch to the root user within your SSH session.

sudo su -

Next, switch to the directory where the Shibboleth software has been pre-staged.

cd /home/ec2-user/software/shibboleth-identity-provider-3.2.1/bin

Use curl to determine the internal hostname of your EC2 instance. You'll need this value in the next step.

curl http://169.254.169.254/latest/meta-data/hostname

Finally, run the installation program.

./install.sh

Enter the following values during the installation wizard.

Configuration Element Value
Source (Distribution) Directory /home/ec2-user/software/shibboleth-identity-provider-3.2.1 (Default)
Installation Directory /opt/shibboleth-idp (Default)
Hostname The internal hostname of your EC2 instance as determined above. (Example: ip-172-31-21-125.ap-northeast-1.compute.internal)
SAML EntityID https://idp1.example.com:8443/idp/shibboleth
Attribute scope example.com
Backchannel PKCS12 Password Pass@123
Cookie Encryption Key Password Pass@123

The following screenshot shows an example of these steps.

Note: The hostname shown below should not be used; instead, use the hostname of your own EC2 instance.

Install & Configure Shibboleth

Clean up file permissions

Because the installation above was run as the root user, all of the resulting files were created with root:root ownership. In order to make the IdP function properly, we need to set the group to the tomcat group and provide group-level permissions. This enables tomcat to read the configuration files and write log files. To save time and make it easier for you, we've packaged all of these chown and chmod commands into a simple script.

To clean up the file permissions, execute the following command, as shown in the following screenshot.

/home/ec2-user/automation/cleanuppermissions.sh

clean up file permissions

Configure LDAP properties file

Next, we need to link our newly installed Shibboleth IdP to the openldap server installed on the same EC2 instance. This is done by configuring the ldap.properties file found in the IdP conf directory.

Again, we've done some of the mundane typing for you, so start by copying the ldap.properties template from the /home/ec2-user/static directory.

mv /opt/shibboleth-idp/conf/ldap.properties /opt/shibboleth-idp/conf/ldap.properties.original
cd /home/ec2-user/static
cp ldap.properties /opt/shibboleth-idp/conf

Note: If you'd like to see what we've changed already, you can diff the two files using the following command.

diff /opt/shibboleth-idp/conf/ldap.properties.original /opt/shibboleth-idp/conf/ldap.properties

Next, edit the ldap.properties file in the IdP configuration directory using vim (or your favorite text editor), as shown in the following screenshot.

cd /opt/shibboleth-idp/conf
vim ldap.properties

Edit ldap.properties

Find the idp.attribute.resolver.LDAP.returnAttributes properties in the ldap.properties file. This attribute defines which ldap attributes are returned to the IdP by openldap in response to queries about the users. Edit the parameter to include the following additional attributes, as shown in the following screenshot.

idp.attribute.resolver.LDAP.returnAttributes = cn,homephone,mail,uid,sn,displayName,givenName,memberOf

Edit ldap.properties

The key attribute here is the memberOf attribute. This attribute is a dynamic attribute provided by the memberOf overlay, which converts all of a user's group memberships into a multi-valued attribute. Later, we'll see how this is used to easily build dynamic SAML assertion attributes using regular expressions.

Configure access control

Shibboleth 3.x controls access to the IdP using the access-control.xml file. Edit this file to allow end user access from anywhere on the Internet by appending the CIDR 0.0.0.0/0 to the list of allowed ranges, as shown in the following screenshot.

cd /opt/shibboleth-idp/conf
cp access-control.xml access-control.xml.original
vim access-control.xml

Edit access-control.xml

Important: In general, you should not allow accessibility to a service from the Internet until it is fully hardened and secured.

Copy WAR deployment descriptor

During the Shibboleth installation, a WAR file containing the form-based login and other components were assembled by the installation program. In this step, we copy a deployment descriptor to the appropriate location within the Tomcat installation so that this WAR file is automatically deployed. To avoid copy and paste issues, we've staged a copy of this idp.xml file in /home/ec2-user/static. Copy this file to the /etc/tomcat8/Catalina/localhost directory, as shown in the following screenshot.

cd /home/ec2-user/static
cp idp.xml /etc/tomcat8/Catalina/localhost/

Copy deployment descriptor

Install AWS SAML metadata

SAML federations use metadata documents to maintain information about the public keys and certificates that each party utilizes. At run time, each member of the federation can then use this information to validate that the cryptographic elements of the distributed transactions come from the expected actors and haven't been tampered with. Since these metadata documents do not contain any sensitive cryptographic material, AWS publishes federation metadata at https://signin.aws.amazon.com/static/saml-metadata.xml

Use the following command sequence to download and rename the AWS federation metadata, as shown in the following screenshot.

cd /opt/shibboleth-idp/metadata
wget https://signin.aws.amazon.com/static/saml-metadata.xml
mv saml-metadata.xml aws.xml

Download AWS federation metadata

Next, we need to tell Shibboleth about this new piece of metadata. To do so, we register a new file-based metadata provider in the IdP configuration. Use the following command sequence to add the necessary configuration, as shown in the following screenshot.

cd /opt/shibboleth-idp/conf
cp metadata-providers.xml metadata-providers.xml.original
vim metadata-providers.xml

Add the following xml element just inside of the final MetadataProvider tag.

<MetadataProvider id="AWS"  xsi:type="FilesystemMetadataProvider" metadataFile="/opt/shibboleth-idp/metadata/aws.xml"/>

Configure AWS federation metadata

Configure AWS relying party

Next, we need to tell Shibboleth that it should offer authentication services for AWS. The SAML configuration for doing so is known as a relying party. Use the following command sequence to add the necessary configuration, as shown in the following screenshot.

cd /opt/shibboleth-idp/conf
cp relying-party.xml relying-party.xml.original
vim relying-party.xml

Add the following to the <util:list id="shibboleth.RelyingPartyOverrides"> element.

<bean parent="RelyingPartyByName" c:relyingPartyIds="urn:amazon:webservices">
    <property name="profileConfigurations">
        <list>
            <bean parent="Shibboleth.SSO" />
            <bean parent="SAML2.SSO"
                p:encryptAssertions="never"
                p:assertionLifetime="PT5M"
                p:signResponses="never"
                p:signAssertions="always"
                p:includeConditionsNotBefore="true"
                p:includeAttributeStatement="true"/>
            <ref bean="SAML2.ECP" />
            <ref bean="SAML2.Logout" />
            <ref bean="SAML2.AttributeQuery" />
            <ref bean="SAML2.ArtifactResolution" />
        </list>
    </property>
</bean>

Configure AWS relying party

Configure AWS specific SAML assertion attributes

In a SAML federation, the Identity Provider can pass various attributes about the user, the authentication method, or other points of context to the service provider (in this case AWS) in the form of SAML attributes. In order for SAML federation for AWS to function properly, several attributes are required. The first such attribute is the Roles attribute, which specifies combinations of AWS IAM Roles and authorizing AWS IAM Identity Providers that the user is authorized to assume. To add this first required AWS SAML attribute, use the following command sequence.

cd /opt/shibboleth-idp/conf
mv attribute-resolver.xml attribute-resolver.xml.original
cp attribute-resolver-ldap.xml attribute-resolver-ldap.xml.original
ln -s attribute-resolver-ldap.xml attribute-resolver.xml
vim attribute-resolver-ldap.xml

Just below the section header for Attribute Definitions, add the following.

<resolver:AttributeDefinition id="awsRoles" xsi:type="ad:Mapped" sourceAttributeID="memberOf">
    <resolver:Dependency ref="myLDAP"/>
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="https://aws.amazon.com/SAML/Attributes/Role" friendlyName="Role" />
        <ad:ValueMap>
            <ad:ReturnValue>arn:aws:iam::$1:role/FederationWorkshop-$2,arn:aws:iam::$1:saml-provider/idp1</ad:ReturnValue>
        <ad:SourceValue>cn=AWS-(\d{12})-(\w*),.*</ad:SourceValue>
    </ad:ValueMap>
</resolver:AttributeDefinition>

The attribute definition above is not trivial, but achieves a very important configuration. Following along line by line, this says:

This attribute will make better sense later on in the exercise when you see it in action. For now, the key take away is that you are defining the resulting value for the AWS Role attribute in a dynamic way (by mapping group memberships) instead of a static way (by explicitly defining ARNs). This dynamic resolution will allow the IdP configuration to scale to support virtually any number of AWS accounts and any number of IAM roles without further configuration.

The second AWS specific attribute is RoleSessionName. This attribute is recorded as part of the identity within CloudTrail to ensure that you can properly account for the federated user's actions. Add this second required AWS SAML attribute immediately following the first.

<resolver:AttributeDefinition id="awsRoleSessionName" xsi:type="ad:Simple" sourceAttributeID="uid">
    <resolver:Dependency ref="myLDAP"/>
    <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="https://aws.amazon.com/SAML/Attributes/RoleSessionName" friendlyName="RoleSessionName" />
</resolver:AttributeDefinition>

This attribute definition is more straight-forward and simply maps the uid attribute from LDAP to the AWS RoleSessionName. You might also elect to utilize the user's email address for RoleSessionName depending on your specific requirements. In either case, your choice of source attribute must be unique.

Your resulting final configuration should resemble the following screenshot.

Configure AWS SAML attributes

Understanding the AWS-<Account Number>-<Role Name> naming convention

In the preceding section, we utilized a naming convention of AWS-<Account Number>-<Role Name> for the groups stored in openldap. To understand why this was chosen, we must first consider several aspects of how AWS environments are commonly segregated:

The AWS-<Account Number>-<Role Name> naming convention was specifically formulated in order to provide a best practice pattern for group naming that was able to flexibly account for all of the aspects identified above. While the specific set of dimensions an organization may choose to use for account segmentation or the specific set of named roles an organization may define will certainly vary from one organization to the next, this standard will work in all known cases. We highly encourage you to use this pattern within your own organization, as it has been proven across a large number of customer implementations at-scale.

Configure AWS attribute release

The attributes stored within SAML assertions contain potentially sensitive information. Therefore, control over which configured attributes are released to which service providers is explicitly controlled. Use the following command sequence to allow the two attributes configured above to be sent to AWS.

cd /opt/shibboleth-idp/conf
cp attribute-filter.xml attribute-filter.xml.original
vim attribute-filter.xml

Just inside the AttributeFilterPolicyGroup element, add the following.

<AttributeFilterPolicy id="releaseAWSToAWS">
    <PolicyRequirementRule xsi:type="Requester" value="urn:amazon:webservices"/>
    <AttributeRule attributeID="awsRoles">
                    <PermitValueRule xsi:type="ANY"/>
    </AttributeRule>
    <AttributeRule attributeID="awsRoleSessionName">
        <PermitValueRule xsi:type="ANY"/>
    </AttributeRule>
</AttributeFilterPolicy>

Your resulting final configuration should resemble the following screenshot.

Configure AWS SAML attribute release

Restart Tomcat

The Shibboleth IdP has now been fully configured for use with AWS. To force all of the modified configurations to take effect, restart the tomcat service.

service tomcat8 restart

Restart tomcat8 service

If Tomcat fails to start for any reason, you can review the following log sources in order to debug:

You will also find final versions of all of the configuration files in /home/ec2-user/static. If you are having trouble, you should use the diff command to help determine any differences between these known good configuration files and your own.

diff /home/ec2-user/static/attribute-filter.xml /opt/shibboleth-idp/conf/attribute-filter.xml

Load openldap groups and group memberships

In the preceding sections, we configured Shibboleth to read a user's ldap group memberships and transform those memberships into specific SAML assertion attributes. To enable testing of your freshly deployed federation provider, we need to create a set of ldap groups using the naming convention that Shibboleth expects and place our two users (bob and alice) in them. For the purposes of this workshop, we've created a set of simple utilities that will generate and load a set of LDAP Data Interchange Format (ldif) files into openldap in order to accomplish this.

Note: These scripts are intended to provide the "cooking show" version of this process. In your own organization, the process for a user to be placed into one of the groups used to control AWS access should be managed through an entitlement portal, a managed workflow environment, or other trusted process.

To begin, 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 you want to operate on. The format for this file is:

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

We'll see this file used more extensively during the advanced use cases. For now, simply use the following command sequence to insert the number of the account in which you deployed Shibboleth above. If you need help finding your account number, see this documentation.

cd /home/ec2-user/policies
vim accounts.txt

Change: <ACCOUNT1> to your AWS account number (e.g. 123456789012) and save the file.

Adjust accounts.txt

Now that you've configured your account number, the next script generateldifs, is a script that takes the union of the accounts defined in accounts.txt and the set of roles in another text file, roles.txt, in order to produce a set of ldif files which define groups using the AWS-<Account Number>-<Role Name> convention. Use the following command sequence to generate these ldif files as shown in the screenshot.

cd ../automation/
./generateldifs.py

Generate ldifs

If you would like to examine the resulting ldif files, they can be found 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 the associated groups. Again, we'll spend more time understanding these ldif files in the advanced use cases portion of the workshop. For now, use the next script, loadldifs, to load these new group definitions into openldap as shown in the following screenshot.

./loadldifs.sh

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

Load ldifs

At this point, the newly created groups are empty. In our final step of the "cooking show," we will add our users (bob and alice) to these groups. To do so, we'll use one more ldif file groupmemberships.ldif. Use the command following sequence to construct an ldif that defines these group memberships.

cd ../ldifs
vim groupmemberships.ldif

Change two occurrences of: <ACCOUNT1> to your account number (e.g. 123456789012) and save the file.

Adjust groupmemberships.ldif

Our final script, loadldapgroupmembers, uses ldapmodify to load the groupmemberships.ldif we've just modified above.

cd ../automation/
./loadldapgroupmembers.sh

Load group memberships

Before moving on, use the following command sequence to inspect the group memberships for both bob and alice. As you do so, you'll notice that bob has one group membership (ReadOnly), whereas alice has two memberships (ReadOnly & PowerUser), giving her access to two roles within the given AWS account.

ldapsearch -D "cn=Manager,dc=example,dc=com" -W -b "dc=example,dc=com" -H ldap://localhost:389 '(uid=bob)' uid cn memberof

Inspect group memberships for bob

ldapsearch -D "cn=Manager,dc=example,dc=com" -W -b "dc=example,dc=com" -H ldap://localhost:389 '(uid=alice)' uid cn memberof

Inspect group memberships for alice

Important: In a federated scenario the IdP is entirely responsible for authorizing which roles within AWS a given user can assume. Using the patterns and configurations shown here, the groups in openldap serve as the source of truth for these entitlements. If a user belongs one of the specially named groups they will be able to access AWS within the confines of the corresponding AWS account and IAM role. As such, please ensure that as you adapt these learnings to your own environment:

Configure host file entry for Shibboleth on your local workstation

Note: This configuration should be performed on your local workstation, not the EC2 instance where Shibboleth was installed.

During the initial configuration of the Shibboleth software, we provided a SAML EntityID of https://idp1.example.com:8443/idp/shibboleth. The Shibboleth software uses this value to perform HTTP 302 browser redirects that are integral to the SAML login flow. Since example.com is only an illustrative domain, we will configure a local host file entry in lieu of configuring a DNS record for our identity provider. Choose the direction set below based on your workstation's operating system (Linux, Mac, or Windows).

Linux/Mac host file entry

Use vim or your favorite editor to add a host file entry for idp1.example.com to the EIP address you noted earlier in the exercise.

sudo vim /etc/hosts

Edit /etc/hosts

Windows host file entry

Use Notepad or your favorite editor to add a host file entry for idp1.example.com to the EIP address you noted earlier in the exercise, as shown in the following screenshot.

notepad %windir%\system32\drivers\etc\hosts

Edit /etc/hosts

Test host file entry

After configuring the host file entry, make sure you can ping your Shibboleth instance, as shown in the following screenshot.

ping idp1.example.com

Edit /etc/hosts

Configure the IAM Identity Provider

Now that we've finished the installation and configuration of Shibboleth, we need to configure AWS to trust the authentication and authorization information it provides. During this process, you'll provide AWS with the SAML metadata from your Shibboleth installation, which details all of the encryption and signing certificates that Shibboleth will use. This exchange provides the preestablished cryptographic trust needed for AWS to utilize the assertions generated by Shibboleth.

In order to start this process, we need to configure an IAM Identity Provider within the AWS console.

Download IdP metadata

Start by downloading the Shibboleth federation metadata from your newly configured IdP. This is the companion to the AWS federation metadata that you installed in the IdP itself.

cd $HOME/Desktop (or another temporary directory of your choice)
curl -o shibmetadata.xml -k https://idp1.example.com:8443/idp/shibboleth

Download Shibboleth metadata

Note: You can also use a web browser to download the metadata if curl is not available on your local workstation.

Create AWS IAM identity provider

With the metadata downloaded, return to the AWS Management Console, navigate to the IAM service, and select Identity Providers from the left hand navigation menu.

Select Identity Providers

Next, choose Create Provider.

Select Identity Providers

Enter the following values to configure the provider, and choose Next Step.

Provider Type SAML
Provider Name idp1
Metadata Document Browse to file downloaded in previous step.

Configure Identity Provider information

Verify the information is correct and then choose Create to create the identity provider.

Verify Identity Provider information

The banner at the top of the screen provides confirmation that your identity provider was successfully created.

Identity Provider confirmation

Create AWS IAM Roles for identity provider access

In our final step before initial testing, we need to create a set of IAM roles that correspond one-to-one to the directory groups we populated earlier in the exercise. These roles will be named such that their resulting ARNs will match the regular expression transformation we configured within Shibboleth earlier. Start by selecting Roles from the left hand menu with the IAM service and then choose Create New Role.

Create new IAM Role

In Step 1, set the Role Name to FederationWorkshop-ReadOnly.

Create new IAM Role

In Step 2, select Role for Identity Provider Access and then select Grant Web Single Sign-On (WebSSO) access to SAML Providers.

Create new IAM Role

In Step 2, set the SAML provider to idp1 using the drop down menu. This configuration defines the specific federation provider that provides authentication and authorization into the role.

Create new IAM Role

In Step 3, review the role trust policy (no changes required) and choose Next Step to continue.

Create new IAM Role

In Step 4, select the ReadOnlyAccess policy.

Note: The policy that you attach here specifically controls the AWS actions that the federated user is authorized to perform. In practice, you would attach a more meaningful and appropriate policy. The ReadOnlyAccess policy selected here has been chosen simply to facilitate this learning exercise.

Create new IAM Role

In Step 5, review all of the role information and then select Create Role to complete the process.

Create new IAM Role

Finally, repeat the entire sequence of preceding steps for a second role named FederationWorkshop-PowerUser. All other inputs remain the same. After creating this second role, type FederationWorkshop in the filter box on the IAM Roles page. You should see both of your newly created roles listed.

Inspect new IAM Roles

Test federated access to the AWS Management console

You are now ready to test federated access to the AWS management console using your newly configured Identity Provider. To do so, open a new browser window, and open the SAML tracer add on. We'll use SAML tracer to inspect the contents of the SAML assertions as they flow from the IdP to AWS. This will allow you to see the results of your configurations and understand the information that AWS is consuming from your identity provider. See the following screenshot for help enabling SAML tracer.

Enable SAML tracer

With SAML tracer enabled, switch back to the main 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

Because we configured Shibboleth with a self-signed certificate, you will be prompted to add a security exception.

Self signed certificate security exception

After adding the exception Shibboleth, will return the login page. Log in using alice's credentials.

Note: Recall that alice's password has been set to Pass@123.

Shibboleth login page

After successfully authenticating, you will then be redirected to the AWS role chooser page. This page is presented because alice was granted more than one role based on her group membership in openldap. Select the FederationWorkshop-PowerUser role and choose Sign In.

AWS SAML role chooser page

You are then logged into the AWS Management Console and provisioned into the role you selected. The selected IAM role and the associated attached policies will control the set of AWS actions that your federated user is able to perform.

AWS Management console via federated login

Before moving on, switch back to the SAML tracer window, and scroll upwards until you find the entry for https://signin.aws.amazon.com/saml. Choose that entry, and select the SAML tab in the lower pane. As you look through the assertion, look for the <saml2:AttributeStatement>. This will allow you to see how the configurations you applied above translate into the actual SAML attributes that are passed to AWS. See the following screenshot for reference.

SAML Assertion in SAML tracer

Configure federated access to the AWS CLI and SDKs

In the final step of this initial exercise, you will be implementing federated API/CLI access. This will enable your users (in this case bob and alice) to access your AWS environment using their example.com credentials through the AWS CLI or one of the AWS SDKs. The following directions focus on the specific configurations and utilities that are needed for this capability. After the workshop, we recommend that you review this blog post for a more detailed review of the internal workings of the solution.

First, on your local workstation, if you do not already have one, you configure a minimal AWS credentials file.

Linux/OSX: ~/.aws/credentials
Windows:   C:\Users\USERNAME\.aws\credentials

Open this file using your favorite text editor and add the following contents, adjusted to your preferred region and output format. Then save and close the file.

[default]
output = json
region = us-west-2
aws_access_key_id =
aws_secret_access_key =

Note: An AWS access key pair is not configured in the above structure because the initial AWS STS call is authenticated by the SAML assertion returned by the trusted IdP. All subsequent API/CLI calls are authenticated by the key pair contained within the returned AWS STS token.

Next, you install three modules that fall outside the core Python distribution, specifically boto, beautifulsoup4, and requests. There are several ways to do this, but the pip utility, which is included in Python 2.7.9+, makes it a very easy task. Execute the following command to install the additional modules, as shown in the following screenshot.

pip install --upgrade boto beautifulsoup4 requests

pip install

Next, download a fully configured version of the script using a browser or your favorite command line tool.

curl -o samlapi_formauth.py http://federationworkshopreinvent2016.s3-website-us-east-1.amazonaws.com/cli/samlapi_formauth.py

Script Download

This version is different from the one listed on the blog post in a few small ways.

payload['_eventId_proceed'] = ''

Now, execute the script using either alice or bob's credentials.

alice@Ubuntu64:/tmp$ ./samlapi_formauth.py
Username: alice
Password: **************** (Pass@123)

Please choose the role you would like to assume:
[ 0 ]:  arn:aws:iam::012345678987:role/FederationWorkshop-ReadOnly
[ 1 ]:  arn:aws:iam::012345678987:role/FederationWorkshop-PowerUser
Selection:  1

---------------------------------------------------------------
Your new access key pair has been stored in the AWS configuration file /home/alice/.aws/credentials under the saml profile.
Note that it will expire at 2016-10-16T17:16:20Z.
After this time, you may safely rerun this script to refresh your access key pair.
To use this credential, call the AWS CLI with the --profile option (e.g., aws --profile saml ec2 describe-instances).
---------------------------------------------------------------

Simple API example listing all S3 buckets:
[<Bucket: mybucket1>, <Bucket: mybucket2>, <Bucket: mybucket3>, <Bucket: mybucket4>, <Bucket: mybucket5>]

After you've done so, let's utilize the saml profile for a few additional CLI calls. First, let's retrieve the list of saml providers.

alice@Ubuntu64:/tmp$ aws --profile saml iam list-saml-providers
{
    "SAMLProviderList": [
                  {
                    "CreateDate": "2016-10-18T20:26:17Z", 
                    "ValidUntil": "2116-10-18T20:26:17Z", 
                      "Arn": "arn:aws:iam::012345678987:saml-provider/idp1"
                  } 
        ]
}

Next, let's inspect the FederationWorkshop-ReadOnly using a CLI filter.

alice@Ubuntu64:/tmp$ aws --profile saml iam list-roles --query 'Roles[?RoleName==`FederationWorkshop-ReadOnly`]'
[
        {
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17", 
                "Statement": [
                      {
                        "Action": "sts:AssumeRoleWithSAML", 
                    "Effect": "Allow", 
                        "Condition": {
                                "StringEquals": {
                                   "SAML:aud": "https://signin.aws.amazon.com/saml"
                               }
                           }, 
                        "Principal": {
                               "Federated": "arn:aws:iam::012345678987:saml-provider/idp1"
                        }
                        }
                ] 
              }, 
              "RoleId": "AROAJZN6LB2TJXXXXXXXX", 
            "CreateDate": "2016-10-18T20:51:27Z", 
            "RoleName": "FederationWorkshop-ReadOnly", 
            "Path": "/", 
            "Arn": "arn:aws:iam::012345678987:role/FederationWorkshop-ReadOnly"
        }
]

Depending on the AWS resources available in your account, try to formulate one or two additional describe or list calls using the saml profile. The AWS CLI Command Reference can help you construct these calls.

Exercise complete

Congratulations! You've successfully completed the first half of the exercise and now have:

With this setup complete, you are now ready to advance your journey into the more advanced use cases. As described in the introduction, you may complete these advanced use cases in the order and combination that you choose. To continue, see a brief summary of each use case and to get started with your own SAML adventure.