✨ Deprecate ClusterExtension spec.serviceAccount#2770
Conversation
✅ Deploy Preview for olmv1 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This pull request deprecates ClusterExtension.spec.serviceAccount and removes the per-service-account authorization/impersonation infrastructure, shifting operator-controller to consistently use its own cluster-admin service account for cluster interactions. It also simplifies drift-detection/watch plumbing by moving from per-ClusterExtension cache management to a shared managedcache.TrackingCache, and updates manifests + test suites accordingly.
Changes:
- Deprecates
spec.serviceAccountin the API (godoc + schema changes) and adds aValidatingAdmissionPolicyto emit kubectl deprecation warnings when it’s set. - Removes per-SA authentication/authorization code paths, feature gates, and related tooling/dependencies.
- Updates Helm charts/manifests and E2E/unit tests to reflect the new model and add warning assertions.
Reviewed changes
Copilot reviewed 74 out of 77 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/extension-developer-e2e/extension_developer_test.go | Removes spec.serviceAccount usage from extension-developer E2E test. |
| test/e2e/steps/testdata/olm-sa-helm-rbac-template.yaml | Removes SA-scoped RBAC template used by older E2E flows. |
| test/e2e/steps/testdata/olm-sa-boxcutter-rbac-template.yaml | Removes SA-scoped Boxcutter RBAC template. |
| test/e2e/steps/testdata/olm-sa-boxcutter-no-create-rbac-template.yaml | Removes “no create verb” RBAC template previously used for preflight-permissions scenarios. |
| test/e2e/steps/testdata/namespace-template.yaml | Adds a reusable namespace YAML template for E2E setup. |
| test/e2e/steps/steps.go | Adds namespace/warning steps; captures kubectl stderr for warning assertions; removes preflight-permissions SA step. |
| test/e2e/steps/hooks.go | Tracks last kubectl apply stderr; removes removed feature gates from test feature map. |
| test/e2e/features/user-managed-fields.feature | Drops SA setup/field; ensures namespace exists explicitly. |
| test/e2e/features/update.feature | Drops SA setup/field; ensures namespace exists explicitly. |
| test/e2e/features/uninstall.feature | Drops SA setup/field and removes SA-deletion resilience scenario tied to old model. |
| test/e2e/features/status.feature | Drops SA setup/field; ensures namespace exists explicitly. |
| test/e2e/features/revision.feature | Drops SA annotations and SA setup; adds namespace setup steps. |
| test/e2e/features/recover.feature | Drops SA setup/field and removes preflight-permissions recovery scenario. |
| test/e2e/features/proxy.feature | Drops SA setup/field; ensures namespace exists explicitly. |
| manifests/standard.yaml | Regenerates CRD schema (serviceAccount optional/deprecated), removes manager ClusterRole, binds operator-controller to cluster-admin, adds VAP + binding. |
| manifests/standard-e2e.yaml | Same as standard.yaml but for e2e manifest variant. |
| manifests/experimental.yaml | Same changes for experimental feature set manifest. |
| manifests/experimental-e2e.yaml | Same changes for experimental e2e manifest variant. |
| Makefile | Removes k8s-pin target and updates verify to use tidy. |
| internal/operator-controller/resolve/catalog_test.go | Updates tests to stop setting spec.serviceAccount. |
| internal/operator-controller/labels/labels.go | Removes SA annotation keys previously used to record service account identity. |
| internal/operator-controller/features/features.go | Removes PreflightPermissions and SyntheticPermissions feature gates. |
| internal/operator-controller/controllers/suite_test.go | Adds envtest setup for VAP + warning capture utilities. |
| internal/operator-controller/controllers/revision_engine_factory.go | Removes SA-scoped client creation; uses base config client for revision engines. |
| internal/operator-controller/controllers/clusterobjectset_controller_test.go | Updates controller tests to remove SA annotations/fields and SA-scoped error scenarios. |
| internal/operator-controller/controllers/clusterobjectset_controller_internal_test.go | Updates internal controller tests to remove SA fields. |
| internal/operator-controller/controllers/clusterextension_reconcile_steps.go | Replaces SA existence validation with a deprecation log warning validator. |
| internal/operator-controller/controllers/clusterextension_controller.go | Adds a WithWatchesRawSource controller builder option. |
| internal/operator-controller/controllers/clusterextension_controller_test.go | Removes SA-related setup and validator tests. |
| internal/operator-controller/controllers/clusterextension_admission_test.go | Adds admission tests for deprecated spec.serviceAccount validation + VAP warning behavior. |
| internal/operator-controller/contentmanager/sourcerer.go | Removes old per-CE dynamic sourcerer implementation. |
| internal/operator-controller/contentmanager/source/internal/eventhandler.go | Removes copied controller-runtime event handler implementation. |
| internal/operator-controller/contentmanager/source/dynamicsource.go | Removes dynamic informer source implementation. |
| internal/operator-controller/contentmanager/source/dynamicsource_test.go | Removes tests for deleted dynamic source. |
| internal/operator-controller/contentmanager/contentmanager.go | Removes per-CE content manager and cache management layer. |
| internal/operator-controller/contentmanager/cache/cache.go | Removes managed-content cache implementation (watch lifecycle per CE). |
| internal/operator-controller/contentmanager/cache/cache_test.go | Removes tests for deleted cache implementation. |
| internal/operator-controller/authentication/tripper.go | Removes token-injecting round-tripper. |
| internal/operator-controller/authentication/tokengetter.go | Removes service-account token getter/cache. |
| internal/operator-controller/authentication/tokengetter_test.go | Removes tests for deleted token getter. |
| internal/operator-controller/authentication/synthetic.go | Removes synthetic impersonation utilities. |
| internal/operator-controller/authentication/synthetic_test.go | Removes tests for deleted synthetic impersonation utilities. |
| internal/operator-controller/applier/helm.go | Removes pre-auth; switches drift detection watch setup to shared tracking cache keyed by GVKs. |
| internal/operator-controller/applier/helm_test.go | Updates Helm applier tests to use mock tracking cache and drop pre-auth cases. |
| internal/operator-controller/applier/boxcutter.go | Removes SA annotations and pre-auth logic from Boxcutter path. |
| internal/operator-controller/applier/boxcutter_test.go | Updates Boxcutter tests to remove SA fields/annotations and pre-auth integration coverage. |
| internal/operator-controller/action/restconfig.go | Removes SA/synthetic rest config mappers. |
| internal/operator-controller/action/restconfig_test.go | Removes tests for deleted restconfig mappers. |
| helm/tilt.yaml | Removes PreflightPermissions from Tilt-enabled feature list. |
| helm/olmv1/values.yaml | Removes deprecated/removed feature gates from default values. |
| helm/olmv1/templates/validatingadmissionpolicybinding-clusterextension-serviceaccount-deprecated.yml | Adds chart template for VAP binding (Warn action). |
| helm/olmv1/templates/validatingadmissionpolicy-clusterextension-serviceaccount-deprecated.yml | Adds chart template for VAP that warns on deprecated serviceAccount usage. |
| helm/olmv1/templates/rbac/clusterrolebinding-operator-controller-manager-rolebinding.yml | Updates binding to reference cluster-admin. |
| helm/olmv1/templates/rbac/clusterrole-operator-controller-manager-role.yml | Removes operator-controller manager ClusterRole template. |
| helm/olmv1/base/operator-controller/crd/standard/olm.operatorframework.io_clusterextensions.yaml | Regenerates standard CRD with deprecation + optional serviceAccount semantics. |
| helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensions.yaml | Regenerates experimental CRD with deprecation + optional serviceAccount semantics. |
| helm/experimental.yaml | Removes removed feature gates from experimental values. |
| hack/tools/k8smaintainer/README.md | Removes docs for deleted k8s pinning tool. |
| hack/demo/synthetic-user-cluster-admin-demo-script.sh | Removes synthetic-user demo script tied to deleted features. |
| hack/demo/resources/synthetic-user-perms/cegroup-admin-binding.yaml | Removes synthetic-user demo RBAC. |
| hack/demo/resources/synthetic-user-perms/argocd-clusterextension.yaml | Removes synthetic-user demo ClusterExtension example. |
| go.sum | Removes checksums tied to dropped dependencies (notably k8s.io/kubernetes). |
| go.mod | Drops k8s.io/kubernetes and replace directives; adjusts dependency direct/indirect classification. |
| docs/draft/howto/use-synthetic-permissions.md | Removes draft docs for synthetic permissions feature. |
| docs/api-reference/olmv1-api-reference.md | Updates generated API reference to reflect deprecation + optional serviceAccount. |
| cmd/operator-controller/main.go | Removes SA/synthetic/preflight wiring; introduces global tracking cache and raw watch source; binds to cluster-admin via charts/manifests. |
| applyconfigurations/api/v1/serviceaccountreference.go | Updates generated apply config docs to mark deprecated type/field. |
| applyconfigurations/api/v1/clusterextensionspec.go | Updates generated apply config docs to mark deprecated field and remove SA semantics. |
| api/v1/validation_test.go | Updates validation test defaults to no longer require serviceAccount. |
| api/v1/clusterextension_types.go | Deprecates spec.serviceAccount, switches it to optional omitzero, and relaxes name validation to allow empty. |
| .claude/TODO-OCPSTRAT-3040.md | Adds internal tracking checklist for the epic work items. |
| .claude/memory/update-ocpstrat-3040-todo.md | Adds a memory instruction to keep the TODO checklist updated. |
| .claude/memory/MEMORY.md | Adds index entry for the new memory note. |
Files not reviewed (2)
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2770 +/- ##
==========================================
+ Coverage 70.42% 71.60% +1.17%
==========================================
Files 143 132 -11
Lines 10625 9403 -1222
==========================================
- Hits 7483 6733 -750
+ Misses 2580 2180 -400
+ Partials 562 490 -72
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 102 out of 106 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 103 out of 107 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 103 out of 107 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
This might cause problems in systems that perform upgrades without using our upstream install scripts. Perhaps a safer alternative would be to continue using our existing role, but changing its rules to match what |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 99 out of 103 changed files in this pull request and generated 3 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 99 out of 103 changed files in this pull request and generated no new comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 99 out of 103 changed files in this pull request and generated 1 comment.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
| name: operator-controller-cluster-admin-rolebinding | ||
| roleRef: | ||
| apiGroup: rbac.authorization.k8s.io | ||
| kind: ClusterRole | ||
| name: operator-controller-manager-role | ||
| name: cluster-admin |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 99 out of 103 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
| }) | ||
| if err != nil { | ||
| return nil, err | ||
| return nil, fmt.Errorf("failed to create client: %w", err) |
| app.kubernetes.io/name: operator-controller | ||
| {{- include "olmv1.labels" $ | nindent 4 }} | ||
| {{- if has "BoxcutterRuntime" .Values.options.operatorController.features.enabled }} | ||
| name: operator-controller-manager-admin-rolebinding | ||
| {{- else }} | ||
| name: operator-controller-manager-rolebinding | ||
| {{- end }} | ||
| name: operator-controller-cluster-admin-rolebinding | ||
| roleRef: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 97 out of 101 changed files in this pull request and generated 1 comment.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
| @@ -30,9 +28,15 @@ import ( | |||
| "github.com/operator-framework/operator-controller/internal/operator-controller/authorization" | |||
| "github.com/operator-framework/operator-controller/internal/operator-controller/contentmanager" | |||
| "github.com/operator-framework/operator-controller/internal/operator-controller/contentmanager/cache" | |||
| "github.com/operator-framework/operator-controller/internal/operator-controller/features" | |||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 97 out of 101 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" | ||
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable once set" |
| replace k8s.io/component-helpers => k8s.io/component-helpers v0.36.1 | ||
|
|
||
| replace k8s.io/controller-manager => k8s.io/controller-manager v0.36.1 | ||
|
|
||
| replace k8s.io/cri-api => k8s.io/cri-api v0.36.1 | ||
|
|
||
| replace k8s.io/cri-client => k8s.io/cri-client v0.36.1 | ||
|
|
||
| replace k8s.io/cri-streaming => k8s.io/cri-streaming v0.36.1 | ||
|
|
||
| replace k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.36.1 | ||
|
|
||
| replace k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.36.1 | ||
|
|
||
| replace k8s.io/endpointslice => k8s.io/endpointslice v0.36.1 | ||
|
|
||
| replace k8s.io/externaljwt => k8s.io/externaljwt v0.36.1 | ||
|
|
||
| replace k8s.io/kms => k8s.io/kms v0.36.1 | ||
|
|
||
| replace k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.36.1 | ||
|
|
||
| replace k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.36.1 | ||
|
|
||
| replace k8s.io/kube-proxy => k8s.io/kube-proxy v0.36.1 | ||
|
|
||
| replace k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.36.1 | ||
|
|
||
| replace k8s.io/kubectl => k8s.io/kubectl v0.36.1 |
Mark spec.serviceAccount as deprecated in the ClusterExtension API. Remove PreAuthorizer integration, SA-scoped RBAC templates, and restconfig action. Simplify the controller to use cluster-admin scope directly. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
…rning Create VAP and VAPB resources that emit a warning when spec.serviceAccount is set on a ClusterExtension. Add integration test infrastructure for warning collection. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
Remove SA-specific e2e test scenarios, SA RBAC templates, and the extension developer test suite. Simplify test steps to use cluster-admin scope. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
Delete authentication and authorization packages, feature gates, k8smaintainer tool, SA demo scripts, and documentation. Remove k8s.io/kubernetes dependency and unnecessary k8s staging replace directives. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
Delete the contentmanager package and replace it with boxcutter's shared TrackingCache. Simplify revision engine factory to use the base config directly. Remove SA label constants. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
Remove SA-related documentation, tutorials, and demo scripts. Clean up remaining ServiceAccount references from unit tests. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com>
…tect OLMv1 API access. Signed-off-by: Daniel Franz <dfranz@redhat.com> Co-Authored-By: Predrag Knezevic <pknezevi@redhat.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 98 out of 102 changed files in this pull request and generated 2 comments.
Files not reviewed (3)
- applyconfigurations/api/v1/clusterextensioninstallconfig.go: Generated file
- applyconfigurations/api/v1/clusterextensionspec.go: Generated file
- applyconfigurations/api/v1/serviceaccountreference.go: Generated file
| if h.TrackingCache == nil { | ||
| return true, "", fmt.Errorf("TrackingCache not initialized, cannot set up drift detection watches") | ||
| } | ||
|
|
||
| if err := cache.Watch(ctx, h.Watcher, relObjects...); err != nil { | ||
| klog.FromContext(ctx).Info("watching managed objects") | ||
| gvks := gvksForObjects(relObjects) |
| k8s.io/client-go v1.5.2 | ||
| k8s.io/component-base v0.36.2 | ||
| k8s.io/klog/v2 v2.140.0 | ||
| k8s.io/kubernetes v1.36.1 | ||
| k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 | ||
| pkg.package-operator.run/boxcutter v0.14.0 |
Description
Deprecate
spec.serviceAccounton ClusterExtension. OLMv1 is a single-tenant system where users with ClusterExtension write access are effectively delegated cluster-admin trust. With the service account field deprecated, operator-controller uses its own cluster-admin service account for all cluster interactions, eliminating the per-SA permission model and ~5,700 lines of supporting infrastructure.Changes
API deprecation:
spec.serviceAccountas deprecated withDeprecated:godoc convention andomitzerotagserviceAccountis setserviceAccount.nameimmutability rule to allow clearing the deprecated fieldRemove per-SA infrastructure:
authorization/package,authentication/package, SA-scoped config mappersk8s.io/kubernetesdependency and transitive replace directives from go.modhack/tools/k8smaintainer/andk8s-pinMakefile targetPreflightPermissionsandSyntheticPermissionsfeature gatesSimplify cache architecture:
contentmanager/package with sharedTrackingCachefrom boxcutter/managedcacheRestConfigMapperpatternE2E test cleanup:
serviceAccountfrom all feature files, add explicit namespace setup stepUpgrade safety:
Removed ~5,700 lines of unneeded code.
Reviewer Checklist