Skip to content
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

feat: add impersonate pacakge #927

Merged
merged 9 commits into from Mar 24, 2021
Merged

feat: add impersonate pacakge #927

merged 9 commits into from Mar 24, 2021

Conversation

codyoss
Copy link
Member

@codyoss codyoss commented Mar 15, 2021

This package is used for creating a impersonated TokenSource. This
TokenSource can then be passed into any client or API that accepts
a client option. This package provides support for three types of
impersonation:

  1. A service account impersonating another service account.
  2. A service account impersonating another service account as an
    admin user -- a pattern used with domain wide delegation.
  3. A service account creating an impersonated ID token.

Fixes: #652
Fixes: #777
Fixes: #731
Updates: #378

This pacakge is used for creating a impersonated TokenSource. This
TokenSource can then be passed into any client or API that accepts
a client option. This package provides support for three types of
impersonation:

1. A service account impersonating another service account.
2. A service account impersonating another service account as an
   admin user -- a pattern used with domain wide delegation.
3. A service account creating an impersonated ID token.
@codyoss codyoss requested review from yoshi-approver and a team as code owners March 15, 2021 17:42
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Mar 15, 2021
@codyoss codyoss added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Mar 15, 2021
@codyoss
Copy link
Member Author

codyoss commented Mar 15, 2021

Still doing a little more manual testing for one of the use-cases, but I thought I would get some code out to start the review process as this a decent size PR.

@codyoss codyoss requested a review from tbpg March 15, 2021 17:44
@codyoss
Copy link
Member Author

codyoss commented Mar 15, 2021

Note this is being targeted to a release branch where this will be released as a preview.

@codyoss
Copy link
Member Author

codyoss commented Mar 15, 2021

cc @salrashid123

@salrashid123
Copy link

hi-

is this PR to break and add additional capabilities to the impersonated creds (eg, impersonate user via domain-delegation, etc) by breaking it out to a config and then to a TokenSource it its own right?

i ask since the baseline exisiting implementation allows you to derive the tokensource via option.

thx


import (
    "google.golang.org/api/option"
    "google.golang.org/api/transport"
)

func main() {

    ctx := context.Background()
    creds, err := transport.Creds(ctx,
        option.WithScopes("https://www.googleapis.com/auth/cloud-platform"),
        option.ImpersonateCredentials("impersonated-account@fabled-ray-104117.iam.gserviceaccount.com"))
    ts := creds.TokenSource

    tok, err := ts.Token()
    log.Printf("access_token %v", tok.AccessToken)

}

@codyoss
Copy link
Member Author

codyoss commented Mar 15, 2021

@salrashid123 This package is meant to be a replacement for that option. The TokenSource generated from here, using ADC and options to configure base credentials, can be passed to any client with option.WithTokenSource.

See example_test.go.

@martinroberts
Copy link

Thank you for breaking this out for those of us calling APIs with no client library. And thanks to @salrashid123 for code and advice in the interim.

I notice that your docs focus on impersonation but you also support (domain-wide)delegation. In particular, I have been caught out by the need for the targetPrincipal to have "Service Account Token Creator" (SATC) on itself and think others would benefit from including this detail in the docs.

Let me spell that out: for a pod with workload identity WI1 (base credentials) impersonating service account SA2 (target principal) to act on behalf of user U3 (subject), we need

  • W1 has SATC role on SA2
  • SA2 has SATC role on SA2 (!)
  • SA2 has been granted relevant scopes and rights by the domain admin for U3

impersonate/doc.go Show resolved Hide resolved
impersonate/example_test.go Outdated Show resolved Hide resolved
impersonate/example_test.go Outdated Show resolved Hide resolved
impersonate/idtoken.go Outdated Show resolved Hide resolved
impersonate/idtoken.go Show resolved Hide resolved
impersonate/user.go Outdated Show resolved Hide resolved
impersonate/user.go Show resolved Hide resolved
impersonate/idtoken.go Show resolved Hide resolved
impersonate/user_test.go Outdated Show resolved Hide resolved
impersonate/integration_test.go Outdated Show resolved Hide resolved
@codyoss codyoss removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Mar 19, 2021
@codyoss codyoss added kokoro:force-run Add this label to force Kokoro to re-run the tests. and removed kokoro:force-run Add this label to force Kokoro to re-run the tests. labels Mar 22, 2021
@kokoro-team kokoro-team removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 22, 2021
@codyoss codyoss requested a review from tbpg March 24, 2021 15:37
Copy link
Contributor

