Credential Management for Mobile Applications

Sample Code & Libraries>Java>Credential Management for Mobile Applications
Community Contributed Software

  • Amazon Web Services provides links to these packages as a convenience for our customers, but software not authored by an "@AWS" account has not been reviewed or screened by AWS.
  • Please review this software to ensure it meets your needs before using it.

Sample application showing how to use the TVM with Mobile Applications.

Details

Submitted By: Glenn@AWS
AWS Products Used: AWS SDK for Android, AWS SDK for iOS
Language(s): Java, Objective-C
Created On: August 23, 2012 8:35 PM GMT
Last Updated: September 24, 2014 7:28 PM GMT
Download

Credential Management for Mobile Applications

Amazon Cognito

  • AWS has released Amazon Cognito. In many cases Amazon Cognito will replace the use of a Token Vending Machine as specified below. Please consider using Amazon Cognito in place of a TVM.
  • This content is being maintained for historical reference.

This article is a supplement to Authenticating Users of AWS Mobile Applications with a Token Vending Machine. It provides additional details on how to secure your Amazon Web Services (AWS) resources when using the token vending machine (TVM) with mobile applications. First, it is important to understand why mobile security is hard. For native mobile applications, the application code exists and executes on the device. This makes it possible for malicious users to extract AWS credentials embedded within the application. Once they have access to the credentials, they may be able to impersonate the application to malicious intent. The purpose of this article is to provide guidance on methods that help secure your AWS resources and limit the access malicious users would have if they were to gain access to your application's credentials.

Restrictions on AWS resources can be applied using two distinct mechanisms: the AWS Security Token Service (STS) and policies. The TVM demonstrates how to use both of these mechanisms to help secure your mobile applications. This article explains STS and policies and shows how they are used in the TVM by detailing a sample application that provides user-specific and limited access to an Amazon Simple Storage Service (Amazon S3) bucket.

AWS Security Token Service

The AWS Security Token Service (STS) is a web service that enables you to request temporary, limited-privilege credentials for AWS Identity and Access Management (IAM) users or for users that you authenticate (federated users). It is through this service that the TVM creates temporary credentials and limits them with an application-specific policy. The sample included in this article shows how to dynamically create these policies on a per-user basis.

Policies

Policies are used to specify permissions for temporary credentials or for an IAM user. In the TVM, we put a policy on the IAM user as well as on all the temporary credentials issued by the TVM. IAM enforces the principle of least privilege, so the policy on the IAM user limits the overall scope of access granted to the application; it represents a maximum level of permission. In the TVM, this restricted IAM user's credentials are used to call STS which then issues the temporary credentials to the mobile application. By placing an additional policy on the temporary credentials themselves, we further restrict the access a given application's user has to your AWS resources.

It is important to limit the IAM user to the maximum set of resources and operations that any user within the application might need. In addition, it is appropriate to further limit access for each individual user based on that user's needs. In the sample application, we provide application users with individual "folders" within Amazon S3. These file stores are implemented inside a single Amazon S3 bucket. Each user can list, create, update, and delete Amazon S3 objects within their store. However, no user can view, get, put, or delete objects in another user's store. There are two important but distinct levels of protection being applied. First, because of the policies applied to the STS credentials, a malicious user is able to tamper only with their own store; they are NOT able to touch or view the data of another user or any of the resources owned by the developer. Second, even if the IAM user's credentials were compromised, only the single Amazon S3 bucket would be accessible. In this scenario, a malicious user would be able to view and change other users' file stores, but would still not have access to any of the developer's other AWS resources. Note, however, that compromising the IAM user's credentials is difficult; those credentials are stored in the TVM (server), whereas the temporary credentials are passed to the application running on the mobile device itself. Additionaly, the temporary credentials have a minimum lifetime of 1 hour and a maximum of 36, so access would be limited to a period of time.

Levels of Access

The following diagram should help to clarify how everything fits together:

The Amazon S3 Personal File Store sample application

