Skip to content

Commit 1ccd064

Browse files
authored
Merge pull request #354 from hashicorp/b-assume-web-identity
Updates for assume role with web identity
2 parents 4fa7744 + fcf3cf0 commit 1ccd064

File tree

4 files changed

+108
-32
lines changed

4 files changed

+108
-32
lines changed

aws_config_test.go

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,16 +2504,16 @@ aws_secret_access_key = SharedConfigurationSourceSecretKey
25042504

25052505
func TestAssumeRoleWithWebIdentity(t *testing.T) {
25062506
testCases := map[string]struct {
2507-
Config *Config
2508-
SetConfig bool
2509-
ExpandEnvVars bool
2510-
EnvironmentVariables map[string]string
2511-
SetEnvironmentVariable bool
2512-
SharedConfigurationFile string
2513-
SetSharedConfigurationFile bool
2514-
ExpectedCredentialsValue aws.Credentials
2515-
ExpectedError func(err error) bool
2516-
MockStsEndpoints []*servicemocks.MockEndpoint
2507+
Config *Config
2508+
SetConfig bool
2509+
ExpandEnvVars bool
2510+
EnvironmentVariables map[string]string
2511+
SetTokenFileEnvironmentVariable bool
2512+
SharedConfigurationFile string
2513+
SetSharedConfigurationFile bool
2514+
ExpectedCredentialsValue aws.Credentials
2515+
ExpectedError func(err error) bool
2516+
MockStsEndpoints []*servicemocks.MockEndpoint
25172517
}{
25182518
"config with inline token": {
25192519
Config: &Config{
@@ -2564,8 +2564,8 @@ func TestAssumeRoleWithWebIdentity(t *testing.T) {
25642564
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityArn,
25652565
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
25662566
},
2567-
SetEnvironmentVariable: true,
2568-
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
2567+
SetTokenFileEnvironmentVariable: true,
2568+
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
25692569
MockStsEndpoints: []*servicemocks.MockEndpoint{
25702570
servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
25712571
},
@@ -2594,8 +2594,8 @@ role_session_name = %[2]s
25942594
},
25952595
},
25962596
EnvironmentVariables: map[string]string{
2597-
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2598-
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2597+
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn,
2598+
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName,
25992599
"AWS_WEB_IDENTITY_TOKEN_FILE": "no-such-file",
26002600
},
26012601
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
@@ -2604,19 +2604,53 @@ role_session_name = %[2]s
26042604
},
26052605
},
26062606

