Search code examples
aws-sdk-go

Why does NewStaticCredentials return a blank Credentials object?


I am trying to read S3 objects in Account A from Account B.
I am able to assume a role in Account B and retrieve sts.Credentials object.

stsClient := sts.New(session.Must(session.NewSession()))
params := &sts.AssumeRoleInput{
    RoleArn:         aws.String(roleArn),
    RoleSessionName: aws.String("role-session-name"),
}
stsResp, err := stsClient.AssumeRole(params)
checkErr(err)
// stsResp.Credentials.AccessKeyId     = ASIA...
// stsResp.Credentials.SecretAccessKey = abc...
// stsResp.Credentials.SessionToken    = xyz...

I then have to convert sts.Credentials object to a credentials.Credentials object in order to use it in

s3Client := s3.New(session.Must(session.NewSession()), &aws.Config{Credentials: creds})

However, when I do:

creds := credentials.NewStaticCredentials(*stsResp.Credentials.AccessKeyId, *stsResp.Credentials.SecretAccessKey, *stsResp.Credentials.SessionToken)

creds for some reason is a pointer to an empty credentials.Credentials object:

&{creds:{AccessKeyID: SecretAccessKey: SessionToken: ProviderName:} forceRefresh:true m:{state:0 sema:0} provider:0xc4201a2840}

I have also tried:

values, err := creds.Get()
checkErr(err)
fmt.Println(values) // prints out credentials values as expected

So, it's not quite clear to me why credentials.NewStaticCredentials() returns an empty credentials object.


Solution

  • When printing out the credentials.Credentials value returned by credentials.NewStaticCredentials() the creds value you see printed is the cached AWS credentials stored in the Credentials type that has not been populated yet. This field is populated when Credentials.Get is called. The value is invalid prior to Get being called.

    The NewStaticCredentials will create a StaticProvider value which satisfies the Provider interface. The Credentials type will use the Provider.Retrieve() method to retrieve the latest credential Values from the Provider. The Credentials type will cache the creds response from Retrieve() until the Provider flags the credentials as expired. In the case of StaticProvider the credentials never expire.

    This is why creds.Get() returns the values without an error. If you were to print creds after Get was called you'd see the cached static values in the Credentials type.