AWS IAM Role Chaining in Java – DynamoDB, S3

AWS IAM Role Chaining Using Java, S3, and Dynamodb

Choosing between IAM roles or IAM users for accessing AWS resources is a matter of the risk appetite you are taking. But for the fact, AWS encourages you to use IAM roles over the users. 

IAM roles provide temporary credentials with the least privilege. However, unlike IAM users, it cannot make direct requests to an AWS resource; therefore, it is supposed to be assumed by an authorized entity such as IAM users, applications, or an EC2 service.

This tutorial aims for a walkthrough guide about using the “IAM role chaining between cross-accounts for accessing a resource such as DynamoDB or S3 Storage in Java language”.

Grant access to the IAM Roles 

For the AWS role chaining example, I will proceed with the assumptions below;

  • I have two different AWS accounts that I named Account-A and Account-B
  • The application instance is running in Account-A
  • The resources I want to access are in Account-B (DynamoDB and S3)

I imagine that I will need two different roles for such a scenario.

Cross Account Sign Role

Cross account access between Account-A and Account-B. This role provides the service instance access from Account-A to Account-B.

Role-1: 

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["sts:AssumeRole"],
    "Resource": "arn:aws:iam::<Account-ID></Account-ID>:role/CrossAccountSignRole"
  }]
}

 ** the permissions will be specified in the CrossAccountSignRole policy based on your needs!

DynamoDB Execution Role

This role will grant access to service instances for running queries over desired AWS resources such as DynamoDB or S3

Role-2:

"Statement": [
        {
            "Action": [
                "dynamodb:DeleteItem",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:BatchGetItem",
                "dynamodb:UpdateTimeToLive",
                "dynamodb:BatchWriteItem",
                "dynamodb:PutItem",
                "dynamodb:Scan",
                "dynamodb:Query",
                "dynamodb:UpdateItem",
                "dynamodb:UpdateTable",
                "dynamodb:ListTables",
                "dynamodb:List*"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:dynamodb:eu-west-1:<Account-ID>:<Table-Name>//index/*",
                "arn:aws:dynamodb:eu-west-1:<Account-ID>:table/<Table-Name>"
            ],
            "Sid": "AllowDynamoDBReadWrite"
        }
    ],
    "Version": "2012-10-17"
}

How does AWS IAM Role Chaining work?

  1. Create an Assume Role Provider for Role-A
  2. Create an Assume Role Provider for Role-B by giving Role-A credentials
  3. Use the Role-B provider as credentials for DynamoDB or S3 clients.

AWS IAM Role Chaining Example in Java

Creating STS Client in Java

private static AWSSecurityTokenServiceClientBuilder getStsClient(StsProperties props) {
 return AWSSecurityTokenServiceClientBuilder
     .standard()
     .withRegion(Regions.fromName(props.getRegion()))
     .withClientConfiguration(getProxyClientConfig(props.getProxyHost(), props.getProxyPort()));
}

Creating Proxy Client

Ideally, you will have a proxy server that brings an extra layer of security to protect you from data breaches and most hacker attacks, so the below code piece will show how to create a proxy client and attach it to the STS client later.

private static ClientConfiguration getProxyClientConfig(String proxyHost, String proxyPort) {
 ClientConfiguration clientConfiguration = new ClientConfiguration();
 clientConfiguration.setProxyHost(proxyHost);
 clientConfiguration.setProxyPort(Integer.parseInt(proxyPort));
 return clientConfiguration;
}

Chaining Roles with AWS Assume Role Credentials Provider

STSAssumeRoleSessionCredentialsProvider uses the AWS Security Token Service to assume a Role, and it creates temporary sessions for authentication. This provider will refresh credentials automatically with a background thread based on your duration specification. If you don’t want to use the auto-refresh mechanism that comes ready on your plate by AWS, you can create a custom credentials provider and override it with your setup.

public static STSAssumeRoleSessionCredentialsProvider getAWSCredentialsProviderChain(StsProperties props) {
 final String dynamoDbSessionName = "dynamodb-session-" + UUID.randomUUID();
 final String crossAccountSessionName = "cross-account-session-" + UUID.randomUUID();
 STSAssumeRoleSessionCredentialsProvider crossAccountProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(props.getRoleArn(), crossAccountSessionName)
     .withExternalId(props.getExternalId())
     .withRoleSessionDurationSeconds(SESSION_DURATION_IN_SECONDS)
     .withStsClient(getStsClient(props).build())
     .build();
 return new STSAssumeRoleSessionCredentialsProvider.Builder(props.getExecutionRoleArn(), dynamoDbSessionName)
     .withExternalId(props.getExecutionRoleExternalId())
     .withRoleSessionDurationSeconds(SESSION_DURATION_IN_SECONDS)
     .withStsClient(getStsClient(props).withCredentials(crossAccountProvider).build())
     .build();
}

How to Use AWS Credentials Provider in DynamoDB or S3?

Create DynamoDB Client with AWS Assume Role Credential Provider

public AmazonDynamoDB amazonDynamoDB() {
 return AmazonDynamoDBClientBuilder.standard()
     .withRegion(Regions.EU_WEST_1)
     .withCredentials(getAWSCredentialsProviderChain(props))
     .build();
}

Create S3 Client with AWS Assume Role Credential Provider

public AmazonS3 getS3Client(StsProperties stsProperties) {
   return AmazonS3Client.builder()
           .withCredentials(getAWSCredentialsProviderChain(props))
           .withRegion(Regions.EU_WEST_1)
           .build();
}

Conclusion

Exceptionly blog has excellent tutorials for challenging language methodologies or tools. 

Feel free to explore some of my other posts in the Java language; 

One thought on "AWS IAM Role Chaining in Java – DynamoDB, S3"

  1. Pingback: Exceptionly

Leave a Reply

Your email address will not be published.

#

“Exceptionly was such a fast and efficient process. Complete game changer for hiring remote.”

Liam Martin
Co-Founder at TimeDoctor

#

“Great service, outstanding speed, stunning quality.”

Andy Tryba
CEO at Gigster

Is Exceptionly an outsourcing business?

No. We encourage our clients to do direct hires. We provide payroll consultancy and services in a 100% transparent way if our clients are new to remote hiring.

Is Exceptionly a database of candidates?

Not really, data is only a small part of our business. While we own over 2 million publicly available software engineer data evaluated, our power lies in hands-on testing and engineer-to-engineer technical interviews.

Is Exceptionly expensive?

Exceptionly is more cost-efficient than any other serious competitor who owns a decent technical testing funnel. If you compare Exceptionly with HR agencies who only do resume screening before endorsement, yes, it is expensive.

Who is the founder of Exceptionly?

Sinan Ata is the founder of Exceptionly, who previously built two global technical talent acquisition enginess and tested over 2.5 million software engineers in his career.

Still have questions? Contact us.

Ready to meet top-notch engineers?

Let's get your talent pipelines up and running!

HIRE WITH EXCEPTIONLY

No hidden fees.