Skip to content

Add multi-tenant workload identity support for GCP Bucket #1862

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

cappyzawa
Copy link
Member

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
@cappyzawa cappyzawa marked this pull request as draft August 8, 2025 16:21
Copy link
Member

@matheuscscp matheuscscp left a comment

Choose a reason for hiding this comment

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

Looking good! 😁

@@ -15,6 +15,7 @@ rules:
- ""
resources:
- secrets
- serviceaccounts
Copy link
Member

Choose a reason for hiding this comment

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

I assume this change is auto-generated due to the following?

// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch

Comment on lines +654 to +655
The `gcp` provider can be used to authenticate automatically using OAuth scopes
or Workload Identity, and by extension gain access to Google Cloud Storage.
Copy link
Member

@matheuscscp matheuscscp Aug 8, 2025

Choose a reason for hiding this comment

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

Suggested change
The `gcp` provider can be used to authenticate automatically using OAuth scopes
or Workload Identity, and by extension gain access to Google Cloud Storage.
The `gcp` provider can be used to authenticate automatically using Workload Identity,
and by extension gain access to Google Cloud Storage.

I'd not mention OAuth scopes anywhere in these docs, they're kind of a very negligible implementation detail, we don't even use specific scopes per service in the implementation, we actually use a single wildcard scope for all of them:

https://www.googleapis.com/auth/cloud-platform

name: source-controller
```

The Google Cloud Storage service uses the permission `storage.objects.get`
Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines +723 to +730
be enabled. Add the following environment variable to the source-controller
deployment:

```yaml
env:
- name: ENABLE_OBJECT_LEVEL_WORKLOAD_IDENTITY
value: "true"
```
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this, the environment variable is set automatically by the controller main() when the feature gate is enabled (auth.EnableObjectLevelWorkloadIdentity()):

source-controller/main.go

Lines 179 to 185 in c2b572b

switch enabled, err := features.Enabled(auth.FeatureGateObjectLevelWorkloadIdentity); {
case err != nil:
setupLog.Error(err, "unable to check feature gate "+auth.FeatureGateObjectLevelWorkloadIdentity)
os.Exit(1)
case enabled:
auth.EnableObjectLevelWorkloadIdentity()
}

@@ -590,6 +607,12 @@ func (r *BucketReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.Bu
// Remove our finalizer from the list
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)

// Cleanup caches.
if r.TokenCache != nil {
Copy link
Member

Choose a reason for hiding this comment

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

There's already a guard inside .DeleteEventsForObject() 👍 We can remove this if like in all other controllers

@@ -430,6 +435,18 @@ func (r *BucketReconciler) reconcileStorage(ctx context.Context, sp *patch.Seria
// the provider. If this fails, it records v1.FetchFailedCondition=True on
// the object and returns early.
func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error) {
usesObjectLevelWorkloadIdentity := obj.Spec.Provider != sourcev1.BucketProviderGeneric && obj.Spec.SecretRef == nil && obj.Spec.ServiceAccountName != ""
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
usesObjectLevelWorkloadIdentity := obj.Spec.Provider != sourcev1.BucketProviderGeneric && obj.Spec.SecretRef == nil && obj.Spec.ServiceAccountName != ""
usesObjectLevelWorkloadIdentity := obj.Spec.Provider != "" && obj.Spec.Provider != sourcev1.BucketProviderGeneric && obj.Spec.ServiceAccountName != ""

httpClient, err := o.newCustomHTTPClient(ctx, o)
if err != nil {
return nil, err
}
clientOpts = append(clientOpts, option.WithHTTPClient(httpClient))
case len(o.authOpts) > 0:
// Object-level workload identity: Create TokenSource using auth options
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Object-level workload identity: Create TokenSource using auth options
// Workload identity: Create TokenSource using auth options

httpClient, err := o.newCustomHTTPClient(ctx, o)
if err != nil {
return nil, err
}
clientOpts = append(clientOpts, option.WithHTTPClient(httpClient))
case len(o.authOpts) > 0:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
case len(o.authOpts) > 0:
default:

If .spec.provider is gcp and .spec.secretRef is not set, we should use the auth package logic

Comment on lines +137 to +138
// No explicit authentication - controller-level workload identity uses Application Default Credentials
// TODO: https://github.com/fluxcd/flux2/issues/5465 will add lockdown support to prevent unintended usage of this fallback
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// No explicit authentication - controller-level workload identity uses Application Default Credentials
// TODO: https://github.com/fluxcd/flux2/issues/5465 will add lockdown support to prevent unintended usage of this fallback

See the default: case comment above

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.

2 participants