How to run AWS SDK version 2 with credentials from variables?
Asked Answered
T

2

10

My question is the same as this other question: How to run AWS SDK with credentials from variables? but I am using SDK version 2 which no longer uses Session (if I understand correctly).

So, I am creating a new client, and I have the credentials as variables. I need to use the IAM service. Here is the function:

func getIAMClient(ctx context.Context) (*iam.Client, error) {
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("no-region"))
    if err != nil {
        return nil, errors.Wrap(err)
    }

    cfg.HTTPClient, err = getHTTPClient(ctx)
    if err != nil {
        return nil, err
    }

    return iam.NewFromConfig(cfg), nil
}

Different users will use the app at the same time, so I can't just use ENV files, but I haven't been able to find a documentation page explaining how to pass these credentials to my Client. Any support will be appreciated!

Taught answered 11/8, 2021 at 6:27 Comment(0)
K
8

This can be achieved with the StaticCredentialsProvider as described in section "Static Credentials" of the AWS SDK for Go V2 documentation:

cfg, err := config.LoadDefaultConfig(ctx, config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("AKID", "SECRET_KEY", "TOKEN")))
Khoury answered 11/8, 2021 at 6:42 Comment(1)
Yes, I have the information in variables, they're not hardcoded. This solved my problem. Thanks a lot!Pier
S
3

To init configs from runtime variables, it's fine to use credentials.NewStaticCredentialsProvider:

staticProvider := credentials.NewStaticCredentialsProvider(
    accessKey, 
    secretKey, 
    sessionToken,
)
cfg, err := config.LoadDefaultConfig(
    context.Background(), 
    config.WithCredentialsProvider(staticProvider),
)
if err != nil {
    return nil, err
}
client := iam.New(cfg)

However the AWS SDK documentation correctly reminds you that:

Do not embed credentials inside an application. Use this method only for testing purposes.

This is because typically code snippets that use static credentials pass hardcoded strings, which obviously is a security issue. In your case, you are attempting to pass runtime variables, so as long as those are not checked in with your application sources, you should be fine.


For the general use case, i.e. environment variables, you can use external.LoadDefaultAWSConfig, which automatically looks for, in this order:

  • Environment Variables
  • Shared Configuration and Shared Credentials files.
// import "github.com/aws/aws-sdk-go-v2/aws/external"

    cfg, err := external.LoadDefaultAWSConfig(external.WithRegion(region))
    if err != nil {
        return nil, err
    }

    client := iam.New(cfg)

The method under the hood calls external.NewEnvConfig which tries to fetch credentials from the environment variables:

  • AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
  • AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY

More details about the read priority of the env vars is given in EnvConfig documentation.

Startle answered 11/8, 2021 at 6:49 Comment(3)
Thanks, but my question was precisely how to pass credentials manually and not have the SDK fetch them from environment or configuration files.Pier
@CamiloUrán yes, TBH at first I misunderstood your question. However the term "variable" in your title may be found by people who look for "environment" variables. So I added the solution to your specific problem to my answer, and left the general part for other use casesStartle
I see! Thanks, like you said, the general case is always useful too.Pier

© 2022 - 2024 — McMap. All rights reserved.