2607+
// "config with file envvar": {
2608+
// Config: &Config{
2609+
// AssumeRoleWithWebIdentity: &AssumeRoleWithWebIdentity{
2610+
// RoleARN: servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2611+
// SessionName: servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2612+
// },
2613+
// },
2614+
// SetTokenFileEnvironmentVariable: true,
2615+
// ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
2616+
// MockStsEndpoints: []*servicemocks.MockEndpoint{
2617+
// servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
2618+
// },
2619+
// },
2620+
26072621
"envvar overrides shared configuration": {
26082622
Config: &Config{},
26092623
EnvironmentVariables: map[string]string{
26102624
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityArn,
26112625
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
26122626
},
2613-
SetEnvironmentVariable: true,
2627+
SetTokenFileEnvironmentVariable: true,
26142628
SharedConfigurationFile: fmt.Sprintf(`
26152629
[default]
26162630
role_arn = %[1]s
26172631
role_session_name = %[2]s
26182632
web_identity_token_file = no-such-file
2619-
`, servicemocks.MockStsAssumeRoleWithWebIdentityArn, servicemocks.MockStsAssumeRoleWithWebIdentitySessionName),
2633+
`, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName),
2634+
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
2635+
MockStsEndpoints: []*servicemocks.MockEndpoint{
2636+
servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
2637+
},
2638+
},
2639+
2640+
"config overrides shared configuration": {
2641+
Config: &Config{
2642+
AssumeRoleWithWebIdentity: &AssumeRoleWithWebIdentity{
2643+
RoleARN: servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2644+
SessionName: servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2645+
WebIdentityToken: servicemocks.MockWebIdentityToken,
2646+
},
2647+
},
2648+
SharedConfigurationFile: fmt.Sprintf(`
2649+
[default]
2650+
role_arn = %[1]s
2651+
role_session_name = %[2]s
2652+
web_identity_token_file = no-such-file
2653+
`, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName),
26202654
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
26212655
MockStsEndpoints: []*servicemocks.MockEndpoint{
26222656
servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
@@ -2728,7 +2762,7 @@ web_identity_token_file = no-such-file
27282762
testCase.Config.AssumeRoleWithWebIdentity.WebIdentityTokenFile = tokenFileName
27292763
}
27302764

2731-
if testCase.SetEnvironmentVariable {
2765+
if testCase.SetTokenFileEnvironmentVariable {
27322766
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", tokenFileName)
27332767
}
27342768

internal/config/config.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,6 @@ type AssumeRole struct {
6161
TransitiveTagKeys []string
6262
}
6363

64-
type AssumeRoleWithWebIdentity struct {
65-
RoleARN string
66-
Duration time.Duration
67-
Policy string
68-
PolicyARNs []string
69-
SessionName string
70-
WebIdentityToken string
71-
WebIdentityTokenFile string
72-
}
73-
7464
func (c Config) CustomCABundleReader() (*bytes.Reader, error) {
7565
if c.CustomCABundle == "" {
7666
return nil, nil
@@ -137,19 +127,34 @@ func (c Config) ResolveSharedCredentialsFiles() ([]string, error) {
137127
return v, nil
138128
}
139129

140-
func (c AssumeRoleWithWebIdentity) ResolveWebIdentityTokenFile() (string, error) {
130+
type AssumeRoleWithWebIdentity struct {
131+
RoleARN string
132+
Duration time.Duration
133+
Policy string
134+
PolicyARNs []string
135+
SessionName string
136+
WebIdentityToken string
137+
WebIdentityTokenFile string
138+
}
139+
140+
func (c AssumeRoleWithWebIdentity) resolveWebIdentityTokenFile() (string, error) {
141141
v, err := expand.FilePath(c.WebIdentityTokenFile)
142142
if err != nil {
143143
return "", fmt.Errorf("expanding web identity token file: %w", err)
144144
}
145145
return v, nil
146146
}
147147

148+
func (c AssumeRoleWithWebIdentity) HasValidTokenSource() bool {
149+
return c.WebIdentityToken != "" || c.WebIdentityTokenFile != ""
150+
}
151+
152+
// Implements `stscreds.IdentityTokenRetriever`
148153
func (c AssumeRoleWithWebIdentity) GetIdentityToken() ([]byte, error) {
149154
if c.WebIdentityToken != "" {
150155
return []byte(c.WebIdentityToken), nil
151156
}
152-
webIdentityTokenFile, err := c.ResolveWebIdentityTokenFile()
157+
webIdentityTokenFile, err := c.resolveWebIdentityTokenFile()
153158
if err != nil {
154159
return nil, err
155160
}

servicemocks/mock.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ const (
102102
</ResponseMetadata>
103103
</AssumeRoleWithWebIdentityResponse>`
104104

105+
MockStsAssumeRoleWithWebIdentityAlternateArn = `arn:aws:iam::666666666666:role/Alternate`
106+
MockStsAssumeRoleWithWebIdentityAlternateSessionName = `AssumeRoleWithWebIdentityAlternateSessionName`
107+
105108
MockStsGetCallerIdentityAccountID = `222222222222`
106109
MockStsGetCallerIdentityInvalidResponseBodyAccessDenied = `<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
107110
<Error>

v2/awsv1shim/session_test.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,8 +2017,8 @@ role_session_name = %[2]s
20172017
},
20182018
},
20192019
EnvironmentVariables: map[string]string{
2020-
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2021-
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2020+
"AWS_ROLE_ARN": servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn,
2021+
"AWS_ROLE_SESSION_NAME": servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName,
20222022
"AWS_WEB_IDENTITY_TOKEN_FILE": "no-such-file",
20232023
},
20242024
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
@@ -2027,6 +2027,20 @@ role_session_name = %[2]s
20272027
},
20282028
},
20292029

2030+
// "config with file envvar": {
2031+
// Config: &awsbase.Config{
2032+
// AssumeRoleWithWebIdentity: &awsbase.AssumeRoleWithWebIdentity{
2033+
// RoleARN: servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2034+
// SessionName: servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2035+
// },
2036+
// },
2037+
// SetEnvironmentVariable: true,
2038+
// ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
2039+
// MockStsEndpoints: []*servicemocks.MockEndpoint{
2040+
// servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
2041+
// },
2042+
// },
2043+
20302044
"envvar overrides shared configuration": {
20312045
Config: &awsbase.Config{},
20322046
EnvironmentVariables: map[string]string{
@@ -2039,7 +2053,27 @@ role_session_name = %[2]s
20392053
role_arn = %[1]s
20402054
role_session_name = %[2]s
20412055
web_identity_token_file = no-such-file
2042-
`, servicemocks.MockStsAssumeRoleWithWebIdentityArn, servicemocks.MockStsAssumeRoleWithWebIdentitySessionName),
2056+
`, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName),
2057+
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
2058+
MockStsEndpoints: []*servicemocks.MockEndpoint{
2059+
servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,
2060+
},
2061+
},
2062+
2063+
"config overrides shared configuration": {
2064+
Config: &awsbase.Config{
2065+
AssumeRoleWithWebIdentity: &awsbase.AssumeRoleWithWebIdentity{
2066+
RoleARN: servicemocks.MockStsAssumeRoleWithWebIdentityArn,
2067+
SessionName: servicemocks.MockStsAssumeRoleWithWebIdentitySessionName,
2068+
WebIdentityToken: servicemocks.MockWebIdentityToken,
2069+
},
2070+
},
2071+
SharedConfigurationFile: fmt.Sprintf(`
2072+
[default]
2073+
role_arn = %[1]s
2074+
role_session_name = %[2]s
2075+
web_identity_token_file = no-such-file
2076+
`, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateArn, servicemocks.MockStsAssumeRoleWithWebIdentityAlternateSessionName),
20432077
ExpectedCredentialsValue: mockdata.MockStsAssumeRoleWithWebIdentityCredentials,
20442078
MockStsEndpoints: []*servicemocks.MockEndpoint{
20452079
servicemocks.MockStsAssumeRoleWithWebIdentityValidEndpoint,

0 commit comments

Comments
 (0)