Authenticating Users of AWS Mobile Applications with a Token Vending Machine
This article discusses an architecture that enables applications running on a mobile device to more securely interact with Amazon Web Services such as Amazon Simple Storage Service (S3), Amazon SimpleDB, Amazon Simple Notification Service (SNS), and Amazon Simple Queue Service (SQS). The architecture discussed uses a "Token Vending Machine" to distribute temporary security credentials to the mobile application.
About Amazon Web Services
Amazon Web Services ("AWS") is a collection of cloud computing infrastructure services that you can use to develop applications. The services include computing, storage, database, and others. AWS uses a "pay-as-you-go" service model: you are charged only for the services that you or your applications use. To make AWS more approachable as a platform for prototyping and experimentation, AWS offers a free tier, a level of services that allows some AWS users to access AWS at no charge.
Authentication, Credentials, and AWS Costing
Amazon Web Services are accessed programmatically through a RESTful web services interface or through method calls that are exposed in SDK libraries provided on the AWS website. In either case, every request made to AWS contains authentication information that associates the request with an account owner. AWS uses this information to ensure that requests access only those resources for which the account owner is authorized. AWS also uses the information to determine the account that should be charged for service usage. The authentication information is derived from credentials that are issued to the account owner when he or she signs up.
Whose Credentials to Use in the Mobile Application?
When developing a mobile application that interacts with AWS, you will need to decide whose credentials to use for authentication. In some scenarios, the end user of the mobile application will have an AWS account and use his or her own credentials. For example, you might develop an application that other AWS developers will use to monitor their own computing instances in the AWS Elastic Computing Cloud (EC2) service. In this case, the end user would be authenticated with his or her own credentials in order to view resources associated with his or her own AWS account.
There may be other scenarios in which it is preferable that the application not operate under the end user's credentials. For example, the application might need to access AWS resources, such as an Amazon SimpleDB domain, that you, as the developer, own. You might be tempted in this scenario to allow the end user to use your root credentials, that is, the credentials associated with your account. However, for security reasons, you should never embed your root credentials in an application. These credentials provide complete access to all your AWS resources as well as your billing information. You should always keep these credentials as secure as possible and use them only when necessary.
A safer alternative to using your root credentials would be to use IAM user credentials. Using the AWS Identity and Access Management (IAM) service, you could create a user that has credentials which are distinct from your root credentials and which have only those permissions that are necessary for your application. Because the IAM user's credentials have limited permissions, a malicious user who obtained these credentials would be similarly limited in what they could accomplish. (For more information about how to create and permission IAM users, see the IAM documentation.) However, even though IAM user credentials limit exposure, it is still relatively easy for a malicious user to obtain them if they are embedded in a mobile application. Therefore, this strategy still incurs considerable risk.
An additional issue with embedding credentials in your application is that there is no easy way to update the credentials once the application is deployed. Updating--also called "rotating"--credentials is a fundamental best practice for maintaining security. If you embed credentials in your application, the only way to update the credentials is to deploy a new version of the application. However, any user that does not install the new version will find that the application no longer works once the updated credentials are required for authentication to the service.
The Token Vending Machine (TVM) which uses the AWS Security Token Service provides a solution for the issues described above. In addition, it provides benefits that aren't available if you use the risky strategy of embedding credentials.
With the TVM, the application uses temporary credentials which expire after a period of time. These credentials can be limited in scope in the same way as the IAM user credentials described above. However, the temporary credentials expire and are therefore refreshed periodically by the application. This characteristic of the credentials brings two benefits.
One is that because the credentials expire, even if they are obtained by a malicious user, their usefulness is time limited. More importantly though, if you as the developer discover that the credentials have been compromised, you can immediately revoke their permissions. You can then deploy new credentials to the application, and you could configure these new credentials with updated permissions. If you embed credentials in the application and you later need to revoke their permissions, it will render the application unusable until you issue an application update.
The TVM provides additional flexibility in other ways as well. With the TVM, you can customize permissions--or revoke them--on a per-user basis.
AWS Security Token Service
The AWS Security Token Service is a feature of Amazon Identity and Access Management (IAM). AWS Security Token Service provides temporary security credentials that are derived from, but not equivalent to, the credentials of an AWS account. These temporary credentials can be qualified to allow access only to specific AWS services or even to subsets of the functionality provided by an AWS service. For example, temporary credentials could be configured to allow access only to the Amazon Simple Storage Service (S3) or only to a particular storage bucket within the S3 service. Unlike account credentials, temporary credentials are time limited. For example, the authorizations associated with temporary credentials can be set to expire after 12 hours. The maximum time that temporary credentials can remain valid is 36 hours.
The temporary credentials provided by AWS Security Token Service consist of four components:
- Access key ID
- Secret access key
- Session token
- Expiration time
For simplicity, in this document, we'll refer to all four of these components collectively as temporary security credentials or just temporary credentials.
Token Vending Machine
In order to make it easier to leverage temporary credentials, we provide two sample reference applications, called Token Vending Machines (TVMs).
Note: The TVMs are provided as an example of one way to implement the interaction with AWS Security Token Service. You are free to use the TVMs as provided, modify them to fit your application, or use them as inspiration for an entirely separate implementation. The source for the TVMs is available at GitHub for both the Anonymous TVM and the Identity TVM.
In a typical implementation, a mobile application calls a TVM to request temporary credentials for a user. The TVM requests the temporary credentials from AWS Security Token Service and then passes the credentials back to the application. The application uses these temporary credentials in subsequent interactions with AWS. When the credentials expire, the application contacts the TVM for new credentials.
The following diagram shows the flow of the temporary credentials from AWS Security Token Service to the mobile application.
To simplify interaction with the TVMs, the AWS SDK for Android and the AWS SDK for iOS include code samples that demonstrate a possible TVM client implementation. As with the TVM itself, you are free to use this sample code as is, to modify it, or to take a different approach.
In the implementation shown in the above diagram, the TVM sample library has been linked with the mobile application and is part of the software deployed to the mobile device. The application uses the library only to obtain the temporary credentials. Once the application has the credentials, it can interact with any AWS service for which the credentials are authorized.
Anonymous TVM and Identity TVM
We provide two versions of the TVM sample reference application. One version is designed to associate authorizations only with a unique identifier for the mobile device. We refer to this version as the anonymous TVM, because the identity of the mobile device user is not stored in any way.
The other version of the TVM supports user registration and login. It is intended to demonstrate a design that could support features such as varying the authorizations provided depending on the user's identity and collecting data about who is using the application and how. We refer to this version of the TVM as the identity TVM. Let's walk through the interaction between the mobile application and each of these two versions.
The mobile application initiates communication with the TVM by calling the registerdevice method with a unique identifier and a secret key. The unique identifier (UID) is a globally unique identifier (GUID). The TVM associates the UID and secret key with each other and then stores them for future reference. The secret key is used to secure subsequent communications between the application and the TVM.
After this initial registration, the application obtains temporary credentials by calling the gettoken method with the UID, a cryptographic signature, and a timestamp. The cryptographic signature is an HMAC hash generated from the timestamp using the secret key. This signature authenticates the device to the TVM: the TVM uses the UID to look up the secret key and then uses the secret key to verify the signature.
The TVM responds by sending back temporary credentials, which have been encrypted using the secret key. The TVM uses the Advanced Encryption Standard (AES) for this encryption.
The application decrypts the temporary credentials using the key and can then use them to access any AWS services for which the temporary credentials are authorized. Eventually, the expiration time of these temporary credentials will be reached, at which point the application can call gettoken again to obtain new temporary credentials.
The process for the identity TVM is similar to the anonymous case; however, the first step in the anonymous case, registerdevice, is replaced by two steps in the identity case, registeruser and login.
The application initiates communication with the TVM by bringing up a browser on the mobile device to enable the user to register a user name and password with the TVM. The TVM derives a secret key from the password. The TVM stores the user name and secret key for future reference.
The application calls the login method with the user name, the unique identifier (UID), a cryptographic signature, and a timestamp. The cryptographic signature is an HMAC hash generated from the timestamp, using the secure secret key derived from the password. The TVM uses the user name to look up this same derivation of the password, which it then uses to verify the signature. The TVM then sends the application a new secret key that will be the shared secret that enables the TVM and application to communicate securely. Finally, it stores the UID with the user name and the secure encryption key.
The application can now obtain temporary credentials by calling the gettoken method with the UID, a signature, and a timestamp. The process is the same as in the anonymous case. The TVM authenticates the application using the signature and then sends the application the temporary credentials, which have been encrypted using the shared encryption key.
When the application receives the encrypted temporary credentials, it decrypts them. The application can then use the credentials to access any AWS service for which the temporary credentials are authorized. As in the anonymous case, the temporary credentials will eventually expire, at which point the application can call gettoken again to obtain new temporary credentials.
Clearing the UID, Username, and Secret Key
The UID, user name, and secret key that are used to interact with the TVM are stored by the application in a special area of the mobile device. For Android devices, this area is called Shared Preferences. For iOS devices, this area is called the Key Chain. In both of these areas, information stored by one application is not accessible to other applications on the device.
In some cases, the application might need to clear the UID, user name, and secret key from the device. For example, the application might support a logout <9D> function that clears this information. The samples that are provided with the AWS SDK for Android and the AWS SDK for iOS demonstrate how to clear this information.
Hosting the TVM
The TVM samples that we provide are designed to be deployed to AWS Elastic Beanstalk. The TVMs are packaged as Java web archive (.war) files, which makes deployment to AWS Elastic Beanstalk straightforward. Although the samples are designed to work with AWS Elastic Beanstalk, they could easily be adapted to run on Apache Tomcat or in some other environment. To learn more about deploying the TVM, go to the pages for the anonymous and identity TVMs.
Secure Transfer of the Session Token
For security reasons, we strongly recommend that you use Secure Sockets Layer (SSL) to encrypt communications between the application and the TVM. SSL encryption will prevent a malicious third party from copying the password or secret key while it is being transferred.
In order to enable SSL to work with the EC2 instance that hosts the TVM on AWS Elastic Beanstalk, you will need to configure the security group of the EC2 instance to allow inbound traffic on TCP port 443 or whichever port you use for SSL traffic.
You must also ensure that the certification authority that you use to sign your SSL certificate is one that is recognized as valid by your mobile operating system.
For more information on using SSL with AWS Elastic Beanstalk, go to the Identity and Access Management (IAM) User Guide.
The TVM User and Limited Authorization
Although you will need to use your AWS account credentials to deploy the TVM, we recommend that you do not run the TVM under your AWS account. Instead, create an IAM user and configure the TVM to use the credentials of this IAM user, which we will call the TVM user. You can attach policies to the TVM user that limit how he or she can interact with AWS. Because the TVM uses the credentials of the TVM user to request temporary credentials from AWS Security Token Service, the authorizations associated with these temporary credentials are constrained to the authorization available to the TVM user. By setting policies that allow the TVM user access only to the services and data necessary for the application to function, you protect the rest of your AWS resources from inadvertent or malicious access.
Policy Objects Further Limit Authorization
As just described, the authorizations associated with the temporary security credentials are constrained by the authorizations associated with the TVM user. You could further constrain the authorizations for the temporary credentials by modifying the provided samples to attach a policy object to the temporary credentials.
Because a distinct policy object could be attached to each set of temporary credentials, you could specify authorizations on a per UID basis, that is, for each user of the mobile application. For certain types of applications, this capability can be important. For example, consider an application that enables users to upload photos to Amazon Simple Storage Service (S3). If every user had the same authorizations, then users would be able to view each other's photos. To avoid this issue, associate a policy object with each user's credentials that limits each user's access to his or her own photos.
You would need to modify the provided samples in order to implement these user-specific policy objects. For more information about policy objects, see the Identity and Access Management (IAM) documentation
Next Steps and Additional Resources
If you are designing a mobile application that will use AWS, we recommend that you download the files and documentation for the TVM and investigate how you might be able to leverage it in your application. To do so, go to the pages for the anonymous and identity TVMs. For an example of using the Identity TVM to provide per-user segregated access to an Amazon S3 bucket, see this article.
If you haven't already done so, download the AWS SDK for Android or the AWS SDK for iOS--or both if you are engaged in cross-platform development. Each of these SDKs includes a sample client library that works in conjunction with the sample TVM reference applications.
Finally, we recommend the Identity and Access Management (IAM) documentation for information about the process of creating IAM users and designing policies that appropriately limit the scope of their access to AWS.