🐛 Fix namespace-scoped RBAC Role name conflicts with kustomize#1329
🐛 Fix namespace-scoped RBAC Role name conflicts with kustomize#1329camilamacedo86 wants to merge 1 commit intokubernetes-sigs:mainfrom
Conversation
When using namespace-scoped RBAC markers with different namespaces, controller-gen would generate multiple Roles with the same name in different namespaces. This caused kustomize to fail with "namespace transformation produces ID conflict" when applying a global namespace transformation, as both Roles would end up in the same namespace with identical names. Changes: - Append namespace to Role name for namespace-scoped Roles (e.g., "manager-role-infrastructure" for namespace "infrastructure") - ClusterRoles maintain original name without suffix - Updated documentation to clarify the naming behavior - Added test scenario covering the reported issue with different resource types in different namespaces (apps/deployments in infrastructure namespace, core/secrets in users namespace) This ensures uniqueness when kustomize transforms namespaces, preventing the ID conflict error.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: camilamacedo86 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
@sbueringer @JoelSpeed |
|
This feels like it could be breaking to me. Existing users will suddenly get a different RBAC file name, which if they blindly apply, means they'll end up with 2 roles per namespace now, with one redundant. Will the rolebindings get updated automatically? I'm guessing not, so then they'd be stuck on an older role that is no longer being updated/maintained. Is it possible to add a name parameter to the RBAC generation? That way, folks would instead be able to choose their own names, rather than relying on generated names, and then they can control this themselves, deliberately, rather than us deciding to add a namespace to the name? |
|
Hi @JoelSpeed If the user use namespace we have a duplication and that does not work well with kustomize See: The ProblemWhen using namespace-scoped RBAC markers with different namespaces, controller-gen generated multiple Roles with duplicate names in different namespaces. This caused kustomize to fail with a "namespace transformation produces ID conflict" error. Test ScenarioUsing these RBAC markers in a controller: // +kubebuilder:rbac:groups=apps,namespace=infrastructure,resources=deployments,verbs=get;list;watch;update;patch
// +kubebuilder:rbac:groups="",namespace=users,resources=secrets,verbs=get;list;watchBEFORE Fix: Duplicate Role Names ❌Generated YAML---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role # ← DUPLICATE NAME
namespace: infrastructure
rules:
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role # ← DUPLICATE NAME
namespace: users
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watchAfter Kustomize Namespace TransformationWhen using # config/default/kustomization.yaml
namespace: myproject-systemResult: CONFLICT! ❌ ---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role # ← SAME NAME
namespace: myproject-system # ← SAME NAMESPACE
rules:
- apiGroups:
- apps
resources:
- deployments
verbs: [get, list, patch, update, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role # ← SAME NAME
namespace: myproject-system # ← SAME NAMESPACE
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, list, watch]Kustomize ErrorTwo Roles with identical (kind, name, namespace) = CONFLICT! AFTER Fix: Unique Role Names ✅Generated YAML---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role-infrastructure # ← UNIQUE NAME (namespace suffix)
namespace: infrastructure
rules:
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role-users # ← UNIQUE NAME (namespace suffix)
namespace: users
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watchAfter Kustomize Namespace TransformationWith the same global namespace transformation: # config/default/kustomization.yaml
namespace: myproject-systemResult: NO CONFLICT! ✅ ---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role-infrastructure # ← UNIQUE NAME
namespace: myproject-system
rules:
- apiGroups:
- apps
resources:
- deployments
verbs: [get, list, patch, update, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: manager-role-users # ← UNIQUE NAME
namespace: myproject-system
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, list, watch]Kustomize Success$ kustomize build config/default | kubectl apply -f -
role.rbac.authorization.k8s.io/manager-role-infrastructure created
role.rbac.authorization.k8s.io/manager-role-users createdEach Role has a unique name - no conflict! ✅ |
| // The generated Role name will be suffixed with the namespace (e.g., "manager-role-namespace") | ||
| // to ensure uniqueness when multiple namespace-scoped Roles are generated. This suffix is | ||
| // ONLY applied to namespace-scoped Roles, not to ClusterRoles. | ||
| Namespace string `marker:",optional"` |
There was a problem hiding this comment.
Won't this break everyone using this part of controller-gen today?
There was a problem hiding this comment.
The change shouldn’t break anything functionally. The RBAC files will still be re-generated; the only delta is the Role name. If someone is currently using namespace-scoped RBAC, the generated Role will now include a namespace suffix.
Honestly, I think this is a very rare use case. If the marker-based namespace RBAC generation were common, we likely would have seen this reported earlier—this is the first time it’s come up. ( it cannot work with kustomize/kubebuilder and nobody raised the issue before )
In this case we’re only changing the resource name. The main way this could “break” someone is if they have external tooling or scripts that reference the old Role name by string (e.g., CI checks, dashboards, custom automation). Otherwise, I think it should be very unlikely to cause issues.
There was a problem hiding this comment.
Wouldn't it lead to duplicate objects if folks still have roles with the old name around and now the name changes?
I'm not sure if we can assume that the files generated by controller-gen are always consumed by kustomize
Generally speaking Roles are usually referenced by name by RoleBindings
There was a problem hiding this comment.
I agree we can’t assume controller-gen output is always consumed by Kustomize. That said, I think the most common adoption path is still Kubebuilder/Operator SDK + Kustomize, where controller-gen is part of the standard workflow.
Also, I don’t think the namespace= RBAC marker is used very often (which may explain why this wasn’t caught earlier). GitHub search suggests ~1.7k usages of namespace= vs ~48.1k total RBAC marker usages:
- https://github.com/search?q=%22%2Bkubebuilder%3Arbac%3A%22+namespace%3D+language%3AGo&type=code&l=Go
- https://github.com/search?q=%22%2Bkubebuilder%3Arbac%3A%22++language%3AGo&type=code
Given that context, expecting generated resources to have unique names seems reasonable. The key question for me is:
1. How do we ensure controller-gen never generates two resources with the same name here?
2. IMO, generating duplicate resource names is a bug.
What’s your suggested fix?
If a breaking change isn’t acceptable even to fix a bug, what alternative do you propose? Should we introduce a new marker resource name? What would to be acceptable?
PS: There are 23k+ refs using the latest Kubebuilder layouts (which promote controller-gen) based on go.kubebuilder.io references:
https://github.com/search?q=go.kubebuilder.io&type=code
There was a problem hiding this comment.
I've opened an alternative PR that addresses the breaking change concerns raised here: #1334
Instead of automatically appending namespace suffixes, my approach adds an optional roleName parameter to the RBAC marker:
// +kubebuilder:rbac:groups=apps,namespace=infrastructure,roleName=infra-manager,resources=deployments,verbs=get;list
// +kubebuilder:rbac:groups="",namespace=users,roleName=user-secrets,resources=secrets,verbs=getThere was a problem hiding this comment.
Makes sense. Thx for looking into how this can be done without a breaking change
There was a problem hiding this comment.
Thanks for the review!
Allows users to specify custom role names per marker to avoid name conflicts when using namespace-scoped RBAC across multiple namespaces. Key features: - Optional roleName parameter in RBAC marker - Non-breaking: defaults to --roleName flag if not specified - Useful for avoiding kustomize namespace transformation conflicts - Multiple markers with same roleName in same namespace are merged Example usage: // +kubebuilder:rbac:groups=apps,namespace=infrastructure,roleName=infra-manager,resources=deployments,verbs=get;list // +kubebuilder:rbac:groups="",namespace=users,roleName=user-secrets,resources=secrets,verbs=get This addresses the issue raised in kubernetes-sigs/kubebuilder#5148 where namespace-scoped Roles with the same name in different namespaces cause kustomize namespace transformation ID conflict errors. Unlike PR kubernetes-sigs#1329 (automatic namespace suffix), this approach: - Is opt-in (non-breaking for existing users) - Gives users explicit control over Role names - Works for any use case, not just kustomize - Avoids breaking changes and migration issues
|
#1334 has been merged, I think we can close this one? |
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
Closing in favour of the PR that adds the roleName |
When using namespace-scoped RBAC markers with different namespaces, controller-gen would generate multiple Roles with the same name in different namespaces. This caused kustomize to fail with "namespace transformation produces ID conflict" when applying a global namespace transformation, as both Roles would end up in the same namespace with identical names. More info: kubernetes-sigs/kubebuilder#5148 (comment)
Changes:
This ensures uniqueness when kustomize transforms namespaces, preventing the ID conflict error.