AWS Security Token Service
Using Temporary Security Credentials (API Version 2011-06-15)
Did this page help you?  Yes | No |  Tell us about it...
« 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.

Creating Temporary Security Credentials for Mobile Apps Using Identity Providers

Imagine that you are creating a mobile app that must access AWS resources such as a game that runs on a mobile device and stores player and score information using Amazon S3 and DynamoDB.

Most requests to AWS services must be signed with an AWS access key. However, we strongly recommend that you not distribute long-term AWS credentials with apps that are downloaded to a user's device, even in an encrypted store. Instead, build your app so that it requests temporary AWS security credentials using web identity federation.

Using web identity federation, you don't need to create custom sign-in code or manage your own user identities. Instead, users of your app can sign in using a well-known identity provider—such as Login with Amazon, Facebook, Google, or any other OpenID Connect (OIDC)-compatible identity provider—and then exchange that external identity for temporary security credentials in AWS that have permissions to use resources in your AWS account. Using an identity provider helps you keep your AWS account secure, because you don't have to distribute long-term security credentials with your application.

For most scenarios, we recommend that you use Amazon Cognito. You can use this service with the AWS SDK for iOS and the AWS SDK for Android to create unique identities for users, using any identity provider supported by AWS. Amazon Cognito also supports unauthenticated (guest) access, and you can migrate user data when a user signs in. Amazon Cognito provides APIs for synchronizing user data so that it is preserved as users move between devices. For more information, see the following:

If you don't use Amazon Cognito, you must write the code that interacts with a web identity provider (Login with Amazon, Facebook, Google, or any other OIDC-compatible identity provider) and then calls the AssumeRoleWithWebIdentity API to trade the authentication token you get from those providers for temporary security credentials. If you have already used this approach for existing apps, you might want to continue to use it.

Using Amazon Cognito with Mobile Apps

The preferred way to use web identity federation is to use Amazon Cognito. The following list outlines the process for using Amazon Cognito to authenticate users and give your app access to AWS services. For specific steps to accomplish this scenario, consult the documentation for Amazon Cognito.

  1. (Optional) Sign up as a developer with Login with Amazon, Facebook, Google, or any other OpenID Connect (OIDC)-compatible identity provider and configure one or more apps with the provider. This step is optional because Amazon Cognito supports unauthenticated (guest) access for your users.

  2. Go to Amazon Cognito in the AWS Management Console. Use the Amazon Cognito wizard to create an identity pool, which is a container that Amazon Cognito uses to keep end user identities organized for your apps. You can share identity pools between apps. When you set up an identity pool, you create 1 or 2 IAM roles (one for authenticated identities, and one for unauthenticated "guest" identities) that define permissions for Amazon Cognito users.

  3. Download and integrate the AWS SDK for iOS or the AWS SDK for Android with your app, and import the files required to use Amazon Cognito.

  4. Create an instance of the Amazon Cognito credentials provider, passing the identity pool ID, your AWS account number, and the Amazon Resource Name (ARN) of the roles that you associated with the identity pool. The Amazon Cognito wizard in the AWS Management Console provides sample code to help you get started. (Currently, sample code is available for iOS and Android only.)

  5. When your app accesses an AWS service, pass the credentials provider instance to the client object, which passes temporary security credentials to the client. The permissions for the credentials are based on the role or roles that you defined earlier.

For more information, see the following:

Using Web Identity Federation for Mobile Apps

Our recommendation is that you use Amazon Cognito for almost all web identity federation scenarios. Amazon Cognito is easy to use and provides additional capabilities like anonymous (unauthenticated) access, and synchronizing user data across devices and providers. However, if you have already created an app that uses web identity federation by manually calling the AssumeRoleWithWebIdentity API, you can continue to use it and your apps will still work fine.

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.

The following list outlines the process for using web identity federation without using Amazon Cognito.

  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 Amazon Resource Name (ARN) for the IAM role that you created for that identity provider. AWS verifies that the token is trusted and valid and if so, AWS STS returns temporary security credentials to your app that have the permissions derived from the role that 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}. For OpenID Connect (OIDC) providers, the providerUrl is the fully qualified URL of the OIDC provider that you created in IAM. The following are acceptable ways to specify the principal:

    "Principal":{"Federated":"cognito-identity.amazonaws.com"}

    "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 identity pool ID (for Amazon Cognito) or the app ID—also known as the client ID or audience—(for other providers) 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:

    cognito-identity.amazonaws.com:aud

    www.amazon.com:app_id

    graph.facebook.com:app_id

    accounts.google.com:aud

    For OIDC providers, use the fully qualified URL of the OIDC provider with the aud context key, like the following example.

    server.example.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 policy's Version element to 2012-10-17.

If you are using Amazon Cognito, you can use the Amazon Cognito console to set up roles. Otherwise, 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 for Web Identity Federation 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. 666777888999000 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": "666777888999000"}}
  }]
}

The following example shows a policy for a role that the mobile app could assume if the application is using Amazon Cognito. us-east:12345678-ffff-ffff-ffff-123456 is assumed to be the identity pool ID assigned by Amazon Cognito.

{
  "Version": "2012-10-17",
  "Id": "RoleForCognito",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "cognito-identity.amazonaws.com"},
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {"StringEquals": {"cognito-identity.amazonaws.com:aud": "us-east:12345678-ffff-ffff-ffff-123456"}}
  }]
}

Getting Temporary Credentials

To get temporary credentials that your app can use to make calls to AWS APIs, you call an API. The API you call depends on the web identity provider you're using.

If you're using Amazon Cognito, you can use the Amazon Cognito Credentials Provider in the AWS Mobile SDKs. This returns temporary security credentials that your app can use to make requests to AWS.

If you are not using Amazon Cognito, 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 Amazon Resource Name (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 Cognito, Amazon, Facebook, and Google.

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:

  • cognito-identity.amazonaws.com:sub

  • www.amazon.com:user_id

  • graph.facebook.com:id

  • accounts.google.com:sub

For OIDC providers, use the fully qualified URL of the OIDC provider with the sub context key, like the following example:

  • server.example.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 Amazon Cognito, Facebook, Google, or another OpenID Connect compatible identity provider; 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:

  • Amazon Cognito Identity in the AWS SDK for Android Developer Guide and Amazon Cognito Identity in the AWS SDK for iOS Developer Guide.

  • 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.