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

Implement a SAML version of "Amazon S3 home directories"

In this exercise, we will go over how to create a S3 bucket where every federated user has access to only his or her own "home directory." The inspiration for this advanced use case comes from a non-federation oriented example in the AWS documentation, Allow Users to Access a Personal "Home Directory" in Amazon S3. Here we'll be modifying this pattern specifically for SAML federated users with a specially crafted IAM policy.

A brief lesson about Amazon S3 objects: Amazon S3 stores data in a flat structure; you create a bucket, and the bucket stores objects. Amazon S3 doesn’t have a hierarchy of sub-buckets or folders; however, tools like the AWS Management Console can emulate a folder hierarchy to present folders in a bucket by using the names of objects (also known as keys). For simplicity, you can think of an object’s name as the full path of a file in a traditional file system. To give you an example, for an object that’s named home/common/shared.txt, the console will show the shared.txt file in the common folder that is in the home folder. The names of these folders (such as home/ or home/common/) are called prefixes.

By the way, the slash (/) in a prefix like home/ isn’t a reserved character—you could name an object (using the Amazon S3 API) with prefixes like home:common:shared.txt or home-common-shared.txt. However, the convention is to use a slash as the delimiter, and the Amazon S3 console (but not Amazon S3 itself) treats the slash as a special character for showing objects in folders. You can read more about it in our documentation Getting Started.

This exercise is applicable to both variants (Open Source & Microsoft) of the workshop, just be sure to select the appropriate link at the end of the exercise to properly continue your SAML adventure.

Architecture

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

Exercise architecture

Note: You should use this architecture and associated AWS CloudFormation template for demonstration and learning purposes ONLY. The 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 exercise. If you have not completed these tasks, please take time to do so now.

Deploy Exercise Infrastructure

To get started, you will deploy an AWS CloudFormation stack that creates a S3 bucket for you.

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 Specify an Amazon S3 template URL, enter the following, and then choose Next.

https://s3.amazonaws.com/federationworkshopreinvent2016/cloudformation/S3HomeDir.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 FederationWorkshopS3HomeDirs
BucketNameSuffix A string of your choice that will be appended to the end of the bucket name (lowercase only)

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, and then choose Create.

AWS CloudFormation Create Stack

The template requires 20-30 seconds to complete. You can choose Refresh during this time to view the creation status in real time. After the stack has completed, choose the Outputs tab and make note of the BucketName for use later in this exercise.

AWS CloudFormation Create Stack

Review IAM policy

Next, we need to attach an IAM policy to the FederationWorkshop-ReadOnly role created in first excercise. This policy will allow every federated user of that role to access his or her own home directory. We start by showing you the entire policy, and then break down each statement to explain how they work.

{
  "Version": "2012-10-17",
  "Statement": [
        {
          "Sid": "AllowUserToSeeBucketListInTheConsole",
          "Effect": "Allow",
          "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
          "Resource": ["arn:aws:s3:::*"]
        },
        {
          "Sid": "AllowListingOfUserFolder",
          "Effect": "Allow",
          "Action": "s3:ListBucket",
          "Resource": "arn:aws:s3:::<YOUR_BUCKET_HERE>",
          "Condition": {"StringLike": { "s3:prefix": [ "","home/", "home/${aws:userid}/*" ]}}
        },
        {
          "Sid": "AllowAllS3ActionsInUserFolder",
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": [
            "arn:aws:s3:::<YOUR_BUCKET_HERE>/home/${aws:userid}",
            "arn:aws:s3:::<YOUR_BUCKET_HERE>/home/${aws:userid}/*"
          ]
        }
  ]
}

Statement 1: Allow required Amazon S3 console permissions

The first statement within the policy provides access to actions that are required for the AWS Management Console to function properly. The s3:ListAllMyBuckets action grants users permission to list all the buckets in the AWS account, which is required for navigating to buckets in the AWS Mangement Console. The AWS Mangement Console also performs a s3:GetBucketLocation call when users initially navigate to the Amazon S3 service, which is why users also require permission for that action.

{
    "Sid": "AllowUserToSeeBucketListInTheConsole",
    "Effect": "Allow",
    "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
    "Resource": ["arn:aws:s3:::*"]
}

Statement 2: Allow listing objects in user’s folder

The second statement within the policy provides access to actions that are required for users to navigate to their home directory through the AWS Management Console. Without the s3:ListBucket action, users would not be able to navigate through the root and home folders. Therefore, this statement grants permissions to list objects at the root level of the S3 bucket, the home folder itself, and everything within the folder that matches their aws:userid. This IAM Policy Variable is a feature that lets you specify placeholders in a policy. Instead of creating a separate policy for each user that specifies the user's name as part of the resource, we create a single policy that works for all federated users dynamically. When the policy is evaluated, the policy variables are replaced with values that come from the request itself.

{
          "Sid": "AllowListingOfUserFolder",
          "Effect": "Allow",
          "Action": "s3:ListBucket",
          "Resource": "arn:aws:s3:::<YOUR_BUCKET_HERE>",
          "Condition": {"StringLike": {"s3:prefix": [ "","home/", "home/${aws:userid}/*" ]}}
}

Statement 3: Allow all Amazon S3 actions in user's folder

The third statement of the policy allows the federated user to perform all s3 actions (such as read, write, and delete objects) but limits them to just their home folder.

