-
Notifications
You must be signed in to change notification settings - Fork 10
[rbac-manager] Support workload identity #330
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
[rbac-manager] Support workload identity #330
Conversation
|
@vinayvinay I think you're the one left in GC that I know.. Any idea who would be best suited to review this? 😁 |
b4d17a9 to
44d5970
Compare
Makefile
Outdated
| go install github.com/onsi/ginkgo/ginkgo@v1.16.5 | ||
| go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.10.0 | ||
| go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest | ||
| go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.17 |
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.
Shamelessly stolen from #335 to get my CI tests passing.. 😬
Thanks for letting me know! Unfortunately I'm no longer at GC so don't think I'd be able to do that 😅 |
|
Bumping - it'd be great to get this in! |
0x0013
left a comment
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.
@jace-ys Thanks, this looks like a valuable addition.
I'm no expert in GCP authentication flow, so I would like to ask some clarifications before I can review, mostly for my own understanding. I've left these in code comments. Apologies if the answers to these are obvious.
cmd/rbac-manager/main.go
Outdated
| Subject: subject, | ||
| } | ||
|
|
||
| ts, err := impersonate.CredentialsTokenSource(ctx, config, option.WithCredentials(creds)) |
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 it necessary for the account to impersonate itself, instead of using the TokenSource already returned by FindDefaultCredentials?
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.
Good question. I'm no expert in GCP auth myself and it's not very well documented or discussed much, but from reading various sources, my understanding is that the federated access token obtained from the GCE
metadata server (via workload identity) is not sufficient for acting as the subject via domain-wide delegation to call Google Workspace Admin APIs.
For delegation to work, we need to sign a JWT with the the "sub" claim set to subject - this happens implicitly through impersonation.
You can kind of see this behaviour in userTokenSource: https://github.com/googleapis/google-api-go-client/blob/af0a938ba1e01e7c2ce7f96fef1e62478f5da784/impersonate/user.go#L96-L103
Whereas you don't see this in computeSource obtained by WID: https://cs.opensource.google/go/x/oauth2/+/refs/tags/v0.24.0:google/google.go;l=270
Hope that make sense!
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.
Also, the changes in this PR were largely inspired / adapted from dexidp/dex#2989
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.
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.
That said, looks like there have been some new developments since I first opened this PR.. 👀
It looks like it's possible to assign Workspace Admin Groups Reader role to service accounts:
- https://support.google.com/a/answer/9807615?sjid=13011041076049488223-AP#:~:text=Assign%20a%20role%20to%20a%20service%20account
- https://cloud.google.com/identity/docs/how-to/setup#auth-no-dwd
Which might mean that there's no need for impersonation or domain-wide delegation anymore, which would greatly simplify the auth here (just google.FindDefaultCredentials might be all that's needed) 🤔
But I think that warrants a separate PR as it's a different feature altogether..
cmd/rbac-manager/main.go
Outdated
| return nil, err | ||
| } | ||
|
|
||
| return directoryv1.NewService(ctx, option.WithTokenSource(ts)) |
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 wonder if the option when using a supplied json credentials (old behavior) could also use the TokenSource from Credentials returned by FindDefaultCredentials?
If so, likely the code could be simplified a little, instead of needing to call NewService with different option for each credential type.
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.
Yeap that's a good point! I didn't change that initially as I didn't want to make too much changes to existing code.
But you're right that we can use the same WithTokenSource option for both the new and old behaviours. That said, it's not TokenSource from the Credentials returned by FindDefaultCredentials but the TokenSource from the jwt.Config, as we need the token source to have the (domain-wide delegation) subject set.
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've updated the PR to use WithTokenSource for both code paths 👍🏻
44d5970 to
2a18959
Compare
|
@jace-ys it seems the container-builder hasn't built an image for this branch - perhaps it didn't receive the webhook at the time of your last push. Could you generate a push event on this PR, for example, by pushing an empty commit, to see if it triggers a build? Thanks! |
2a18959 to
3cdb482
Compare
Tried that but doesn't look like it triggered a build either! 🙁 |
@jace-ys thanks for trying, it looks like container-builder is still not picking it up. I assume this is because the head branch is external from GC. I'll see if there's anything that can be done about it. |
|
Hey @0x0013, any luck getting the CI check to run? |
3cdb482 to
32b96b6
Compare
|
Hi @jace-ys , Thanks for reminder. It's been a bit hard to commit time to it, but we do have a fix for this issue, just awaiting proper review. TLDR is that our container-builder, which also is (and should be) a required CI check, currently only acts on organisation-internal commits - which is good from the point of security (we don't want to run automated builds on arbitrary commits), but is obviously not ideal for accepting external contributions. So I've been trying to implement a way to manually trigger it after someone from GC evaluates the changes in the PR. Hopefully we have the reviews done this week. |
|
/build container |
|
Looks like it doesn't work yet, will investigate. |
Thanks for looking into this, appreciate your time! |
|
/build container |
1 similar comment
|
/build container |
|
@jace-ys looks like container-builder is finally able to build the container and also return the status to GitHub CI check. Could you please rebase this PR to |
32b96b6 to
efc8c4b
Compare
Thanks for doing this! I've rebased 👍🏻 |
|
/build container |
0x0013
left a comment
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.
Sorry this took so long to review due to the CI check issues, and thanks for addressing my previous comments.
The change looks good to me. I've tested on lab to ensure the original behavior (mounted credentials file) still works, and it seems that it does.
Thanks again for submitting the PR.
|
@jace-ys it looks like there are some merge conflicts since the dependency updates we pushed yesterday. Could I ask you to rebase once again? |
efc8c4b to
32b96b6
Compare
c131e13 to
b774edb
Compare
Awesome, thanks for helping out with this. I've rebased now. |
|
/build container |
0x0013
left a comment
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.
Thanks for rebasing. Looks good.
And thanks again for your contribution.
|
Edit: Nevermind, just realized the upstream image is not public |
Hey folks 👋🏻
Hope you don't mind this contribution but we'd like to see theatre support workload identity in the
rbac-managerinstead of using service account keys. I've made the change such that if workload identity is not configured, therbac-managerwill fallback to using service account keys.This is how we're currently using it with workload identity in our GKE cluster (after removing
GOOGLE_APPLICATION_CREDENTIALS):Same change on our fork: duffelhq#3
kubectl annotate serviceaccount theatre-rbac-manager \ --namespace theatre-system \ iam.gke.io/gcp-service-account=theatre@duffel-prod.iam.gserviceaccount.com