In the provided sample, we demonstrate how to modify the existing identity TVM to provide users with personal file stores using Amazon S3. It is assumed that the reader has read and is familiar with the original token vending machine article.

First, we want to limit the overall access of the application by restricting the IAM User. To do this, we apply the following policy to the TVM's IAM User after creation:

        {
            "Statement": 
            [
                {
                    "Effect": "Allow",
                    "Action": ["s3:PutObject","s3:GetObject","s3:DeleteObject"],
                    "Resource": "arn:aws:s3:::__MY_APPS_BUCKET_NAME__/*"
                },
                {
                    "Effect": "Allow",
                    "Action": ["s3:ListBucket"],
                    "Resource": "arn:aws:s3:::__MY_APPS_BUCKET_NAME__"
                },
                {
                    "Effect": "Allow",
                    "Action": "sts:GetFederationToken",
                    "Resource": "*"
                },
                {
                    "Effect": "Allow",
                    "Action": "iam:GetUser",
                    "Resource": "*"
                },
                {
                    "Effect": "Allow",
                    "Action": "sdb:*",
                    "Resource": "*"
                }
            ]
        }                
        

The developer should replace the string __MY_APPS_BUCKET_NAME__ with the appropriate value. In the above policy, each statement has a specific effect, either for the token vending machine or for the application itself:

  • The first statement allows the application to create, delete, and retrieve objects within the specified Amazon S3 bucket.
  • The second statement allows the application to list the objects in the specified Amazon S3 bucket.
  • The third statement allows the TVM to create temporary credentials using the AWS Security Token Service (STS).
  • The fourth statement is used by the TVM to access the developer's AWS Account ID.
  • The fifth statement allows the TVM to access the Amazon SimpleDB domains used to store the user accounts created and utilized by the TVM.

This policy significantly limits the access and power of the IAM user and therefore improves security. As shown in the diagram, it limits the set of resources available within the developer's account. Even if the IAM user's credentials were to be compromised, they would still provide only limited permissions. The owner of the account could inspect the Amazon S3 bucket and Amazon SimpleDB domains to see if there had been any tampering. The IAM user's credentials are never sent to the device; they are used only as parameters to AWS Elastic Beanstalk as part of the TVM configuration.

Next, the TVM dynamically creates a policy that limits the access provided by the generated temporary credentials. The following template serves as a basis to create a custom policy for each individual user in order to constrain that user's access. The policy below is an application-specific replacement for the sample policy provided with the default TVMs. This policy is specific to the Amazon S3 Personal File Store application. When using the TVM, you should create and use your own application-specific policy. The following policy can be found in the file TokenVendingMachinePolicy.json.

         { 
            "Statement":
            [
                {"Effect":"Allow","Action":["s3:PutObject","s3:GetObject","s3:DeleteObject"],"Resource":"arn:aws:s3:::__MY_APPS_BUCKET_NAME__/__USERNAME__/*"},
                {"Effect":"Allow","Action":"s3:ListBucket","Resource":"arn:aws:s3:::__MY_APPS_BUCKET_NAME__","Condition":{"StringLike":{"s3:prefix":"__USERNAME__/"}}},
                {"Effect":"Deny","Action":["sts:*", "iam:*", "sdb:*"],"Resource":"*"}
            ]
         }
        
Here again the developer supplies the __MY_APPS_BUCKET_NAME__ value which should match the value in the preceding policy. However, the TVM automaticlly replaces the __USERNAME__ value using the username that the user logged into the application with. Each statement in the policy has a distinctive purpose:
  • The first statement allows each application user to get, put and delete objects in the specified Amazon S3 bucket, but requires that the object name be prefixed with their username. This has the effect of "segregating" the users into separate "folders" of the Amazon S3 bucket.
  • The second statement allows users to list only their object's contents by enforcing the prefix condition on the specified bucket.
  • The final statement removes the STS, IAM, and Amazon SimpleDB permissions that the IAM user was given. These permissions are necessary for the IAM user and TVM, but not for the application users.

The preceding policy requires the AWS Mobile SDKs to be used in a specific fashion in order to list, get, and put objects. In the following section, we show the relevant code snippets from the sample application.

