How to Assume Cross-Account Role?
Asked Answered
U

1

6

AWS' Golang SDK says that I should use stscreds.AssumeRoleProvider to assume a cross-account role (in this case, for querying another account's DynamoDb table from a web server). This code works:

var sess *session.Session

func init() {

  sess = session.Must(session.NewSession(&aws.Config{
    Region: aws.String("us-west-2"),
  }))

}

func getDynamoDbClient() *dynamodb.DynamoDB {

  crossAccountRoleArn := "arn:...:my-cross-account-role-ARN"

  creds := stscreds.NewCredentials(sess, crossAccountRoleArn, func(arp *stscreds.AssumeRoleProvider) {
    arp.RoleSessionName = "my-role-session-name"
    arp.Duration = 60 * time.Minute
    arp.ExpiryWindow = 30 * time.Second
  })

  dynamoDbClient := dynamodb.New(sess, aws.NewConfig().WithCredentials(creds))

  return dynamoDbClient
}

According to the documentation, the returned client is thread-safe:

DynamoDB methods are safe to use concurrently.

The question is, since the credential are auto-renewed via stscreds.AssumeRoleProvider, do I

  • Need to new up a new client on each request (to ensure that I've got unexpired credentials), or

  • Can I new up a DynamoDb client when the web server starts up, and reuse it for the life of the web server?

Edited To Note:

I dug into the source code for the Golang AWS SDK, and it looks like the credentials returned by stscreds.NewCredentials() are nothing more than a wrapper around a reference to the stscreds.AssumeRoleProvider. So it seems likely to me that the client will magically get auto-renewed credentials.

AWS' documentation leaves something to be desired.

Uriisa answered 30/10, 2017 at 19:22 Comment(1)
Not posting as an answer because I don't know for sure in this specific case, but my past experiences with AWS SDKs and temporary credentials show that you need to create the client at startup, and if/when it stops working, then create a new client. Every request is more often than needed, but one created at startup may not work forever.Poler
M
-1
roleArn := "arn:aws:iam::1234567890:role/my-role"
awsSession, _ := session.NewSession(&aws.Config{
    Region: aws.String("us-west-2"),
})

stsClient := sts.New(awsSession)
stsRequest := sts.AssumeRoleInput{
    RoleArn:         aws.String(roleArn),
    RoleSessionName: aws.String("my-role-test"),
    DurationSeconds: aws.Int64(900), //min allowed
}

stsResponse, err := stsClient.AssumeRole(&stsRequest)

if err != nil {
    log.Fatal("an exception occurred when attempting to assume the my role. error=" + err.Error())
}

os.Setenv("AWS_ACCESS_KEY_ID", *stsResponse.Credentials.AccessKeyId)
os.Setenv("AWS_SECRET_ACCESS_KEY", *stsResponse.Credentials.SecretAccessKey)
os.Setenv("AWS_SESSION_TOKEN", *stsResponse.Credentials.SessionToken)
os.Setenv("AWS_SECURITY_TOKEN", *stsResponse.Credentials.SessionToken)
os.Setenv("ASSUMED_ROLE", roleArn)
Moramorabito answered 14/10, 2021 at 18:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.