feat(impersonated): add impersonated credentials auth#779
feat(impersonated): add impersonated credentials auth#779salrashid123 wants to merge 0 commit intogoogleapis:masterfrom salrashid123:master
Conversation
|
@salrashid123 @JustinBeckwith I will make an effort to provide code review on this tomorrow 👍 |
bcoe
left a comment
There was a problem hiding this comment.
this is looking really solid, mainly a few initial questions.
src/auth/impersonated.ts
Outdated
| * If left unset, sourceCredential must have that role on targetPrincipal. | ||
| * @param targetScopes scopes to request during the authorization grant. | ||
| * @param lifetime number of seconds the delegated credential should be | ||
| * valid for (up to 3600). |
There was a problem hiding this comment.
If I need to hold the actual credentials to generate the impersonated client, how does this provide improved security. I think I just don't fully understand the threat model this protects me from (not be a security person).
There was a problem hiding this comment.
You'll always need some credentials to bootstrap with but this capability basically allows you to impersonate another credential
you can do something like this: You own serivceAccoutnA, I own serviceAccountB and I give B permissions on GCS BucketG that i own; A does not have permission on G.
I can create an IAM condition that says "only allow A access to impersonate B between 1am and 2am". So what serviceAccountA has is temp access to bucketG.
You can basically continue this chain of delegation. The full flow is described here
src/auth/impersonated.ts
Outdated
| .getAccessToken() | ||
| .then(res => { | ||
| const name = 'projects/-/serviceAccounts/' + this.targetPrincipal; | ||
| const u = `https://iamcredentials.googleapis.com/v1/${name}:generateAccessToken`; |
There was a problem hiding this comment.
it might be worth pulling this endpoint into a variable, and perhaps even making it configurable with ImpersonatedOptions.
There was a problem hiding this comment.
ok added in an option
test/test.impersonated.ts
Outdated
| const scopes = [mockExample()]; | ||
| impersonated.credentials.access_token = 'initial-access-token'; | ||
| impersonated.credentials.expiry_date = new Date().getTime() - 10000; | ||
| await impersonated.request({url}); |
There was a problem hiding this comment.
is the idea that it will immediately refresh the token on the first request, because the impersonated account hasn't yet been created?
There was a problem hiding this comment.
yeah, i derived that idea from how google-auth-python does its refresh of creds. Should i init creds on creation (i was just blindly copying the existing compute implementation here)
bcoe
left a comment
There was a problem hiding this comment.
I'm going to switch some of the promise logic to use await, but otherwise this is honestly looking very solid; I believe we'll want to add documentation, which I will create a tracking ticket for.
|
this is blocked while we have a few internal discussions about how to make auth more extensible. |
|
hi- |
|
To echo @salrashid123, as far as I know this work is not related to the ID token work I've done. |
|
@bcoe is there anything we can do to help move this PR along? I'm not sure what's still outstanding. (IIUC this functionality would be very useful in local development, to allow an individual developer's local credentials to impersonate a service account - some GCP APIs only support access by service accounts - without the developer needing a private SA key file on their machine) |
|
@rh389 I apologize for the slow reply, I would love to get this work moving again. I'm going to bring it up with a few folks internally and see what we can make happen. |
|
Hi, we'd use this feature too :) For example for vision api we need service account from exact project as adding from other one is not working. Fortunatelly impersonation is working and we wanted to use it but without this feature we are blocked |
|
@salrashid123 not quite sure what happened, had a merge conflict updating your PR, changes incoming. |
Fixes #535
Adds
ImpersonatedCredentials. This credential type basically takes one source credential and exchanges it for another, different service account.for reference, it exists currently in:
google-auth-python: google.auth.impersonated_credentials.htmlgoogle-auth-java: ImpersonatedCredentials.javaI do NOT have testcases that cover this (any pointers or sample on how to do the exchange (i.,e two round trips for the token would be appreciated)