TL;DR: you can access the AWS APIs securely (e.g. S3, DynamoDB, EC2) from browsers (i.e. using JavaScript) or native apps, without the need of a backend server. Live demo @

In the past, we've talked about how it's becoming so much easier to write client side apps that are still fully secure thanks to JSON Web Tokens: (Cookies vs Tokens, Token-based auth with and 10 things you should know about tokens).

In this article, we will show how to use AWS APIs from the client side, without the need to go through a server. The process is illustrated in the following diagram:

  1. The user logs in and gets a JSON Web Token (JWT)
  2. Gets AWS Token (Temp Credentials) using the JWT
  3. Call the AWS API using the the AWS Token

We are assuming you have an AWS account and Auth0 account.

1. The user logs in and gets a JWT

First, we initialize the JavaScript login widget and call .signin.

  var widget = new Auth0Widget({ domain: '', clientID: 'your-client-id', callbackURL: 'your-callback-url' });


The login result comes in the location.hash. The getProfile method will return the profile and JWT and we store those in local storage.

widget.getProfile(location.hash, function (err, profile, id_token) {
  store.set('profile', JSON.stringify(profile));
  store.set('id_token', id_token);

  location.href = 'files.html'

2. Get AWS Temp Credentials using the JWT

After the user is logged in, Auth0 will send you a JSON Web Token (JWT). We then use the /delegation endpoint in Auth0 to exchange the JWT (id_token) obtained in step 1 for an AWS token. Behind the scenes, the Auth0 server will call AWS IAM APIs to perform this.

Here's the code:

  var aws_arns = {
      role: 'arn:aws:iam::account_number:role/role_name',
      principal: 'arn:aws:iam::account_number:saml-provider/provider_name'

  var aws_creds;
  auth0.getDelegationToken('.. client_id ..', store.get('id_token'), aws_arns, function(err, result) {
     aws_creds = result.Credentials; // AWS temp credentials

The role and principal are values you get from AWS IAM console. You have to do a one-time configuration to add Auth0 as an identity provider, and create a role and a policy. More details here

As an example, this policy gives permission to do everything on an S3 folder under a bucket. The name of the folder gets resolved at runtime depending on the contents of the JSON Web Token. The user_id in the JWT will be replaced as the name of the folder (${saml:sub} is a placeholder for the user_id).

3. Upload file using AWS Session Token

Here we set the bucket.config.credentials with the AWS Token we've got on Step 2 (aws_creds) and call putObject using the user_id as part of the S3 path.

bucket.config.credentials = new AWS.Credentials(aws_creds.AccessKeyId,

bucket.putObject({ Key: folder_prefix + user_id + '/' +,
                   ContentType: file.type,
                   Body: file,
                   ACL: 'private'}, callback);

We are using the AWS JavaScript SDK.

Here is a short video showing the whole process:

AWS APIs supported

This technique could be also used for any AWS API, besides S3:

For a complete list of AWS services theta support IAM policies see:

Finally, AWS recently announced their support for Creating Temporary Security Credentials for Mobile Apps using Google, Facebook or Amazon Login. That works similarly to what we are showing here, however it only supports these 3 identity providers: Amazon, Facebook and Google. With Auth0 you can expand this to work with any identity provider: your own username/passwords, enterprise credentials or a long list of social providers.

Tokens FTW!