-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
idtoken: support authorized_user credential type #873
Comments
I managed to work around this, as follows: import (
"context"
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/idtoken"
)
func IDTokenTokenSource(ctx context.Context, audience string) (oauth2.TokenSource, error) {
// First we try the idtoken package, which only works for service accounts
ts, err := idtoken.NewTokenSource(ctx, audience)
if err != nil {
if err.Error() != `idtoken: credential must be service_account, found "authorized_user"` {
return nil, err
}
// If that fails, we use our Application Default Credentials to fetch an id_token on the fly
gts, err := google.DefaultTokenSource(ctx)
if err != nil {
return nil, err
}
ts = oauth2.ReuseTokenSource(nil, &idTokenSource{TokenSource: gts})
}
return ts, nil
}
// idTokenSource is an oauth2.TokenSource that wraps another
// It takes the id_token from TokenSource and passes that on as a bearer token
type idTokenSource struct {
TokenSource oauth2.TokenSource
}
func (s *idTokenSource) Token() (*oauth2.Token, error) {
token, err := s.TokenSource.Token()
if err != nil {
return nil, err
}
idToken, ok := token.Extra("id_token").(string)
if !ok {
return nil, fmt.Errorf("token did not contain an id_token")
}
return &oauth2.Token{
AccessToken: idToken,
TokenType: "Bearer",
Expiry: token.Expiry,
}, nil
} This code will wrap the google oauth TokenSource to pass through its id_token |
Hey @bouk you are correct that we don't currently support this, but this was done intentionally at the time of writing. The identity token spec we follow states this is optional: AIP 4116. That being said I am curious if the other language libraries we support currently have this feature. @bshaffer do you know if user credentials are used in other languages? |
The python SDK seems to support it at least, since that's what gcloud uses under the hood (I assume?) |
@bouk It looks like the python auth library only works with service accounts as well. I am not against this request, but I would prefer to be consistent with what our other libraries in other languages are doing. |
Edit: thought this issue was that |
Any update on this? Would be nice if we don't have to manually do the workaround mentioned above :) @codyoss |
At least it would be great to have suport for impersonated service accounts to test locally.
|
I hope there is not a "deadlock" in pushing request changes like this, as what we were saying above is that "python lib does that logic, so we gonna do it the same here". I am not sure but I hope it won't be like some python lib users encountered the same and they created some issue (or maybe not as less people use python to work with google-apis?) saying to change this and they got a reply saying "golang package does that so we cannot change". :) |
@codyoss would you be open in pull request for at least accepting impersonated_service_account? I think not supporting authorized_user makes sense but impersonated_service_account is a valid ask. |
@tdi google.FindDefaultCredentials already supports that type of file out of the box. See code: impersonatedServiceAccount |
@codyoss Would this line of code in the above example work when an The Thank you :) |
@codyoss I think it is this line creating problems here google-api-go-client/idtoken/idtoken.go Line 139 in d530a93
This blocks I know you mentioned that on the Python package it is the same logic But I think perhaps all those packages should update their rules to have |
Another question, reading this https://google.aip.dev/auth/4116
But the page seems didn't mention that |
This package predates |
Ah, that is very nice of you, thank you very much 😃 |
@codyoss I believe to enable |
Having some level of support here for a service account or service account impersonation would be awesome for the developer experience. Mostly just commenting here to register a bit more demand and follow any outcome :D |
@liufuyang I think this package could support impersonated_service_account after taking a closer look, but might have to do so by reincorporating some of the logic in the oauth2 package here. Glanced at the issue you filed. The reason for all of that is the way the impersonated service accounts authenticate is quite different than a normal flow. They actually are just calling the https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/generateAccessTokenunder the hood. This package could do something similar and have a wrapper around calling https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/generateIdToken. So although it is not as convenient today this can be achieved by calling that API to create a TokenSource. We do have a helper for doing this today with https://pkg.go.dev/google.golang.org/api/impersonate#IDTokenSource, but it does not work auto-magically with |
@codyoss @adrianajg Thank you and I saw some nice code has been merged but has this been correctly implemented? I tested with While using a normal service account's json key file, this is what I see: There is an I glanced the code a bit while debugging, perhaps we need to set the google-api-go-client/impersonate/idtoken.go Lines 124 to 128 in 1651c38
Or, do we supposed to just use that Thank you :) |
Impersonated service account still unsupported: google-api-go-client/idtoken/idtoken.go Line 96 in b1c45c2
Also creating the option via google-api-go-client/option/option.go Line 315 in b1c45c2
which is also unsupported: Also regarding this workaround #873 (comment) , I can't use it when working with IAP service, we have to send a different audience and the The only thing that works is to download some service account save it a file and run with it locally. which isn't ideal. |
Right now there's no way to get an ID token if your credentials are user credentials e.g. if you're signed into gcloud locally.
Right now I have to exec out into
gcloud auth print-identity-token
to get a token, it would be great if this library supported it natively.The text was updated successfully, but these errors were encountered: