Skip to content

Commit

Permalink
aws/session: Enable SSO provider to be mixed with other credential pr…
Browse files Browse the repository at this point in the history
…ovider declarations.
  • Loading branch information
skmcgrail committed May 12, 2021
1 parent bba6aba commit fb7391e
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 17 deletions.
20 changes: 10 additions & 10 deletions aws/session/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ func resolveCredsFromProfile(cfg *aws.Config,
sharedCfg.Creds,
)

case len(sharedCfg.WebIdentityTokenFile) != 0:
// Credentials from Assume Web Identity token require an IAM Role, and
// that roll will be assumed. May be wrapped with another assume role
// via SourceProfile.
return assumeWebIdentity(cfg, handlers,
sharedCfg.WebIdentityTokenFile,
sharedCfg.RoleARN,
sharedCfg.RoleSessionName,
)

case sharedCfg.hasSSOConfiguration():
creds, err = resolveSSOCredentials(cfg, sharedCfg, handlers)

Expand All @@ -113,16 +123,6 @@ func resolveCredsFromProfile(cfg *aws.Config,
sharedCfg, handlers, sessOpts,
)

case len(sharedCfg.WebIdentityTokenFile) != 0:
// Credentials from Assume Web Identity token require an IAM Role, and
// that roll will be assumed. May be wrapped with another assume role
// via SourceProfile.
return assumeWebIdentity(cfg, handlers,
sharedCfg.WebIdentityTokenFile,
sharedCfg.RoleARN,
sharedCfg.RoleSessionName,
)

default:
// Fallback to default credentials provider, include mock errors for
// the credential chain so user can identify why credentials failed to
Expand Down
67 changes: 63 additions & 4 deletions aws/session/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,31 @@ func setupCredentialsEndpoints(t *testing.T) (endpoints.Resolver, func()) {

stsServer := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(
assumeRoleRespMsg,
time.Now().
Add(15*time.Minute).
if err := r.ParseForm(); err != nil {
w.WriteHeader(500)
return
}

form := r.Form

switch form.Get("Action") {
case "AssumeRole":
w.Write([]byte(fmt.Sprintf(
assumeRoleRespMsg,
time.Now().
Add(15*time.Minute).
Format("2006-01-02T15:04:05Z"))))
return
case "AssumeRoleWithWebIdentity":
w.Write([]byte(fmt.Sprintf(assumeRoleWithWebIdentityResponse,
time.Now().
Add(15*time.Minute).
Format("2006-01-02T15:04:05Z"))))
return
default:
w.WriteHeader(404)
return
}
}))

ssoServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -275,6 +295,23 @@ func TestSharedConfigCredentialSource(t *testing.T) {
return func() {}, nil
},
},
{
name: "sso mixed with credential process provider",
profile: "sso_mixed_credproc",
expectedAccessKey: "SSO_AKID",
expectedSecretKey: "SSO_SECRET_KEY",
expectedSessionToken: "SSO_SESSION_TOKEN",
init: func() (func(), error) {
return ssoTestSetup()
},
},
{
name: "sso mixed with web identity token provider",
profile: "sso_mixed_webident",
expectedAccessKey: "WEB_IDENTITY_AKID",
expectedSecretKey: "WEB_IDENTITY_SECRET",
expectedSessionToken: "WEB_IDENTITY_SESSION_TOKEN",
},
}

