Skip to content

Commit

Permalink
AWS Single Sign-On (SSO) Provider Support (#1072)
Browse files Browse the repository at this point in the history
* Implement AWS SSO Credential Provider
* Add Support AWS SSO Provider in Credential Chain
* Add Go Module Replace Tool for Local SDK Usage
* Expand Credential Chain Tests
  • Loading branch information
skmcgrail authored Jan 27, 2021
1 parent bbf9460 commit e8777b6
Show file tree
Hide file tree
Showing 26 changed files with 935 additions and 51 deletions.
9 changes: 9 additions & 0 deletions .changes/next-release/config-feature-1611597600517230000.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ID": "config-feature-1611597600517230000",
"SchemaVersion": 1,
"Module": "config",
"Type": "feature",
"Description": "Add Support for AWS Single Sign-On (SSO) credential provider",
"MinVersion": "",
"AffectedModules": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ID": "credentials-feature-1611597655218336000",
"SchemaVersion": 1,
"Module": "credentials",
"Type": "feature",
"Description": "Add AWS Single Sign-On (SSO) credential provider",
"MinVersion": "",
"AffectedModules": null
}
2 changes: 1 addition & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package config

import (
"context"
"github.com/google/go-cmp/cmp"
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/google/go-cmp/cmp"
)

func TestConfigs_SharedConfigOptions(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions config/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/aws/aws-sdk-go-v2 v1.0.1-0.20210122214637-6cf9ad2f8e2f
github.com/aws/aws-sdk-go-v2/credentials v1.0.0
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.0
github.com/aws/aws-sdk-go-v2/service/sso v1.0.0
github.com/aws/aws-sdk-go-v2/service/sts v1.0.0
github.com/aws/smithy-go v1.0.0
github.com/google/go-cmp v0.5.4
Expand Down
2 changes: 2 additions & 0 deletions config/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/aws/aws-sdk-go-v2/service/sso v1.0.0 h1:eNwZL0deLt9ehrTpPAO/pvztJxa4RT6+E7sbDpgMGUQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.0.0/go.mod h1:qNdDupP6xoM//zL1JmPl2XGbyPL5kKrlsoYVh8XZxzQ=
github.com/aws/smithy-go v1.0.0 h1:hkhcRKG9rJ4Fn+RbfXY7Tz7b3ITLDyolBnLLBhwbg/c=
github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
29 changes: 29 additions & 0 deletions config/load_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
"github.com/aws/aws-sdk-go-v2/credentials/processcreds"
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/smithy-go/logging"
Expand Down Expand Up @@ -110,6 +111,10 @@ type LoadOptions struct {
// stscreds.AssumeRoleOptions
AssumeRoleCredentialOptions func(*stscreds.AssumeRoleOptions)

// SSOProviderOptions is a function for setting
// the ssocreds.Options
SSOProviderOptions func(options *ssocreds.Options)

// LogConfigurationWarnings when set to true, enables logging
// configuration warnings
LogConfigurationWarnings *bool
Expand Down Expand Up @@ -592,3 +597,27 @@ func WithS3UseARNRegion(v bool) LoadOptionsFunc {
return nil
}
}


// getSSOProviderOptions returns AssumeRoleCredentialOptions from LoadOptions
func (o LoadOptions) getSSOProviderOptions(context.Context) (func(options *ssocreds.Options), bool, error) {
if o.SSOProviderOptions == nil {
return nil, false, nil
}

return o.SSOProviderOptions, true, nil
}

// WithSSOProviderOptions is a helper function to construct
// functional options that sets a function to use ssocreds.Options
// on config's LoadOptions. If the SSO credential provider options is set to nil,
// the sso provider options value will be ignored. If multiple
// WithSSOProviderOptions calls are made, the last call overrides
// the previous call values.
func WithSSOProviderOptions(v func(*ssocreds.Options)) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.SSOProviderOptions = v
return nil
}
}

19 changes: 19 additions & 0 deletions config/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
"github.com/aws/aws-sdk-go-v2/credentials/processcreds"
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/middleware"
Expand Down Expand Up @@ -406,3 +407,21 @@ func getLogConfigurationWarnings(ctx context.Context, configs configs) (v bool,
}
return
}

// ssoCredentialOptionsProvider is an interface for retrieving a function for setting
// the ssocreds.Options.
type ssoCredentialOptionsProvider interface {
getSSOProviderOptions(context.Context) (func(*ssocreds.Options), bool, error)
}

func getSSOProviderOptions(ctx context.Context, configs configs) (v func(options *ssocreds.Options), found bool, err error) {
for _, c := range configs {
if p, ok := c.(ssoCredentialOptionsProvider); ok {
v, found, err = p.getSSOProviderOptions(ctx)
if err != nil || found {
break
}
}
}
return
}
27 changes: 25 additions & 2 deletions config/resolve_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
"github.com/aws/aws-sdk-go-v2/credentials/processcreds"
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/sso"
"github.com/aws/aws-sdk-go-v2/service/sts"
)

Expand Down Expand Up @@ -118,6 +120,9 @@ func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *En
Value: sharedConfig.Credentials,
}

case sharedConfig.hasSSOConfiguration():
err = resolveSSOCredentials(ctx, cfg, sharedConfig, configs)

case len(sharedConfig.CredentialProcess) != 0:
// Get credentials from CredentialProcess
err = processCredentials(ctx, cfg, sharedConfig, configs)
Expand Down Expand Up @@ -151,6 +156,24 @@ func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *En
return nil
}

func resolveSSOCredentials(ctx context.Context, cfg *aws.Config, sharedConfig *SharedConfig, configs configs) error {
var options []func(*ssocreds.Options)
v, found, err := getSSOProviderOptions(ctx, configs)
if err != nil {
return err
}
if found {
options = append(options, v)
}

cfgCopy := cfg.Copy()
cfgCopy.Region = sharedConfig.SSORegion

cfg.Credentials = ssocreds.New(sso.NewFromConfig(cfgCopy), sharedConfig.SSOAccountID, sharedConfig.SSORoleName, sharedConfig.SSOStartURL, options...)

return nil
}

func ecsContainerURI(path string) string {
return fmt.Sprintf("%s%s", ecsContainerEndpoint, path)
}
Expand Down Expand Up @@ -353,7 +376,7 @@ func assumeWebIdentity(ctx context.Context, cfg *aws.Config, filepath string, ro
optFns = append(optFns, optFn)
}

provider := stscreds.NewWebIdentityRoleProvider(sts.NewFromConfig(cfg.Copy()), roleARN, stscreds.IdentityTokenFile(filepath), optFns...)
provider := stscreds.NewWebIdentityRoleProvider(sts.NewFromConfig(*cfg), roleARN, stscreds.IdentityTokenFile(filepath), optFns...)

cfg.Credentials = provider

Expand Down Expand Up @@ -401,7 +424,7 @@ func credsFromAssumeRole(ctx context.Context, cfg *aws.Config, sharedCfg *Shared
}
}

cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg.Copy()), sharedCfg.RoleARN, optFns...)
cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), sharedCfg.RoleARN, optFns...)

return nil
}
Expand Down
Loading

0 comments on commit e8777b6

Please sign in to comment.