Listing Objects

The only requirement to list objects in the application's bucket is to provide the prefix. The prefix is the user's username followed by a forward slash ("/"), as required by the policy.

  • iOS

S3ListObjectsRequest  *listObjectsRequest = [[[S3ListObjectsRequest alloc] initWithName:__MY_APPS_BUCKET_NAME__] autorelease];
listObjectRequest.prefix = [NSString stringWithFormat:@"%@/", __USERNAME__];

S3ListObjectsResponse *listObjectResponse = [s3Client listObjects:listObjectRequest];
                    

  • Android

ListObjectsRequest req = new ListObjectsRequest();
req.setBucketName( __MY_APPS_BUCKET_NAME__ );
req.setPrefix( __USERNAME__ + "/" );
		
ObjectListing objects = s3Client.listObjects( req );
                    

Put Object

Putting objects into the application bucket requires that the user's username be a prefix followed by the forward slash ("/") character.

  • iOS

NSString *keyName = [NSString stringWithFormat:@"%@/%@", __USERNAME__, objectName.text];
        
S3PutObjectRequest *por = [[[S3PutObjectRequest alloc] initWithKey:keyName inBucket:__MY_APPS_BUCKET_NAME__] autorelease];
por.data = data;

[s3Client putObject:por];
                    

  • Android

ByteArrayInputStream bais = new ByteArrayInputStream( data.getBytes() );
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength( data.getBytes().length );

String keyName = __USERNAME__ + "/" + objectName.getText().toString();
s3Client.putObject(__MY_APPS_BUCKET_NAME__, keyName, bais, metadata );
                    

Get Object

When listing the objects, the names returned contain the user-specific prefix as part of the name. Therefore, getting objects does not require additional logic.

  • iOS

S3GetObjectRequest  *getObjectRequest  = [[[S3GetObjectRequest alloc] initWithKey:__OBJECT_NAME__ 
                                                                       withBucket:__MY_APPS_BUCKET_NAME__] autorelease];
S3GetObjectResponse *getObjectResponse = [s3Client getObject:getObjectRequest];
                    

  • Android

S3Object objectData = s3Client.getObject( __MY_APPS_BUCKET_NAME__, __OBJECT_NAME__ );                   
                    

What's Missing

The sample TVMs we supply are intended to demonstrate a partial solution that highlights certain services and features. Feel free to customize the TVMs to meet your specific needs and modify both the server and client code where appropriate. Some features that are not included in the sample TVM, but that you might consider implementing, are:

  • Limiting the number of passwords a user can attempt and locking out a user for too many failed attempts.
  • Including a password reset/recovery mechanism.
  • Providing user/device management utilities.
  • Offering the ability to audit consumed AWS resources--especially on a per user basis.
You can easily modify the TVM to provide the above functionality--or other functionality if a specific application requires it.

Final Thoughts

This article and sample focus specifically on Amazon S3, but the techniques shown here are not limited to Amazon S3. The same care and diligence should be taken when using any AWS service. Below are additional resources for learning how to apply policies to AWS services. Finally, the Amazon S3 Personal File Store sample uses the username as part of the policy set on temporary credentials returned to the application. For this sample, a user changing their username would be problematic for the application. A user who utilized one username would not be able to access those resources once the username was changed. Additionally, it is important that usernames be kept unique. The TVM does this by default, but it is important for this sample to keep that functionality intact.

References

The full sample code includes the modified Identity TVM used for the Amazon S3 Personal File Store sample as well as both the Android and iOS sample applications. You can find it here:

The downloadable sample code requires the AWS Mobile SDKs. Follow these links to download the AWS Mobile SDKs:

For more information about using AWS credentials with mobile applications go the following article:

For more information about policies, read the following topics:

For more information about the AWS Security Token Service, follow this link

Questions?

Please feel free to ask questions or post comments in the Mobile Development Forum.

©2014, Amazon Web Services, Inc. or its affiliates. All rights reserved.