@tbpg tbpg left a comment

Choose a reason for hiding this comment

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

LGTM. Would be great to have users try this out before releasing into a non-prerelease version (i.e. v0.81.0-impersonate-beta before v0.81.0 (I forget the exact syntax)) .

impersonate/integration_test.go Outdated Show resolved Hide resolved
@codyoss codyoss merged commit f8c4b7e into googleapis:impersonate-preview Mar 24, 2021
@codyoss codyoss deleted the imp-pub-2 branch March 24, 2021 21:56
@natalysheinin
Copy link

Just tried this and it worked as expected. Thank-you so much for pushing this feature through.

@hanneshayashi
Copy link

Works like a charm. Thanks for this!

@salrashid123
Copy link

tested

  • impersonate->(access_tokens->gcs), 
  • impersonate->(id_tokens->IAP), 
  • impersonate->(id_tokens->gRPC)->Cloud Run, 

its unrelated to impersonated creds here but its never really clear how to use our tokensources with grpc connections...maybe a doc bug to update grpc stuff elsewhere

here's the full test sequence for the bit above with a highlight on the specific grpc struct you need for tokensource

https://gist.github.com/salrashid123/17d36368fc720c09b4acf4a7bdc9f340#file-main-go-L157


ref, cloud run+idtoken+grpc

@codyoss
Copy link
Member Author

codyoss commented Mar 30, 2021

@salrashid123

never really clear how to use our tokensources with grpc connections
For use with our gRPC based client libraries you can use the option.WithTokenSource. If you are talking about manually dialing what you did in your gist is fine dialing with grpc.WithPerRPCCredentials. You could use the oauth.TokenSource directly instead of using a wrapper if you wanted. We wrap it in our transport code because we add a little bit of extra metadata.

@salrashid123
Copy link

yeah, the grpc test was using this library to get an idtoken for a non GCP service api (i.e an api that i run that is grpc that happens to accept a google id_token (and in this case, the idtoken is for an impersonated creds).

but yeah, thanks. the oauth.TokenSource{} also works here.

	conn, err = grpc.Dial(grpcHost+":443",
		grpc.WithTransportCredentials(ce),
		grpc.WithPerRPCCredentials(oauth.TokenSource{
			TokenSource: gRPCidTokenSource,
		}),
	)

@upodroid
Copy link

upodroid commented Apr 8, 2021

I'm implementing the new impersonate package in hashicorp/terraform#28296 and it looks like the package only allows the initial credentials to be an ADC. Terraform supports static accesstoken(static TokenSource) or json loaded with option.WithCredentialsJSON which this package doesn't support.

https://github.com/hashicorp/terraform/blob/b7fb533bd27d63e582489906a63bf1b25ecd5e49/backend/remote-state/gcs/backend.go#L152

@codyoss
Copy link
Member Author

codyoss commented Apr 8, 2021

@upodroid You should be able to pass in any TokenSource by doing something like: impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{...}, option.WithTokenSource(anyTokenSource)) This will use the provided TokenSource instead of creds found via ADC for the base credentials in the impersonation flow. Does that solve your issue?

@upodroid
Copy link

That worked for me, thanks.

@upodroid
Copy link

btw, v0.44.0 doesn't include the impersonate package. It would be nice to see it in v0.45.0

@codyoss
Copy link
Member Author

codyoss commented Apr 15, 2021

@upodroid Yes, v0.44.0 got cut sooner than originally planned. I hope to get this in the next main release. I will ping this issue and update the release notes accordingly when that happens.

codyoss added a commit that referenced this pull request May 3, 2021
This package is used for creating an impersonated TokenSource. This
TokenSource can then be passed into any client or API that accepts
a client option. This package provides support for three types of
impersonation:

1. A service account impersonating another service account.
2. A service account impersonating another service account as an
   admin user -- a pattern used with domain wide delegation.
3. A service account creating an impersonated ID token.
@codyoss codyoss mentioned this pull request May 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants