Skip to content

feat(clusters): setup workload identity confguration for oidc clusters - #2192

Merged
mikolajkucinski merged 18 commits into
mainfrom
feat/1637-object-level-workload-identity
Sep 9, 2026
Merged

feat(clusters): setup workload identity confguration for oidc clusters#2192
mikolajkucinski merged 18 commits into
mainfrom
feat/1637-object-level-workload-identity

Conversation

@mikolajkucinski

@mikolajkucinski mikolajkucinski commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Description

Flux reaches a Plugin's target cluster through the kubeconfig Secret that onboarding writes, and for OIDC onboarded clusters that Secret holds a token that has to be rotated. Flux can mint the token itself with ObjectLevelWorkloadIdentity, via a ConfigMap describing the cluster instead of a kubeconfig.

A workloadIdentity feature toggle is added. When enabled the bootstrap controller now renders that ConfigMap for every OIDC onboarded cluster, with the API server address, the CA and the service account Flux should impersonate.

bootstrap controller implements generic object reconciler without status patches.

Can be used for corev1.Secret now

A new RestClientGetter method for WorkloadIdentity is added in clientutil - NewRestClientGetterForWI

cluster controller uses the new RestClientGetter method if workloadIdentity is enabled

off-boarding is strictly cluster secret drop and not anymore by Cluster resource deletion

What type of PR is this? (check all applicable)

  • 🍕 Feature
  • 🐛 Bug Fix
  • 📝 Documentation Update
  • 🎨 Style
  • 🧑‍💻 Code Refactor
  • 🔥 Performance Improvements
  • ✅ Test
  • 🤖 Build
  • 🔁 CI
  • 📦 Chore (Release)
  • ⏩ Revert

Related Tickets & Documents

Added tests?

  • 👍 yes
  • 🙅 no, because they aren't needed
  • 🙋 no, because I need help
  • Separate ticket for tests # (issue/pr)

Added to documentation?

  • 📜 README.md
  • 🤝 Documentation pages updated
  • 🙅 no documentation needed
  • (if applicable) generated OpenAPI docs for CRD changes

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes

@mikolajkucinski
mikolajkucinski force-pushed the feat/1637-object-level-workload-identity branch 2 times, most recently from cd2432a to d2bebb1 Compare September 7, 2026 10:04
@mikolajkucinski
mikolajkucinski marked this pull request as ready for review September 7, 2026 10:09
@mikolajkucinski
mikolajkucinski requested a review from a team as a code owner September 7, 2026 10:09
Copilot AI lite review requested due to automatic review settings September 7, 2026 10:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are confirmed correctness issues (e2e ClusterRoleBinding update without resourceVersion, and missing/empty CA key can produce a “ready” Flux access ConfigMap with empty CA data).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds support for Flux HelmReleases to reach OIDC-onboarded remote clusters via Flux’s ObjectLevelWorkloadIdentity by switching from a rotating kubeconfig Secret reference to a rendered per-cluster access ConfigMap (while leaving kubeconfig-onboarded clusters unchanged).

Changes:

  • Render a Flux access ConfigMap for OIDC clusters during cluster reconciliation (and surface readiness via a new Cluster condition).
  • Update Plugin → HelmRelease reconciliation to use kubeConfig.configMapRef when the access ConfigMap exists, otherwise fall back to the kubeconfig Secret.
  • Add unit/e2e coverage and enable the Flux helm-controller feature gate in the sample Flux install.
File summaries
File Description
internal/flux/helm_release_builder.go Adds builder support for kubeConfig.configMapRef.
internal/flux/helm_release_builder_test.go Unit tests for new ConfigMap kubeconfig reference builder method.
internal/controller/plugin/plugin_controller_flux.go Chooses ConfigMap vs Secret cluster access mode when building HelmRelease spec.
internal/controller/plugin/flux_kubeconfig.go Determines whether OIDC cluster access ConfigMap should be used (with fallback).
internal/controller/plugin/flux_kubeconfig_test.go Unit tests for access-mode detection logic.
internal/controller/cluster/phases/phases.go Inserts new Flux access rendering phase for OIDC clusters.
internal/controller/cluster/phases/ensure_flux_access.go Renders the Flux access ConfigMap for OIDC clusters and sets Cluster condition.
internal/controller/cluster/phases/ensure_flux_access_test.go Unit tests for ConfigMap rendering and phase ordering/conditions.
internal/controller/cluster/cluster_controller.go Adds RBAC for ConfigMaps and watches owned ConfigMaps.
e2e/shared/cluster.go Adds shared helper to set up OIDC ClusterRoleBinding for e2e.
e2e/plugin/scenarios/flux_object_level_workload_identity.go New e2e scenario covering OIDC onboarding → ConfigMap rendering → HelmRelease via configMapRef.
e2e/plugin/e2e_test.go Runs the new plugin e2e scenario and offboards the extra OIDC cluster.
e2e/cluster/expect/expect.go Removes duplicated OIDC role binding helper (moved to shared).
e2e/cluster/e2e_test.go Switches cluster e2e tests to use the shared OIDC role binding helper.
config/samples/flux/kustomization.yaml Enables ObjectLevelWorkloadIdentity feature gate for helm-controller in sample Flux install.
charts/manager/templates/rbac/manager-role.yaml Extends manager RBAC to create/update/patch ConfigMaps.
api/v1alpha1/plugin_types.go Adds a new condition reason for “access mode undetermined”.
api/v1alpha1/cluster_types.go Adds FluxAccessReady condition type for OIDC access ConfigMap readiness.
Review details
  • Files reviewed: 18/18 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread e2e/shared/cluster.go
Comment thread internal/controller/cluster/phases/ensure_flux_access.go Outdated
@mikolajkucinski
mikolajkucinski force-pushed the feat/1637-object-level-workload-identity branch from d2bebb1 to e0c505f Compare September 8, 2026 08:26
@github-actions github-actions Bot added size/L and removed size/XL labels Sep 8, 2026
@mikolajkucinski mikolajkucinski changed the title feat(plugins): reach OIDC clusters via ObjectLevelWorkloadIdentity feat(clusters): render the flux access ConfigMap for OIDC clusters Sep 8, 2026
@abhijith-darshan abhijith-darshan changed the title feat(clusters): render the flux access ConfigMap for OIDC clusters feat(clusters): generate ObjectLevelWorkloadIdentity ConfigMap for OIDC clusters Sep 8, 2026
@github-actions github-actions Bot added size/XXL and removed size/L labels Sep 8, 2026
@abhijith-darshan abhijith-darshan changed the title feat(clusters): generate ObjectLevelWorkloadIdentity ConfigMap for OIDC clusters feat(clusters): setup workload identity confguration for oidc clusters Sep 8, 2026
@abhijith-darshan
abhijith-darshan force-pushed the feat/1637-object-level-workload-identity branch 2 times, most recently from 13abfdf to d8d82f3 Compare September 8, 2026 21:10
@abhijith-darshan
abhijith-darshan requested review from a team as code owners September 8, 2026 22:54
@abhijith-darshan
abhijith-darshan force-pushed the feat/1637-object-level-workload-identity branch from 639bc7b to 950fe0b Compare September 8, 2026 22:58
@abhijith-darshan
abhijith-darshan requested a lite review from Copilot September 8, 2026 22:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new ReconcileObject finalizer logic mishandles ctrl.Result{Requeue:true} and the feature-flag “hot reload” handlers currently don’t reconcile resources (and silently drop errors), which can break expected behavior when toggling the gate.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (5)

  • pkg/mocks/mock_Client.go: Generated file
  • pkg/mocks/mock_FinalizerNamer.go: Generated file
  • pkg/mocks/mock_ObjectReconciler.go: Generated file
  • pkg/mocks/mock_Reconciler.go: Generated file
  • pkg/mocks/mock_Storage.go: Generated file
  • Files reviewed: 26/31 changed files
  • Comments generated: 5
  • Review effort level: Lite

Comment thread pkg/lifecycle/reconcile.go Outdated
Comment thread internal/controller/cluster/bootstrap_controller.go
Comment thread internal/controller/cluster/cluster_controller.go
Comment thread internal/controller/cluster/phases/bootstrap_phases.go
Comment thread internal/controller/cluster/phases/bootstrap_phases.go
@abhijith-darshan

Copy link
Copy Markdown
Contributor

needs - #2203

mikolajkucinski and others added 15 commits September 9, 2026 11:08
Add an ensureFluxAccess phase rendering a ConfigMap with provider, address,
audiences, serviceAccountName and ca.crt, and the configmaps RBAC marker for
the cluster controller.

On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
Move ensureFluxAccess to the end of the OIDC phase chain so a ConfigMap
write failure no longer breaks out before the phases that renew the
kubeconfig Secret token, add a FluxAccessReady condition, and take the
ConfigMap keys from the upstream Flux constants.

On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
Set a controller owner reference, enqueue the cluster when the ConfigMap
changes, and take the service account name from the cluster instead of
the secret.

On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
Add the workloadIdentity feature key and IsWorkloadIdentityEnabled accessor, the global.workloadIdentity.enabled chart value and helper, and drop the unused FluxAccessReady condition.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Split the bootstrap controller into idempotent phases and, under workload identity, write the Flux remote ConfigMap instead of a static kubeconfig. Enable the ObjectLevelWorkloadIdentity feature gate on the Flux controllers.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Add NewRestClientGetterForWI which mints a ServiceAccount token and builds the rest config from the OIDC secret, and move remote client construction into the cluster phases to select the WI or kubeconfig path per secret.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Label the feature-flags ConfigMap and watch it in the cluster and bootstrap controllers, updating the workload identity gate live via an atomic bool.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Flip the feature flag live and verify the Flux config map is written with no static kubeconfig.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Delete the KubeConfig secret instead of the Cluster so the bootstrap
controller does not recreate the Cluster from the still-present secret
during AfterAll.

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
this is handled in createOrUpdateCluster

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
after suite handles it and the finalizer check is asserted in pkg/lifecycle/reconcile_test

Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
Signed-off-by: abhijith-darshan <abhijith.ravindra@sap.com>
@abhijith-darshan
abhijith-darshan force-pushed the feat/1637-object-level-workload-identity branch from e6d971c to eab1e74 Compare September 9, 2026 09:09
On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
@mikolajkucinski
mikolajkucinski force-pushed the feat/1637-object-level-workload-identity branch from 0a2239d to 9a6d1b6 Compare September 9, 2026 11:16
…e changes

On-behalf-of: @SAP <mikolaj.kucinski@sap.com>
Signed-off-by: Mikolaj Kucinski <osidu12@gmail.com>
@mikolajkucinski
mikolajkucinski force-pushed the feat/1637-object-level-workload-identity branch from bcb1383 to 4c008ce Compare September 9, 2026 11:24
@mikolajkucinski
mikolajkucinski merged commit acdd619 into main Sep 9, 2026
27 checks passed
@mikolajkucinski
mikolajkucinski deleted the feat/1637-object-level-workload-identity branch September 9, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants