New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
delay WebIdentityRoleOptions validation #2030
Conversation
When loading the default config and `AWS_WEB_IDENTITY_TOKEN_FILE` is set it triggers the assume role with web identity provider. This provider requires it's configuration either entirely in environment variables or shared config. The Go SDK offers an API to configure this provider further via code which was being ignored or causing early validation issues. This change allows `AWS_WEB_IDENTITY_TOKEN_FILE` to be set and all other options to be supplied by Go code relaxing the constraint that everything has to come from the environment. fixes #2015
config/resolve_credentials.go
Outdated
opts := stscreds.WebIdentityRoleOptions{ | ||
RoleARN: roleARN, | ||
RoleSessionName: sessionName, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The opts
value isn't passed to stscreds.NewWebIdentityRoleProvider
, so the RoleSessionName
set here is lost.
The original declaration of optFns
should be restored, i.e.
optFns := []func(*stscreds.WebIdentityRoleOptions){
func(options *stscreds.WebIdentityRoleOptions) {
options.RoleSessionName = sessionName
},
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, I've restored the way RoleSessionName
was being set.
HI @aajtodd, I've been doing some more testing. To clarify, when |
No. The The Since the API does exist though this PR attempts to make more of the options valid, in particular role ARN and explicit My 2 cents, if you know the provider explicitly you may not want to go through the default chain to get at it. Configure the credential provider explicitly if you know what it should be. This can even be your own custom defined chain. NOTE: If you configure your own credential provider you likely will want to wrap it with |
In our current setup, we have to do (among other setup), the following: func getCredentialsProvider(ctx context.Context, c *Config) (aws.CredentialsProvider, string, error) {
...
envConfig, err := config.NewEnvConfig()
...
// Set up the WebIdentityRoleCredentialOptions here, in case the envvar `AWS_WEB_IDENTITY_TOKEN_FILE` is set
// Otherwise, the AWS SDK for Go expects that there will be configured credentials and will return an error.
if web := c.AssumeRoleWithWebIdentity; web != nil {
loadOptions = append(loadOptions, config.WithWebIdentityRoleCredentialOptions(func(opts *stscreds.WebIdentityRoleOptions) {
opts.RoleARN = web.RoleARN
opts.RoleSessionName = web.SessionName
opts.Duration = web.Duration
if web.Policy != "" {
opts.Policy = aws.String(web.Policy)
}
if len(web.PolicyARNs) > 0 {
opts.PolicyARNs = getPolicyDescriptorTypes(web.PolicyARNs)
}
if web.HasValidTokenSource() {
opts.TokenRetriever = web
}
}))
}
cfg, err := config.LoadDefaultConfig(ctx, loadOptions...)
if err != nil {
return nil, "", fmt.Errorf("loading configuration: %w", err)
}
// If the envvar `AWS_WEB_IDENTITY_TOKEN_FILE` has not been set, and we want to assume a web role, we now have
// to handle it manually. Creating the STS client for assuming the role needs a populated `aws.Config`, so we have
// to do this after calling `config.LoadDefaultConfig`
if c.AssumeRoleWithWebIdentity != nil && envConfig.WebIdentityTokenFilePath == "" {
provider, err := webIdentityCredentialsProvider(ctx, cfg, c)
if err != nil {
return nil, "", err
}
cfg.Credentials = provider
}
...
}
func webIdentityCredentialsProvider(ctx context.Context, awsConfig aws.Config, c *Config) (aws.CredentialsProvider, error) {
web := c.AssumeRoleWithWebIdentity
client := stsClient(ctx, awsConfig, c)
appCreds := stscreds.NewWebIdentityRoleProvider(client, web.RoleARN, web, func(opts *stscreds.WebIdentityRoleOptions) {
opts.RoleSessionName = web.SessionName
opts.Duration = web.Duration
if web.Policy != "" {
opts.Policy = aws.String(web.Policy)
}
if len(web.PolicyARNs) > 0 {
opts.PolicyARNs = getPolicyDescriptorTypes(web.PolicyARNs)
}
})
_, err := appCreds.Retrieve(ctx)
if err != nil {
return nil, c.NewCannotAssumeRoleWithWebIdentityError(err)
}
return aws.NewCredentialsCache(appCreds), nil
}
func stsClient(ctx context.Context, awsConfig aws.Config, c *Config) *sts.Client {
return sts.NewFromConfig(awsConfig, func(opts *sts.Options) {
if c.StsRegion != "" {
opts.Region = c.StsRegion
}
if c.StsEndpoint != "" {
opts.EndpointResolver = sts.EndpointResolverFromURL(c.StsEndpoint)
}
})
} We need to resolve all of the configuration first so that we can get an |
From the code provided:
This is correct and expected.
This is a misunderstanding of both how Attempting to hook into this default behavior is understandable but also probably not optimal for your use case. It uses heuristics and a prioritized list to attempt to resolve configuration stopping at the first valid source. When you know the credential provider to choose already you'd be better off handling your own configuration with custom code as you are doing for the web identity provider in the code shared). All that being said this PR enables more of the options from |
Thanks, @aajtodd. Because of the purpose of |
When loading the default config and
AWS_WEB_IDENTITY_TOKEN_FILE
is set it triggers the assume role with web identity provider. This provider requires it's configuration either entirely in environment variables or shared config. The Go SDK offers an API to configure this provider further via code which was being ignored or causing early validation issues. This change allowsAWS_WEB_IDENTITY_TOKEN_FILE
to be set and all other options to be supplied by Go code relaxing the constraint that everything has to come from the environment.fixes #2015
For changes to files under the
/codegen/aws-models
folder, and manual edits to autogenerated code (e.g./service/s3/api.go
) please create an Issue instead of a PR for those type of changes.If there is an existing bug or feature this PR is answers please reference it here.
To help speed up the process and reduce the time to merge please ensure that
Allow edits and access to secrets by maintainers
is checked before submitting your PR. This will allow the project maintainers to make minor adjustments or improvements to the submitted PR, allow us to reduce the roundtrip time for merging your request.