for i, c := range cases {
Expand Down Expand Up @@ -403,6 +440,28 @@ const assumeRoleRespMsg = `
</AssumeRoleResponse>
`

var assumeRoleWithWebIdentityResponse = `<AssumeRoleWithWebIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<AssumeRoleWithWebIdentityResult>
<SubjectFromWebIdentityToken>amzn1.account.AF6RHO7KZU5XRVQJGXK6HB56KR2A</SubjectFromWebIdentityToken>
<Audience>[email protected]</Audience>
<AssumedRoleUser>
<Arn>arn:aws:sts::123456789012:assumed-role/FederatedWebIdentityRole/app1</Arn>
<AssumedRoleId>AROACLKWSDQRAOEXAMPLE:app1</AssumedRoleId>
</AssumedRoleUser>
<Credentials>
<AccessKeyId>WEB_IDENTITY_AKID</AccessKeyId>
<SecretAccessKey>WEB_IDENTITY_SECRET</SecretAccessKey>
<SessionToken>WEB_IDENTITY_SESSION_TOKEN</SessionToken>
<Expiration>%s</Expiration>
</Credentials>
<Provider>www.amazon.com</Provider>
</AssumeRoleWithWebIdentityResult>
<ResponseMetadata>
<RequestId>request-id</RequestId>
</ResponseMetadata>
</AssumeRoleWithWebIdentityResponse>
`

const getRoleCredentialsResponse = `{
"roleCredentials": {
"accessKeyId": "SSO_AKID",
Expand Down
5 changes: 4 additions & 1 deletion aws/session/shared_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ func (cfg *sharedConfig) validateCredentialType() error {
len(cfg.CredentialSource) != 0,
len(cfg.CredentialProcess) != 0,
len(cfg.WebIdentityTokenFile) != 0,
cfg.hasSSOConfiguration(),
) {
return ErrSharedConfigSourceCollision
}
Expand Down Expand Up @@ -459,6 +458,10 @@ func (cfg *sharedConfig) clearCredentialOptions() {
cfg.CredentialProcess = ""
cfg.WebIdentityTokenFile = ""
cfg.Creds = credentials.Value{}
cfg.SSOAccountID = ""
cfg.SSORegion = ""
cfg.SSORoleName = ""
cfg.SSOStartURL = ""
}

func (cfg *sharedConfig) clearAssumeRoleOptions() {
Expand Down
33 changes: 32 additions & 1 deletion aws/session/shared_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,38 @@ func TestLoadSharedConfig(t *testing.T) {
{
Filenames: []string{testConfigFilename},
Profile: "source_sso_and_assume",
Err: fmt.Errorf("only one credential type may be specified per profile"),
Expected: sharedConfig{
Profile: "source_sso_and_assume",
RoleARN: "source_sso_and_assume_arn",
SourceProfileName: "sso_and_assume",
SourceProfile: &sharedConfig{
Profile: "sso_and_assume",
RoleARN: "sso_with_assume_role_arn",
SourceProfileName: "multiple_assume_role_with_credential_source",
SourceProfile: &sharedConfig{
Profile: "multiple_assume_role_with_credential_source",
RoleARN: "multiple_assume_role_with_credential_source_role_arn",
SourceProfileName: "assume_role_with_credential_source",
SourceProfile: &sharedConfig{
Profile: "assume_role_with_credential_source",
RoleARN: "assume_role_with_credential_source_role_arn",
CredentialSource: credSourceEc2Metadata,
},
},
},
},
},
{
Filenames: []string{testConfigFilename},
Profile: "sso_mixed_credproc",
Expected: sharedConfig{
Profile: "sso_mixed_credproc",
SSOAccountID: "012345678901",
SSORegion: "us-west-2",
SSORoleName: "TestRole",
SSOStartURL: "https://127.0.0.1/start",
CredentialProcess: "/path/to/process",
},
},
}

Expand Down
14 changes: 14 additions & 0 deletions aws/session/testdata/credential_source_config
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,17 @@ sso_start_url = https://THIS_SHOULD_NOT_BE_IN_TESTDATA_CACHE/start
sso_account_id = 012345678901
sso_role_name = TestRole

[profile sso_mixed_credproc]
sso_account_id = 012345678901
sso_region = us-west-2
sso_role_name = TestRole
sso_start_url = https://127.0.0.1/start
credential_process = cat ./testdata/test_json.json

[profile sso_mixed_webident]
web_identity_token_file = ./testdata/wit.txt
role_arn = sso_mixed_webident_arn
sso_account_id = 012345678901
sso_region = us-west-2
sso_role_name = TestRole
sso_start_url = https://127.0.0.1/start
17 changes: 16 additions & 1 deletion aws/session/testdata/credential_source_config_for_windows
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,19 @@ credential_process = type .\testdata\test_json.json

[chained_cred_proc]
role_arn = assume_role_w_creds_proc_source_prof
source_profile = cred_proc_no_arn_set
source_profile = cred_proc_no_arn_set

[profile sso_mixed_credproc]
sso_account_id = 012345678901
sso_region = us-west-2
sso_role_name = TestRole
sso_start_url = https://127.0.0.1/start
credential_process = type .\testdata\test_json.json

[profile sso_mixed_webident]
web_identity_token_file = .\testdata\wit.txt
role_arn = sso_mixed_webident_arn
sso_account_id = 012345678901
sso_region = us-west-2
sso_role_name = TestRole
sso_start_url = https://127.0.0.1/start
7 changes: 7 additions & 0 deletions aws/session/testdata/shared_config
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,10 @@ source_profile = multiple_assume_role_with_credential_source
[profile source_sso_and_assume]
role_arn = source_sso_and_assume_arn
source_profile = sso_and_assume

[profile sso_mixed_credproc]
sso_account_id = 012345678901
sso_region = us-west-2
sso_role_name = TestRole
sso_start_url = https://127.0.0.1/start
credential_process = /path/to/process
1 change: 1 addition & 0 deletions aws/session/testdata/wit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YXdzIHNkayBmb3IgZ28gd2ViIGlkZW50aXR5IHRva2Vu

0 comments on commit fb7391e

Please sign in to comment.