AWS Official Blog

Delegating API Access to AWS Services Using IAM Roles

by Jeff Barr | on | in AWS IAM |

Today I’m happy to bring you a guest post from Anders Samuelsson, Senior Product Manager on the AWS Identity and Access Management team.

– Jeff;


Suppose you run a research lab and you dump a terabyte or so of data into Amazon DynamoDB for easy processing and analysis. Your colleagues at other labs and in the commercial sphere have become aware of your research and would like reproduce your results and perform further analysis on your own. Until now, this would have been a fairly difficult undertaking.

Today, we are giving you the tools and facilities needed to simplify the implementation of this very important (not to mention powerful) use case. You can now use an AWS Identity and Access Management (IAM) role in combination with IAM users to enable cross-account API access or delegate API access within an account. This new feature gives you better control and simplifies access management when you are managing services and resources across multiple AWS accounts.

Earlier this year we introduced IAM roles for EC2 instances. Roles for Amazon EC2 enable you to define IAM roles, which specify a set of permissions that an EC2 instance can assume to act on your behalf. Now, IAM users can also assume roles, so you can enable cross-account API access or delegate API access within an account without having to share long-term security credentials.

When you assume an IAM role, you get a set of temporary security credentials that have the permissions associated with the role. You use these temporary security credentials instead of your long-term security credentials in calls to AWS services. You then interact with the service with the permissions granted to the IAM role you assumed.

Let’s take a closer look at how you might use this in practice.

How do I grant users API access across AWS accounts?
Let’s assume your company has two AWS accounts:

  • research@example.com is where data from several research projects are stored
  • aws@example.com is your company.s main account where you have created most of your IAM users

Let’s also assume that a developer is defined as IAM user “Joe” in aws@example.com. Joe needs read-only access to data stored in DynamoDB tables that are in research@example.com.

Enabling cross-account API access requires establishing a trust relationship between the two accounts. (In our example, that’s between aws@example.com and research@example.com.)

Account administrators can establish the trust relationship in two steps:

  1. Configure the trusting entity (the account that owns the resources)
  2. Configure the trusted entity (the account where the IAM user is managed)

1. Configure the Trusting Entity
To establish the trust relationship, the administrator for research@example.com performs the following steps to grant IAM users in aws@example.com the ability to assume a role that grants read-only access to DynamoDB:

  1. Signs in to the IAM console and clicks the Roles link.
  2. Clicks Create a role
  3. Enters a name for the IAM role. In this example, the role is named DynamoDB-ReadOnly-role.
  4. Expands Roles for cross-account access and selects the role type Provide access between AWS accounts you own.
  5. Adds aws@example.com as the account from which IAM users can access research@example.com. The administrator does this by specifying the AWS account ID for aws@example.com. He gets the AWS Account ID from the My Account page in the AWS Management Console dropdown.
  6. Assigns a policy to the IAM role that grants read-only access to DynamoDB. The administrator does this by picking the Amazon DynamoDB Read Only Access policy from the policy template list.

2. Configure the Trusted Entity

Now that the admin of research@example.com has granted access to aws@example.com, the administrator of aws@example.com has to go in and explicitly grant access to the individual IAM users which should have access to assume the DynamoDB-ReadOnly-role. This is because IAM users are .secure by default., meaning that they only have the permissions explicitly granted by their administrators. To do this, the administrator for aws@example.com performs the following steps:

  1. Signs in to the IAM console.
  2. Assigns a policy to Joe (or to a group that Joe belongs to) that grants the right to call AssumeRole on the DynamoDB-ReadOnly-role. The policy below is an example of such a policy (with 111122223333 as the account ID for research@example.com):
    { “Statement” : [
      {
        “Effect” : “Allow” ,
        “Action” : “sts:AssumeRole” ,
        “Resource” : “arn:aws:iam::111122223333:role/DynamoDB-ReadOnly-role”
      }
      ]
    }

How Does Joe use the IAM Role to Access Resources in the research@example.com?
The application that Joe uses to accesses data in the research@example.com account will make API calls to assume the IAM role and use the role’s temporary security credentials when interacting with the DynamoDB table in research@example.com. The picture below illustrates the actual flow:

This simple sample code, using the AWS Java SDK, illustrates the individual steps for assuming a role and using the roles temporary security credentials to access DynamoDB.

import java.util.HashMap ;

import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.dynamodb.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodb.model.*;
import com.amazonaws.auth.*;

public class AssumeRoleDemo {
    private static final String ROLE_ARN =
    “arn:aws:iam::111122223333:role/DynamoDB-ReadOnly-role”;
    private static final String TABLE_NAME = “TestProject”;
    private static final String KEY_VALUE = “1234567890”;

    private static AWSCredentials longTermCredentials_;
   
    private static void init() throws Exception {
    // acquire long term credentials from the properties file
    longTermCredentials_ = new PropertiesCredentials(AssumeRoleDemo.class.getResourceAsStream(“AwsCredentials.properties”));
    }
   
    public static void main(String[] args) throws Exception {
        init();

    // Step 1. Use Joe.s long-term credentials to call the
    // AWS Security Token Service (STS) AssumeRole API, specifying
    // the ARN for the role DynamoDB-RO-role in research@example.com.

        AWSSecurityTokenServiceClient stsClient = new
            AWSSecurityTokenServiceClient(longTermCredentials_);
       
        AssumeRoleRequest assumeRequest = new AssumeRoleRequest()
            .withRoleArn(ROLE_ARN)
            .withDurationSeconds(3600)
            .withRoleSessionName(“demo”);
       
        AssumeRoleResult assumeResult =
        stsClient.assumeRole(assumeRequest);

    // Step 2. AssumeRole returns temporary security credentials for
    // the IAM role.

        BasicSessionCredentials temporaryCredentials =
        new BasicSessionCredentials(
                    assumeResult.getCredentials().getAccessKeyId(),
                    assumeResult.getCredentials().getSecretAccessKey(),
                    assumeResult.getCredentials().getSessionToken());

    // Step 3. Make DynamoDB service calls to read data from a
    // DynamoDB table, stored in research@example.com, using the
    // temporary security credentials from the DynamoDB-ReadOnly-role
    // that were returned in the previous step.

        AmazonDynamoDBClient dynamoClient = new AmazonDynamoDBClient(temporaryCredentials);
       
        GetItemResult result = dynamoClient.getItem(new GetItemRequest(TABLE_NAME, new Key(new AttributeValue(KEY_VALUE))));
    }
}

For additional information about this new feature visit the Delegating API Access by Using Roles section in the Using IAM guide.

Enabling cross-account API access is another step in the evolution of IAM roles. In the future, we will evaluate integrating the ability to assume roles into the AWS Management Console as well as enabling additional AWS services to integrate with roles.

If you have specific feature requests or want to tell us about your use case please post to the IAM forum. As always, we are eager to hear about how customers use AWS IAM to control access to your AWS resources.

— Anders