AWS Security Token Service
Using Temporary Security Credentials (API Version 2011-06-15)
« PreviousNext »
View the PDF for this guide.Go to the AWS Discussion Forum for this product.Go to the Kindle Store to download this guide in Kindle format.Did this page help you?  Yes | No |  Tell us about it...

Creating Temporary Security Credentials for Mobile Apps Using Identity Providers

Imagine that you have a mobile app that needs access to AWS resources. (Or it might be a web app that uses client script; the concepts presented here are the same.) The app might be a game that runs on a phone and stores player and score information in an Amazon S3 bucket or an DynamoDB table. Because the app needs to be able to distinguish individual users, users cannot be anonymous.

Most requests to AWS services must be signed, which requires an access key ID and secret access key. However, for apps that are downloaded to a user's device or computer, we recommend that you do not distribute long-term AWS security credentials such as those for an AWS account or for an IAM user.

Instead, you want to build the app such that it requests temporary security credentials using web identity federation. This way you can create an app that authenticates users—that is, lets users sign in—using these identity providers:

Using any of these providers can simplify the development and management of your app. Instead of providing custom sign-in logic and having to manage user login information (either in a custom system or as IAM users), your app can rely on well-known and secure sign-in protocols that many users already have access to. Because you can trade a token from the identity provider for temporary security credentials, you don't have to distribute any credentials with the app, and you don't need to manage the process of rotating the credentials.

Process for Using Web Identity Federation for Mobile Apps

To use one of the supported identity providers and use web identity federation to get temporary security credentials, you follow the steps outlined here.

Note

To help understand how web identity federation works, you can use the Web Identity Federation Playground. This interactive website lets you walk through the process of authenticating via Login with Amazon, Facebook, or Google, getting temporary security credentials, and then using those credentials to make a request to AWS.

  1. Sign up as a developer with the identity provider. You also configure your app with the provider; when you do, the provider gives you an ID that's unique to your app. (Different providers use different terminology for this process. We're using the term configure for the process of identifying your app with the provider.) Each provider gives you an app ID that's unique to that provider, so if you configure the same app with multiple providers, your app will have multiple app IDs. You can configure multiple apps with each provider.

    The following external links provide information about using one of the identity providers:

  2. In AWS, create one or more IAM roles. For each role, define who can assume the role (the trust policy or trust relationship) and what permissions the app's users will have (the access policy).

    Create one role for each identity provider for each app. For example, you might create a role that can be assumed by an app where the user signed in using Login with Amazon, a second role for the same app where the user has signed in using Facebook, and a third role for the app where users sign in using Google. For the trust relationship, specify the identity provider (like Amazon.com) as the federated principal (the trusted entity), and include a condition that matches the app's ID. Examples of the roles for different providers are shown later in this topic.

  3. In your application, authenticate your users using Login with Amazon, Facebook, or Google. To do this, call the identity provider using an interface that they provide. For example, you might call an API and pass the user's credentials and possibly other information that the provider requires. The exact way in which you authenticate the user depends on the provider and on what platform your app is running. Typically, if the user is not already signed in, the identity provider takes care of displaying a sign-in page for that provider. After the identity provider authenticates the user, the provider returns a token to your app.

  4. In your app, make an unsigned call to the AssumeRoleWithWebIdentity action to request temporary security credentials. In the request, you pass the identity provider's token and specify the ARN for the IAM role that you created for that identity provider. AWS verifies that the token is trusted and valid. If so, AWS STS returns temporary security credentials to your app that have the permissions derived from the role you named in the request. The response also includes metadata about the user from the identity provider, such as the unique user ID that the identity provider assigned to the user.

  5. Using the temporary security credentials you get in the AssumeRoleWithWebIdentity response, your app makes signed requests to AWS APIs. The user ID information from the identity provider can be used to distinguish users in the app—for example, you can put objects into Amazon S3 folders that include the user ID as prefixes. This allows you to create access control policies that lock that folder down so only the user with that ID can access it. For more information, see Identifying Providers, Apps, and Users with Web Identity Federation later in this topic.

  6. Your app caches the temporary security credentials so that you do not have to get new ones each time the app needs to make a request to AWS. By default, the credentials are good for one hour. When the credentials expire (or before then), you make another call to AssumeRoleWithWebIdentity to obtain a new set of temporary security credentials. Depending on the identity provider and how they manage their tokens, you might have to refresh the provider's token before you make a new call to AssumeRoleWithWebIdentity, since the provider's tokens also usually expire after a fixed time. (If you're using the AWS SDK for iOS or the AWS SDK for Android, you can use the AmazonSTSCredentialsProvider action, which manages the AWS STS credentials, including refreshing them as required.)

Invoking the Identity Provider to Authenticate the User

In your app, when a user signs in, you invoke the authentication process for the identity providers you configured the app with. The specifics of how you do this vary both according to which identity provider you're using (Login with Amazon, Facebook, or Google) and what platform your app is running on. For example, an Android app can use a different way to authenticate than an iOS app or a JavaScript-based web app.

In general, the authentication process returns a token to the app that represents the authenticated user. You might also get back additional information about the user, depending on what the provider exposes and what information the user is willing to share. You can use this information in your app.

Creating a Role to Allow AWS Access for the Mobile App

In order to allow the mobile app to access resources, you must create one or more IAM roles that the app can assume. As with any role, a role for the mobile app contains two policies. One is the trust policy that specifies who can assume the role (the trusted entity, or principal). The other policy (the access policy) specifies the actual AWS actions and resources that the mobile app is allowed or denied access to, and is similar to user or resource policies.

The trust policy must grant an Allow effect for the sts:AssumeRoleWithWebIdentity action. In this role, you use two values that let you make sure that the role can be assumed only by your application:

  • For the Principal element, you use the string {"Federated":providerUrl}. The following are acceptable ways to specify the principal:

    "Principal":{"Federated":"www.amazon.com"}

    "Principal":{"Federated":"graph.facebook.com"}

    "Principal":{"Federated":"accounts.google.com"}

  • In the Condition element, you use a StringEquals condition to test that the app ID in the request matches the app ID that you got when you configured the app with the identity provider. This ensures the request is coming from your app. In the policy, you can test the app ID you have against the following policy variables:

    www.amazon.com:app_id

    graph.facebook.com:app_id

    accounts.google.com:aud

Notice that the values you use for the principal in the role are specific to an identity provider. A role can specify only one principal. Therefore, if the mobile app allows users to sign in using more than one identity provider, you must create a role for each of the identity providers.

Note

Because the policy for the trusted entity uses policy variables that represent the provider and the app ID, you must set the Version element to 2012-10-17.

You can use the IAM console to create a role for web identity federation. The console lets you choose Roles for Web Identity Provider Access for the role type, and then walks you through the process of configuring the principal and of creating a condition that tests for the app ID. For more information, see Creating a Role in Using IAM.

The following example shows a trust policy for a role that the mobile app could assume if the user has signed in using Login with Amazon. In the example, amzn1.application-oa2-123456 is assumed to be the app ID that Amazon assigned when you configured the app using Login with Amazon.

{
  "Version": "2012-10-17",
  "Id": "RoleForLoginWithAmazon",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "www.amazon.com"},
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {"StringEquals": {"www.amazon.com:app_id": "amzn1.application-oa2-123456"}}
  }]
}

