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

[rbac-manager] Support workload identity #330

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jace-ys
Copy link
Contributor

@jace-ys jace-ys commented Dec 8, 2023

Hey folks 👋🏻

Hope you don't mind this contribution but we'd like to see theatre support workload identity in the rbac-manager instead of using service account keys. I've made the change such that if workload identity is not configured, the rbac-manager will 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

# Config Connector CRDs
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicy
metadata:
  name: theatre-workload-identity-user
  annotations:
    cnrm.cloud.google.com/project-id: duffel-prod
spec:
  bindings:
  - members:
    - serviceAccount:duffel-prod.svc.id.goog[theatre-system/theatre-rbac-manager]
    role: roles/iam.workloadIdentityUser
  - members:
    - serviceAccount:[email protected]
    # Required so that the theatre service account can impersonate itself
    role: roles/iam.serviceAccountTokenCreator
  resourceRef:
    apiVersion: iam.cnrm.cloud.google.com/v1beta1
    kind: IAMServiceAccount
    external: projects/duffel-prod/serviceAccounts/[email protected]
 kubectl annotate serviceaccount theatre-rbac-manager \
    --namespace theatre-system \
    iam.gke.io/[email protected]

@jace-ys jace-ys marked this pull request as draft December 8, 2023 16:23
@jace-ys jace-ys marked this pull request as ready for review December 8, 2023 17:56
@jace-ys
Copy link
Contributor Author

jace-ys commented Dec 8, 2023

@vinayvinay I think you're the one left in GC that I know..

Any idea who would be best suited to review this? 😁

Makefile Outdated
@@ -68,7 +68,7 @@ manifests: generate
install-tools:
go install github.com/onsi/ginkgo/[email protected]
go install sigs.k8s.io/controller-tools/cmd/[email protected]
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.17
Copy link
Contributor Author

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.. 😬

@jace-ys
Copy link
Contributor Author

jace-ys commented Aug 20, 2024

@mbfisher @bogvak @0x0013 Sorry for the direct tag but wanted to get this merged and saw that you folks have been recently active on this repo!

@mbfisher
Copy link

@mbfisher @bogvak @0x0013 Sorry for the direct tag but wanted to get this merged and saw that you folks have been recently active on this repo!

I'm a contributor so can't help I'm afraid, Core Infra own this so I'd raise a SPOC ticket with them to get a review

@jace-ys
Copy link
Contributor Author

jace-ys commented Aug 20, 2024

I'm a contributor so can't help I'm afraid, Core Infra own this so I'd raise a SPOC ticket with them to get a review

Thanks for letting me know! Unfortunately I'm no longer at GC so don't think I'd be able to do that 😅

@benwh
Copy link
Contributor

benwh commented Sep 9, 2024

Bumping - it'd be great to get this in!

👋 @ttamimi @VSpike @ijames-gc

Copy link
Contributor

@0x0013 0x0013 left a 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.

Subject: subject,
}

ts, err := impersonate.CredentialsTokenSource(ctx, config, option.WithCredentials(creds))
Copy link
Contributor

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?

Copy link
Contributor Author

@jace-ys jace-ys Nov 30, 2024

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!

Copy link
Contributor Author

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

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:

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..

return nil, err
}

return directoryv1.NewService(ctx, option.WithTokenSource(ts))
Copy link
Contributor

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.

Copy link
Contributor Author

@jace-ys jace-ys Nov 30, 2024

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.

Copy link
Contributor Author

@jace-ys jace-ys Nov 30, 2024

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 👍🏻

@jace-ys jace-ys force-pushed the jace/rbac-manager-workload-identity branch from 44d5970 to 2a18959 Compare November 30, 2024 06:30
@0x0013
Copy link
Contributor

0x0013 commented Dec 16, 2024

@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!

@jace-ys jace-ys force-pushed the jace/rbac-manager-workload-identity branch from 2a18959 to 3cdb482 Compare December 16, 2024 16:11
@jace-ys
Copy link
Contributor Author

jace-ys commented Dec 16, 2024

@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!

Tried that but doesn't look like it triggered a build either! 🙁

@0x0013
Copy link
Contributor

0x0013 commented Dec 16, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants