amazon-web-servicesaws-sdk-jsaws-sts

AWS SDK v3 Assume role for a client


I'm writing a Node JS app using AWS JS SDK v3. I am correctly using STS to assume role and retrieve credentials. The assume call response is such:

{
    "$metadata": {
        "httpStatusCode": 200,
        "requestId": "xxx",
        "attempts": 1,
        "totalRetryDelay": 0
    },
    "Credentials": {
        "AccessKeyId": "xxx",
        "SecretAccessKey": "xxx",
        "SessionToken": "xxx",
        "Expiration": "2021-02-26T15:40:17.000Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "xxx",
        "Arn": "arn:aws:sts::xxx"
    }
}

I am taking the credentials and passing them to a DynamoDBClient constructor (along with region).

import { DynamoDBClient, ListTablesCommand } from '@aws-sdk/client-dynamodb';
    
public getTablesList(region: string) {
    const credentials = await getCredentialsFromSTS(region);
    const clientParams = Object.assign(credentials, region); // This just merges two JSONs into one
    const dbClient = new DynamoDBClient(clientParams);
    const command = new ListTablesCommand({});
    const response = await dbClient.send(command);
    console.log(response);
}

What I get in the response is a list of only the tables of the account, that runs my code. The tables in the account where I am assuming the role are not present. Maybe I am assuming the role wrongly? I tried to package the credentials in a "Credentials" key, but that didn't help either.

const clientParams = Object.assign({ Credentials: credentials }, region);

Any idea what I am doing wrong here? Maybe the DDBClient is not assuming it as it should, but is there a way to check the assumed role for the DBClient? I found a namespace called RoleInfo in the documentation, but I don't know how to invoke it.


Solution

  • Please read the documentation of the DynamoDBClient parameter object: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#constructor-property

    The credentials fields are lower-case whereas in the STS result they are upper-case.

    There are also more errors in your code, such as the Object.assign(credentials, region); call. region here is a string, so by assigning it into credentials you will not get a property named "region" with the value of that region variable, but you will get numeric properties, each with one character of the region string.

    The correct initialization should be:

    const credentials = await getCredentialsFromSTS(region);
    const dbClient = new DynamoDBClient({
      region: region,
      credentials: {
        accessKeyId: credentials.AccessKeyId,
        secretAccessKey: credentials.SecretAccessKey,
        sessionToken: credentials.SessionToken,
      }
    });