Skip to content

[extension/oauth2clientauthextension] Add support for Oauth2 STS mode #40850

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

jinghan-ma
Copy link

Description

Adds an new mode of operation for Oauth2 STS exchange. The existing 2-legged flow remains in tact.

A few new configuration options were added (e.g. SubjectToken), but no breaking changes were made to existing config options.

The extension automatically chooses which mode to use based on whether a ClientSecret is passed in for the 2-legged flow or if a SubjectToken was provided for the STS flow.

Link to tracking issue

Fixes #38086

Testing

Did an automated integration test against Google's sts server.
Added unit tests for the STS authenticator.

Documentation

Added descriptions for the newly introduced configs for STS.

@jinghan-ma jinghan-ma requested a review from a team as a code owner June 20, 2025 22:12
@jinghan-ma jinghan-ma requested a review from mwear June 20, 2025 22:12
Copy link

linux-foundation-easycla bot commented Jun 20, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@github-actions github-actions bot requested a review from pavankrish123 June 23, 2025 22:28
@jinghan-ma jinghan-ma requested a review from axw July 3, 2025 18:48
Copy link
Contributor

@axw axw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a code owner, but since you asked, here's my review :)

Probably needs to happen in another change, but IMO the Config struct should have a confighttp.ClientConfig embedded, which would replace the need for the TLS and Timeout config, which are embedded in confighttp.ClientConfig. That would also enable instrumentation of the token requests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in filename: twoleggedclienthauth.go

Comment on lines +241 to +242
shouldError bool
expectedError string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
shouldError bool
expectedError string
expectedType any

Comment on lines +273 to +285
if test.shouldError {
assert.ErrorContains(t, err, test.expectedError)
return
}

assert.NoError(t, err)
if test.settings.SubjectToken != "" {
_, ok := rc.(*stsClientAuthenticator)
assert.True(t, ok)
} else {
_, ok := rc.(*twoLeggedClientAuthenticator)
assert.True(t, ok)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if test.shouldError {
assert.ErrorContains(t, err, test.expectedError)
return
}
assert.NoError(t, err)
if test.settings.SubjectToken != "" {
_, ok := rc.(*stsClientAuthenticator)
assert.True(t, ok)
} else {
_, ok := rc.(*twoLeggedClientAuthenticator)
assert.True(t, ok)
}
requiore.NoError(t, err)
assert.IsType(t, test.expectedType, rc)

@@ -316,3 +231,59 @@ func TestFailContactingOAuth(t *testing.T) {
assert.ErrorIs(t, err, errFailedToGetSecurityToken)
assert.ErrorContains(t, err, serverURL.String())
}

func TestClientAuthenticatorMode(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should all or most the other tests in this file be moved to twoleggedclientauth_test.go?

Comment on lines +64 to +77
func (o *stsClientAuthenticator) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
tok, err := o.tokenSource.Token()
if err != nil {
return nil, err
}
return map[string]string{
"authorization": fmt.Sprintf("Bearer %s", tok.AccessToken),
}, nil
}

// Applied when authenticator is returned as PerRPCCredentials
func (o *stsClientAuthenticator) RequireTransportSecurity() bool {
return !o.config.DisableTLSOnUse
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func (o *stsClientAuthenticator) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
tok, err := o.tokenSource.Token()
if err != nil {
return nil, err
}
return map[string]string{
"authorization": fmt.Sprintf("Bearer %s", tok.AccessToken),
}, nil
}
// Applied when authenticator is returned as PerRPCCredentials
func (o *stsClientAuthenticator) RequireTransportSecurity() bool {
return !o.config.DisableTLSOnUse
}

AFAICS they're not needed? These methods are for implementing credentials.PerRPCCredentials, but we're using grpcOAuth.TokenSource for that.

Comment on lines +31 to +37
mockKsaTokenFile, err := os.CreateTemp("", "test_ksa_token_path")
assert.NoError(t, err)
defer os.Remove(mockKsaTokenFile.Name())
_, err = mockKsaTokenFile.WriteString("test-ksa-token")
assert.NoError(t, err)
err = mockKsaTokenFile.Close()
assert.NoError(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mockKsaTokenFile, err := os.CreateTemp("", "test_ksa_token_path")
assert.NoError(t, err)
defer os.Remove(mockKsaTokenFile.Name())
_, err = mockKsaTokenFile.WriteString("test-ksa-token")
assert.NoError(t, err)
err = mockKsaTokenFile.Close()
assert.NoError(t, err)
mockKsaTokenFile := filepath.Join(t.TempDir(), "test_ksa_token_path")
err := os.WriteFile(mockKsaTokenFile, "test-ksa-token", 0644)
assert.NoError(t, err)

If you use T.TempDir(), it will be removed when the test completes.

@atoulme atoulme marked this pull request as draft July 16, 2025 21:59
@atoulme
Copy link
Contributor

atoulme commented Jul 16, 2025

Please address feedback and mark ready to review again

Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Jul 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Oauth 2.0 Token Exchange In oauth2clientauth
3 participants