googleapis / google-auth-library-python

Google Auth Python Library
https://googleapis.dev/python/google-auth/latest/
Apache License 2.0
780 stars 307 forks source link

Allow google.auth.impersonated_credentials ability to domain-delegate #930

Open salrashid123 opened 2 years ago

salrashid123 commented 2 years ago

This is a really rare usecase but filing it for the record and api surface parity with golang.

in some usecases, i would like to impersonate a service account AND use that service account to assume the identity of a Google Workspace User (and then use some api on behalf of that user)

Currently google.auth.impersonated_credentials fulfils the first phase:

user_1 --> impersonate(svc_account) --> access_resource (as svc_account)

the flow in the go snippet below goes one step further:

user1->impersonate(svc_account)-->domain_delgate(user2)->calendar_api (as user2)

    ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{
        TargetPrincipal: "foo@project-id.iam.gserviceaccount.com",
        Scopes:          []string{"https://www.googleapis.com/auth/cloud-platform"},
        // Specify user to impersonate
        Subject: "admin@example.com",
    })

note the Subject field which does the second step (its very briefly described here under the addition claims section)


WIthout this built in capability, a customer would need to manually generate a JWT signed by svc_account where the subect field is the user2 then send that to google, get the access_token back and embed that into staticCredential

the other approach is to chain the impersonated_credential into another stand-alone class (outside of this library)...(which maybe a better way, considering)

its really convoluted and i'll cite a sample of this shortly.

salrashid123 commented 2 years ago

ok, here are two snippets.

In the first one, i'm using impersonated_credentials to sign a JWT as the service account, then exchange that jwt with google for the target users's access_token. This FR is to somehow make it easier to do these step (agian, this is a pretty specific usecase...)

for referenc, all that the impersonated_credentials signer is doing is itself using the iamcredentials api. Meaning, the snippet above is equivalent to doing this manually here:

busunkim96 commented 2 years ago

@arithmetic1728 @silvolu Please take a look.

tvoipio commented 2 years ago

I would not say this is "pretty specific use case", as it appears that domain-wide delegation is crucial for any successful server-to-server interaction with Google Workspace. I am trying to provision users, Gmail settings, and calendar events from another source (running in AWS) to Google Workspace, and it seems that this issue is preventing me from using workload identity federation at the moment. I have to try the method outlined in the gists above, but if it does not work, I have to scrap federation and just store the service account keys as secrets in AWS - not really thrilled by the prospect.

It would be nice if the "does not seem possible" comment in #935 had some reasoning as to why, as the gists here seem to show that it IS possible?

salrashid123 commented 2 years ago

you can use a service account directly to access workspace apis without the two step process of actually using domain delegation. i'm using a svc account here directly for the groups api.

In your case, you can use worklaod federation from aws and enable service_account_impersonation_url setting as shown here