-
Notifications
You must be signed in to change notification settings - Fork 375
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(impersonated): add impersonated credentials auth #779
Conversation
@salrashid123 @JustinBeckwith I will make an effort to provide code review on this tomorrow 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)