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

idtoken: Can't use impersonated service account token

Open j0hnsmith opened this issue 3 years ago • 5 comments

Environment details

  • Programming language: Go
  • OS: all
  • Language runtime version: all
  • Package version: v0.65.0

Steps to reproduce

  1. authClient, err := idtoken.NewClient(ctx, endpoint)

Problem

Trying to use an impersonated_service_account token doesn't work because only tokens with type service_account are supported.

https://github.com/googleapis/google-api-go-client/blob/c890ff5f4b6246b4f87de68bc2f1fe8f0b3c68f9/idtoken/idtoken.go#L139-L141

Anywhere a service account can be used an impersonated service account should also be valid. I'm getting the error idtoken: credential must be service_account, found "impersonated_service_account"

j0hnsmith avatar Jan 12 '22 11:01 j0hnsmith

Are you trying to create an idtoken from an impersonated service account? If so I would recommend this method in the impersonate package: IDTokenSource.

codyoss avatar Jan 12 '22 15:01 codyoss

No, I want an "HTTP Client that automatically adds an ID token to each request via an Authorization header". I know there are other token source implementations however idtoken.NewClient() explicitly does't support option.WithTokenSource (see below).

https://github.com/googleapis/google-api-go-client/blob/c890ff5f4b6246b4f87de68bc2f1fe8f0b3c68f9/idtoken/idtoken.go#L28-L48

The exact functionality I want is provided by idtoken.NewClient()... apart from impersonated_service_account tokens not being valid.

j0hnsmith avatar Jan 12 '22 16:01 j0hnsmith

@codyoss Hi, I see you changed the label to question, I'm confused, at the least this is a feature request, no?

If you think that idtoken.NewClient(ctx, endpoint) shouldn't work with an impersonated service account can you give a reason why?

j0hnsmith avatar Jan 14 '22 13:01 j0hnsmith

I have finished to work on that feature and I discovered that thread. The impersonated service account credential type definitively must be able to generate an id_token on the service account that is impersonated.

use case: I want to invoke a Cloud Run IAM protected from my dev environment. I can't generate a service account key file (Organisation policy set, and in any case, it's a bad practice), and I don't want to change my code (to make it working exactly in the same way on GCP).

However, for that, a fix is required on my previous contribution in the golang.org/x/oauth2 library (here my pull request to set a default scope is no scope is defined).

To have an overview of a working solution, here my current commit that work with the fix. I will create a pull request as soon as the fix is merged.

guillaumeblaquiere avatar Jan 21 '22 19:01 guillaumeblaquiere

I have a similar problem but with external_account rather than impersonated_service_account.

I have a Workload Identity Federation setup and am using Keyless API authentication, basically just setting GOOGLE_APPLICATION_CREDENTIALS to the path of my JSON file without credentials. This works fine when using access tokens (FindDefaultCredentials) which you do for most SDK clients and services, however I also use IAP which obviously requires an ID token.

My first question would be if this is even intended to be supported, that is to get an ID token for an external_account?

If so, would my issue be included in the scope for this issue or should I open a new one? Or is there in fact a way for me to actually get a token source that returns ID tokens since I also need to create a client that automatically sets a valid token on each request. I looked into impersonate.IDTokenSource but did not get that to work, is it expected to work with external_account?

bombsimon avatar Jun 13 '22 15:06 bombsimon

I hit the same problem described above. Is there a solution?

senthilkumarkj avatar Dec 10 '22 00:12 senthilkumarkj

This is now supported as of https://github.com/googleapis/google-api-go-client/pull/1792

codyoss avatar Jan 06 '23 17:01 codyoss

looks like the above PR added support only for type impersonated_service_account but not type external_account used in workload identity https://google.aip.dev/auth/4117

senthilkumarkj avatar Feb 27 '23 07:02 senthilkumarkj

@senthilkumarkj That was intentional as the original issue was about impersonated_service_account. external_account should be a new different issue to be tracked.

codyoss avatar Feb 27 '23 16:02 codyoss

Thanks, Cody. Opened new issue to track it - https://github.com/googleapis/google-api-go-client/issues/1879. Without this we are unable to call Cloud Run APIs in Google Cloud from a non google platform with Workload Identity Federation.

senthilkumarkj avatar Feb 27 '23 17:02 senthilkumarkj