Fun times with AWS STS AssumeRole
I had an AWS STS AssumeRole
problem today when I was working with the AWS SDK; digging
in it turned out the problem was that AssumeRole
was not actually being invoked. Poking
around I was unsurprised to find that @ben11kehoe
had already clearly stated the problem and GitHub user petitout had example Go code
with the right way to do it (link).
Sometimes you need to assume another role than your default execution role in order to
accomplish a task. You can explicitly call STS AssumeRole
yourself and configure the
SDK client to use the returned credentials, or you can configure your SDK client to call
AssumeRole
itself when it needs the credentials. I like the second way because it means
that credentials aren’t something that my code has access to.
Sample code for not assuming a role correctly; you might have stumbled on this the same way I did:
// almost certainly not what you want
cfg, _ := config.LoadDefaultConfig(
ctx,
config.WithAssumeRoleCredentialOptions(func(aro *stscreds.AssumeRoleOptions) {
aro.Client = stsClient
aro.RoleARN = arn
aro.RoleSessionName = sessionName
}),
)
A person might think that the code above is right, because it has all kinds of the right
keywords that trigger pattern recognition. The comments on WithAssumeRoleCredentialOptions
read:
// WithAssumeRoleCredentialOptions is a helper function to construct functional
// options that sets a function to use stscreds.AssumeRoleOptions on config's
// LoadOptions. If assume role credentials options is set to nil, the assume
// role credentials value will be ignored. If multiple WithAssumeRoleCredentialOptions
// calls are made, the last call overrides the previous call values.
I think that what this actually does is … you know, I truly have no idea, and don’t intend to dig into what exactly this does. It definitely does not do what I thought it did.
Sample code for probably doing what you want:
// almost certainly what you do want instead
cfg, err := config.LoadDefaultConfig(
ctx,
config.WithCredentialsProvider(stscreds.NewAssumeRoleProvider(
stsClient, arn, func(aro *stscreds.AssumeRoleOptions) {
aro.RoleSessionName = sessionName
}
))
)
When the SDK needs credentials, this setup uses STS AssumeRole
to obtain credentials
with the STS client and role ARN that you provide. The stsClient
in this example can be
configured to take credentials from the environment.
Hope posting this helps make the solution findable for other folks.
re-posting and expanding on my original Mastodon post