google-api-go-client icon indicating copy to clipboard operation
google-api-go-client copied to clipboard

IAM: support STS token source

Open aylei opened this issue 3 years ago • 7 comments

When using workload identity federation, one follows the steps described in Accessing resources from an OIDC identity provider:

  1. Get a token from the OIDC provider
  2. Exchange the token for a federated access token through the STS API
  3. Impersonate a service account via the federated access token

It would be valuable if the SDK can provide an implementation of TokenSource to simplify the step 2. Generally, the newly introduced stsTokenSource will take a TokenSource of the token from an external OIDC provider, and exchange/refresh federated access tokens from STS.

aylei avatar Nov 13 '20 06:11 aylei

Thanks for the feature request. We have some work in progress to improve the auth experience, but don't have an ETA on this specific idea.

tbpg avatar Nov 17 '20 15:11 tbpg

This should now be supported by the underlying oauth2 package: https://pkg.go.dev/golang.org/x/oauth2/google#hdr-Workload_Identity_Federation

codyoss avatar Aug 09 '21 15:08 codyoss

golang.org/x/oauth2/google supports external_account typed JSON credentials(https://github.com/golang/oauth2/pull/462) but underlying golang.org/x/oauth2/google/internal/externalaccount is not exported. I think this PR should be re-opened for more general oauth2.TokenSource like STSTokenSource.

apstndb avatar Aug 10 '21 10:08 apstndb

That package should not need to be exported. Methods like CredentialsFromJSON will now do the right thing if the type is an "external_account".

codyoss avatar Aug 10 '21 15:08 codyoss

external_account type credentials which is supported by CredentialsFromJSON is not flexible because it processes STS subject token only from file path or URL. https://github.com/golang/oauth2/blob/faf39c7919d5800bdcad2fbcb2a330c3fdd0ef96/google/google.go#L100-L126 https://github.com/golang/oauth2/blob/faf39c7919d5800bdcad2fbcb2a330c3fdd0ef96/google/internal/externalaccount/basecredentials.go#L87-L101

  1. Get a token from the OIDC provider
  2. Exchange the token for a federated access token through the STS API
  3. Impersonate a service account via the federated access token

It would be valuable if the SDK can provide an implementation of TokenSource to simplify the step 2.

I don't know this repo(google-api-go-client) is the right place of the token source but I think the original feature request means to exchange OIDC token from a string variable or another token source.

apstndb avatar Aug 11 '21 07:08 apstndb

CredentialsFromJSON is not flexible because it processes STS subject token only from file path or URL.

Could you provide some psudocode for how you would envision working with with such an api. I am not quite understanding how the current implementation does not provide enough flexibility for what you are trying to accomplish.

codyoss avatar Aug 11 '21 14:08 codyoss

I have written PoC code. golang.org/x/oauth2/google package doesn't support that use-case. https://github.com/apstndb/image-pull-secret-controller/blob/ae414e44a30ebdef331d59a5dc32d9a27af84feb/controllers/imagepullsecret_controller.go#L95-L115 I have used Kubernetes TokenRequest API(it can be replaced by Service Account Token Volume Projection sometimes) but I think there are more situations which receive OIDC token dynamically.

apstndb avatar Aug 13 '21 11:08 apstndb