Skip to content

Commit

Permalink
add options for customizing credential providers
Browse files Browse the repository at this point in the history
  • Loading branch information
rittneje committed Dec 9, 2021
1 parent 0f451d5 commit 9a46073
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG_PENDING.md
Expand Up @@ -2,4 +2,6 @@

### SDK Enhancements

* `aws/session`: Add options for customizing the construction of credential providers. Currently only supported for `stscreds.WebIdentityRoleProvider`.

### SDK Bugs
31 changes: 21 additions & 10 deletions aws/session/credentials.go
Expand Up @@ -14,8 +14,17 @@ import (
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
"github.com/aws/aws-sdk-go/service/sts"
)

// CredentialsProviderOptions specifies additional options for configuring
// credentials providers.
type CredentialsProviderOptions struct {
// WebIdentityRoleProviderOptions configures a WebIdentityRoleProvider,
// such as setting its ExpiryWindow.
WebIdentityRoleProviderOptions func(*stscreds.WebIdentityRoleProvider)
}

func resolveCredentials(cfg *aws.Config,
envCfg envConfig, sharedCfg sharedConfig,
handlers request.Handlers,
Expand All @@ -40,6 +49,7 @@ func resolveCredentials(cfg *aws.Config,
envCfg.WebIdentityTokenFilePath,
envCfg.RoleARN,
envCfg.RoleSessionName,
sessOpts.CredentialsProviderOptions,
)

default:
Expand All @@ -59,6 +69,7 @@ var WebIdentityEmptyTokenFilePathErr = awserr.New(stscreds.ErrCodeWebIdentity, "
func assumeWebIdentity(cfg *aws.Config, handlers request.Handlers,
filepath string,
roleARN, sessionName string,
options *CredentialsProviderOptions,
) (*credentials.Credentials, error) {

if len(filepath) == 0 {
Expand All @@ -69,17 +80,16 @@ func assumeWebIdentity(cfg *aws.Config, handlers request.Handlers,
return nil, WebIdentityEmptyRoleARNErr
}

creds := stscreds.NewWebIdentityCredentials(
&Session{
Config: cfg,
Handlers: handlers.Copy(),
},
roleARN,
sessionName,
filepath,
)
svc := sts.New(&Session{
Config: cfg,
Handlers: handlers.Copy(),
})

return creds, nil
p := stscreds.NewWebIdentityRoleProvider(svc, roleARN, sessionName, filepath)
if options != nil && options.WebIdentityRoleProviderOptions != nil {
options.WebIdentityRoleProviderOptions(p)
}
return credentials.NewCredentials(p), nil
}

func resolveCredsFromProfile(cfg *aws.Config,
Expand Down Expand Up @@ -114,6 +124,7 @@ func resolveCredsFromProfile(cfg *aws.Config,
sharedCfg.WebIdentityTokenFile,
sharedCfg.RoleARN,
sharedCfg.RoleSessionName,
sessOpts.CredentialsProviderOptions,
)

case sharedCfg.hasSSOConfiguration():
Expand Down
51 changes: 51 additions & 0 deletions aws/session/credentials_test.go
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
Expand Down Expand Up @@ -814,6 +815,56 @@ func TestSessionAssumeRole_WithMFA_ExtendedDuration(t *testing.T) {
}
}

func TestSessionAssumeRoleWithWebIdentity_Options(t *testing.T) {
restoreEnvFn := initSessionTestEnv()
defer restoreEnvFn()

os.Setenv("AWS_REGION", "us-east-1")
os.Setenv("AWS_ROLE_ARN", "web_identity_role_arn")
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", "./testdata/wit.txt")

endpointResolver, teardown := setupCredentialsEndpoints(t)
defer teardown()

optionsCalled := false

sess, err := NewSessionWithOptions(Options{
Config: aws.Config{
EndpointResolver: endpointResolver,
},
CredentialsProviderOptions: &CredentialsProviderOptions{
WebIdentityRoleProviderOptions: func(*stscreds.WebIdentityRoleProvider) {
optionsCalled = true
},
},
})
if err != nil {
t.Fatalf("expect no error, got %v", err)
}

if !optionsCalled {
t.Errorf("expect options func to be called")
}

creds, err := sess.Config.Credentials.Get()
if err != nil {
t.Fatalf("expect no error, got %v", err)
}

if e, a := "WEB_IDENTITY_AKID", creds.AccessKeyID; e != a {
t.Errorf("expect %v, got %v", e, a)
}
if e, a := "WEB_IDENTITY_SECRET", creds.SecretAccessKey; e != a {
t.Errorf("expect %v, got %v", e, a)
}
if e, a := "WEB_IDENTITY_SESSION_TOKEN", creds.SessionToken; e != a {
t.Errorf("expect %v, got %v", e, a)
}
if e, a := stscreds.WebIdentityProviderName, creds.ProviderName; e != a {
t.Errorf("expect %v,got %v", e, a)
}
}

func ssoTestSetup() (func(), error) {
dir, err := ioutil.TempDir("", "sso-test")
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions aws/session/session.go
Expand Up @@ -304,6 +304,11 @@ type Options struct {
//
// AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE=IPv6
EC2IMDSEndpointMode endpoints.EC2IMDSEndpointModeState

// Specifies options for creating credential providers.
// These are only used if the aws.Config does not already
// include credentials.
CredentialsProviderOptions *CredentialsProviderOptions
}

// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
Expand Down

0 comments on commit 9a46073

Please sign in to comment.