kwojcicki / amazon-dax-client-v3

AWS JS SDK v3 compatible dax client
Apache License 2.0
5 stars 2 forks source link

Add support for passing credentials #8

Open AlessioVallero opened 1 month ago

AlessioVallero commented 1 month ago

Hi! Thanks for your work on making this library happening!

My application authenticates using temporary credentials from the credentials provider, which I use to pass to DynamoDB with no issue.

However, it seems that "credentials" or "providerCredentials" is actually not a config item accepted by the TypeScript definition of your library.

Is that something that you already support and just need to expose to the types?

kwojcicki commented 1 month ago

Hey @AlessioVallero the DAX library itself reuses the credentials from the passed in DDB client. So I would hope:

 const documentDaxClient = new AmazonDaxClient({
        client: DynamoDBDocumentClient.from(new DynamoDBClient({
            endpoint: process.env.dax,
            region: 'us-east-2',
            credentials:  yourTempCreds
        }))
    });

Just works.

With that being said I've not experimented with temporary credentials so if that does not work can you provide a small repro and I can then add support.

AlessioVallero commented 1 month ago

Sure. What I believe is happening, when using temporary credentials, is that DynamoDBClient WILL take care of refreshing the credentials. However, the refreshed credentials generated later are not passed along to the AmazonDaxClient like you are doing at the beginning, when the class instance is being created. So you will need to find a way to pass it back to the DaxClient when credentials are refreshed.

Hard to tell, but maybe the issue would be solved by decommenting this line? Though, in my case, I would need it event when client is a DynamoDBDocumentClient.

Here's a piece of the code I'm running:

import { DynamoDBClient, DynamoDBClientConfig } from '@aws-sdk/client-dynamodb'
import { fromTemporaryCredentials } from '@aws-sdk/credential-providers'
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'
import AmazonDaxClient from 'amazon-dax-client-sdkv3'

export const createDynamodbClient = (logger: Logger) => {
  const options: DynamoDBClientConfig = {
    region: config.resources.dynamodb.region || undefined,
    endpoint: config.resources.dynamodb.endpoint || undefined,
  }

  const credentials = fromTemporaryCredentials({
    params: {
      RoleArn: 'MY_ROLE_ARN',
      RoleSessionName: 'MY_ROLE_SESSION_NAME',
    },
    clientConfig: {
      region: config.resources.dynamodb.region,
    },
  })
  options.credentials = credentials

  const client = new DynamoDBClient(options)

  const marshallOptions = {
    // Whether to automatically convert empty strings, blobs, and sets to `null`.
    convertEmptyValues: false, // false, by default.
    // Whether to remove undefined values while marshalling.
    removeUndefinedValues: false, // false, by default.
    // Whether to convert typeof object to map attribute.
    convertClassInstanceToMap: false, // false, by default.
  }
  const unmarshallOptions = {
    // Whether to return numbers as a string instead of converting them to native JavaScript numbers.
    wrapNumbers: false, // false, by default.
  }
  const translateConfig = { marshallOptions, unmarshallOptions }

  const documentClient = new AmazonDaxClient({
    client: DynamoDBDocumentClient.from(client, translateConfig),
  })

  return {
    client,
    documentClient,
    disconnect: () => {
      client.destroy()
    },
  }
}