The following example shows a policy for a role that the mobile app could assume if the user has signed in using Facebook. 111222333444555 is assumed to be the app ID assigned by Facebook.

{
  "Version": "2012-10-17",
  "Id": "RoleForFacebook",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "graph.facebook.com"},
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {"StringEquals": {"graph.facebook.com:app_id": "111222333444555"}}
  }]
}

The following example shows a policy for a role that the mobile app could assume if the user has signed in using Google. 111222333444555666777 is assumed to be the app ID assigned by Google.

{
  "Version": "2012-10-17",
  "Id": "RoleForGoogle",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "accounts.google.com"},
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {"StringEquals": {"accounts.google.com:aud": "111222333444555666777"}}
  }]
}

Getting Temporary Credentials

To get temporary credentials that your app can use to make calls to AWS APIs, you call the AssumeRoleWithWebIdentity action of the AWS Security Token Service. This is an unsigned call, meaning that the app does not have to have access to any AWS security credentials in order to make the call. When you make this call, you pass the following information:

  • The ARN of the role that the app should assume, as described in the preceding section. As noted, if your app supports multiple ways for users to sign in, you will have defined multiple roles, one per identity provider. The call to AssumeRoleWithWebIdentity should include the ARN of the role that's specific to the provider through which the user signed in.

  • The token that the app got from the identity provider after the app authenticated the user.

  • The duration, which specifies how long the temporary security credentials are good for. The maximum (and the default) is 1 hour (3600 seconds). You need to pass this value only if you want the temporary credentials to expire before 1 hour. The minimum duration for the credentials is 15 minutes (900 seconds).

  • A role session name, which is a string value that can be used to identify the session.

  • Optionally, a policy (in JSON format). This policy is combined with the policy associated with the role. This lets you further restrict the access permissions that will be associated with the temporary credentials, beyond the restrictions already established by the role access policy. Note that this policy cannot be used to elevate privileges beyond what the assumed role is allowed to access.

    Note

    Because a call to AssumeRoleWithWebIdentity is not signed, you should only include this optional policy if the request is not being transmitted through an untrusted intermediary.