{
          "Sid": "AllowAllS3ActionsInUserFolder",
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": [
            "arn:aws:s3:::<YOUR_BUCKET_HERE>/home/${aws:userid}",
            "arn:aws:s3:::<YOUR_BUCKET_HERE>/home/${aws:userid}/*"
          ]
}

The key portion of this statement is the Resource element. The first entry allows the user to perform actions on their specific folder. The second entry allows the user to perform actions in their specific folder. Both of these entries are required for the policy to operate as expected. For example, users have permission to change their folder’s storage class, enable encryption, or make their folder public (perform actions on the folder). Similarly, they have permissions to upload files, delete files, and create subfolders within their folder (perform actions in the folder).

Apply the IAM policy

Now you are ready to apply the IAM policy to the FederationWorkshop-ReadOnly role. Open a new browser window and log into the AWS Management Console. Then choose Services, then Security & Identity, and finally IAM as shown in the following screenshot.

IAM Console

Choose Roles from the left pane, and then choose the FederationWorkshop-ReadOnly role, as shown in the following screenshot.

IAM Roles

On the role Summary page, choose the Permissions tab. Under Inline Policies, choose click here, as shown in the following screenshot.

Inline Policy

Note: Read more about the differences between Inline policies and managed policies

On the Set Permissions page, choose Custom Policy.

IAM Policy

On the Review Policy page, type s3-homedir-iam-policy for the name of the policy. In the policy editor, paste the full IAM policy from above. Substitute all three of the occurrences of the <YOUR_BUCKET_HERE> placeholder with the actual bucket name, then choose Validate Policy. After you confirm the the policy is valid, choose Apply Policy.

IAM Policy

Note: Make sure that as you are copying the IAM policy in the IAM policy editor, you check for the whitespaces and json syntax. If you want to validate your policy, you can use Json Validator.

Create home directories for federated users

Within the home directory bucket, you now create a home folder and individual home directories for each federated user.

Create home folder

From the AWS Management Console, choose Services, then Storage & Content Delivery, and finally S3 to navigate to the S3 console, as shown in the following screenshot.

S3 Console

Select the federationworkshophomedirs-<BucketNameSuffix> bucket that was created by CloudFormation earlier in the exercise. Choose Create Folder, and then type home as shown in the following screenshot.

home folder creation

Understanding the home directory naming convention

The individual home directories names in the home folder must match the aws:userid IAM policy variable. For SAML federated users, this variable evaluates to a composite value in the form of RoleId:RoleSessionName. For more details about this and other IAM policy variables see the documentation.

The first portion of the composite value, RoleId, is a form of an IAM unique ID. When IAM creates a user, group, role, policy, instance profile, or server certificate, it assigns to each entity a unique ID that is distinct from the Amazon Resource Name (ARN) or name of the object. Unique IDs also remain unique even in cases where an IAM principal is recreated using the same name. The RoleId can be found by doing a describe of the IAM role from the CLI. Use the following command to determine the RoleId of the FederationWorkshop-ReadOnly role. Copy down this value as you will need it in the subsequent steps.

aws iam get-role --role-name FederationWorkshop-ReadOnly

role id

The second portion of the composite value is RoleSessionName. Recall from the first hour exercise that RoleSessionName is the value provided to AWS by your SAML identity provider. In this workshop, we configured RoleSessionName to be the uid of the user in the back end directory.

So in this example, for our federated user alice, aws:userid will resolve to the following composite value.

AROAIVQ5DNUHIOTQDUAJM:alice

Note: Your value for RoleId will be different from the value shown above.

Create the home directories

Create a folder inside the home folder for each of your federated users (bob and alice) using the Roleid:RoleSessionName format described above inside the home folder of your bucket. Be sure to substitute the value of RoleId that is specific to your account. Once you create the individual folders, it will look similar to the following screenshot.

home directory structure

Testing

Now that you have completed the configuration, let's test it out. To do so, let's make sure that our federated user alice can operate on her directory, but not on bob's directory. If she attempts any such actions, she receives an unauthorized operation exception.

Start by opening a new browser window and enter the IdP initiated login URL for your Identity Provider.

Open Source: https://idp1.example.com:8443/idp/profile/SAML2/Unsolicited/SSO?providerId=urn:amazon:webservices
Microsoft: https://idp1.example.com/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices

Login using alice's credentials and select the FederationWorkshop-ReadOnly role, as shown in the following screenshot.

AWS SAML role chooser page

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

Once you are on the AWS Management Console, navigate to S3.

AWS Management Console

Upload an object in alice's home directory

Navigate to the S3 bucket you created earlier, and choose the home folder. Then choose alice's home directory in the Roleid:RoleSessionName format as shown in the following screenshot.

Alice's home dir

Upload a test file to the home directory by choosing Upload and then Add Files.

Upload File

Once the file transfer has finished, it appears in the left pane, as shown in the following screenshot.

Upload Success

Try to upload an object in bob's home directory

Go back to the home folder where you can see both home directories. Choose the home directory for bob, as shown in the following screenshot.

Bob's home dir

Try to upload a file to this directory, as you did earlier, by choosing Upload in the top left corner and then Add Files. The upload will fail because alice does not have access to upload a file in bob's home directory.

Upload Failed

Key take-aways

In summary, there are two key take-aways from this use case:

Exercise complete

Congratulations! You've successfully completed the S3 home directory advanced use case.

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