When you call AssumeRoleWithWebIdentity, AWS verifies the authenticity of the token. For example, depending on the provider, AWS might make a call to the provider and include the token that the app has passed. Assuming that the identity provider validates the token, AWS returns the following information to you:

  • A set of temporary security credentials. These consist of an access key ID, a secret access key, and a session token.

  • The role ID and the ARN of the assumed role.

  • A SubjectFromWebIdentityToken value that contains the unique user ID.

When you have the temporary security credentials, you can use them to make AWS API calls. This is the same process as making an AWS API call using long-term security credentials, except that you must include the session token, which lets AWS verify that the temporary security credentials are valid.

Your app should cache the credentials. As noted, by default the credentials expire after an hour. If you are not using the AmazonSTSCredentialsProvider action in the AWS SDK, it's up to your app to call AssumeRoleWithWebIdentity again to get a new set of temporary security credentials before the existing set expires.

Identifying Providers, Apps, and Users with Web Identity Federation

When you create access policies in IAM, it's often useful to be able to specify permissions based on configured apps and on the ID of users who have authenticated using an identity provider. For example, your mobile app that's using web identity federation might keep information in Amazon S3 using a structure like this:

myBucket/app1/user1
myBucket/app1/user2
myBucket/app1/user3
...
myBucket/app2/user1
myBucket/app2/user2
myBucket/app2/user3
...

You might also want to additionally distinguish these paths by provider. In that case, the structure might look like the following (only two providers are listed to save space):

myBucket/Amazon/app1/user1
myBucket/Amazon/app1/user2
myBucket/Amazon/app1/user3
...
myBucket/Amazon/app2/user1
myBucket/Amazon/app2/user2
myBucket/Amazon/app2/user3

myBucket/Facebook/app1/user1
myBucket/Facebook/app1/user2
myBucket/Facebook/app1/user3
...
myBucket/Facebook/app2/user1
myBucket/Facebook/app2/user2
myBucket/Facebook/app2/user3
...

For these structures, app1 and app2 represent different apps, such as different games, and each of the app's users has a distinct folder. The values for app1 and app2 might be friendly names that you assign (for example, mynumbersgame) or they might be the app IDs that the providers assign when you configure your app. If you decide to include provider names in the path, those can also be friendly names like Amazon and Facebook.

You can typically create the folders for app1 and app2 through the AWS Management Console, since the application names are static values. That's true also if you include the provider name in the path, since the provider name is also a static value. In contrast, the user-specific folders (user1, user2, user3, etc.) have to be created at run time from the app, using the user ID that's available in the SubjectFromWebIdentityToken value that is returned by the request to AssumeRoleWithWebIdentity.

To write policies that allow exclusive access to resources for individual users, you can match the complete folder name, including the app name and provider name, if you're using that. You can then include the following provider-specific keys that reference the user ID that is returned from the provider:

  • www.amazon.com:user_id

  • graph.facebook.com:id

  • accounts.google.com:sub

The following example shows an access policy that grants access to a bucket in Amazon S3 whose prefix matches this:

myBucket/Amazon/mynumbersgame/user1

The example assumes that the user has signed in using Login with Amazon, and that the user is using the app to which you've given the friendly name mynumbersgame. You would create similar policies for users who have signed in using Facebook and Google; those policies would use a different provider name as part of the path and would use different app IDs.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::myBucket"],
      "Condition": {"StringLike": {"s3:prefix": ["Amazon/mynumbersgame/${www.amazon.com:user_id}/*"]}}
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::myBucket/amazon/mynumbersgame/${www.amazon.com:user_id}",
        "arn:aws:s3:::myBucket/amazon/mynumbersgame/${www.amazon.com:user_id}/*"
      ]
    }
  ]
}

Additional Resources for Web Identity Federation

The following resources can help you learn more about web identity federation:

  • The Web Identity Federation Playground is an interactive website that lets you walk through the process of authenticating via Login with Amazon, Facebook, or Google, getting temporary security credentials, and then using those credentials to make a request to AWS.

  • The entry Web Identity Federation using the AWS SDK for .NET on the AWS .NET Development blog walks through how to use web identity federation with Facebook and includes code snippets in C# that show how to call AssumeRoleWithWebIdentity and how to use the temporary security credentials from that API call in order to access an Amazon S3 bucket.

  • The AWS SDK for iOS and the AWS SDK for Android contain sample apps. These apps include code that shows how to invoke the identity providers, and then how to use the information from these providers to get and use temporary security credentials.

  • The article Web Identity Federation with Mobile Applications discusses web identity federation and shows an example of how to use web identity federation to get access to content in Amazon S3.