Mirror the new RBAC UI role grants onto rbacsync's ClusterRole (EV-6977) - #5234
Draft
dimitri-nicolo wants to merge 5 commits into
Draft
Mirror the new RBAC UI role grants onto rbacsync's ClusterRole (EV-6977)#5234dimitri-nicolo wants to merge 5 commits into
dimitri-nicolo wants to merge 5 commits into
Conversation
calico-private adds resources to the managed calico-ui-* role catalogue to close gaps against what tigera-ui-user and tigera-network-admin ship. Kubernetes' privilege-escalation guard only lets calico-kube-controllers create a ClusterRole granting permissions it already holds, so every one of those grants has to be mirrored in rbacSyncControllerRules() or the create is rejected. The failure would not be partial: the rbacsync controller ensures cluster-context first and returns on error, so the gatewayapis grant alone would abort the whole sync cycle, tier and LMA roles included. Added: - operator.tigera.io/gatewayapis, joining the feature-enabled checks. - The six applicationlayer.projectcalico.org WAF resources, and gateways/httproutes as their attach targets. - apps/deployments, which the WAF configuration page displays. The base rules grant apps/daemonsets scoped to calico-node only. - The three policy.networking.k8s.io admin network policy resources. - networks with the modify verbs. The common rules already grant it watch/list/get for the node controller's IPAM syncer, which is not enough for the egress-gateways modify role. - securityeventwebhooks under crd.projectcalico.org as well as projectcalico.org, moved to its own rule now that it spans two groups. The WAF and Gateway API rules already exist in KubeControllersEnterpriseCommonRules via wafRules(), but gated on the GatewayAPI CR being present. rbacsync needs them whenever RBAC management is enabled, so they are repeated here rather than relying on that gate — otherwise the managed WAF roles are creatable on Gateway API clusters and rejected everywhere else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
projectcalico/calico master added CEL validation rules to the IPPool CRD after the last sync, so validate-gen-versions' dirty-check fails on every PR until the copies under pkg/imports/crds/calico are refreshed. Same content the CI regen produces; no operator code change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The IPPool CRD synced from projectcalico/calico master carries CEL
validation rules whose estimated cost the k8s 1.31 apiserver rejects
("estimated rule cost exceeds budget by factor of more than 100x");
1.33 accepts them, and upstream calico CI applies the same CRDs on
kindest v1.35.5. Verified against real apiservers: kindest/node v1.33.0
accepts both IPPool CRD flavors and boots with the kind v0.31.0 binary
this repo pins in go.mod, while v1.31.4 reproduces the rejection.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The managed webhooks role writes securityeventwebhooks through the aggregated projectcalico.org API only and reads the CRD group behind it, so the escalation guard needs the write verbs on the aggregated group and reads on the CRD group. Granting write on both handed kube-controllers privilege the catalogue never passes on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
calico-ui-waf-mod now patches a deployment's pod template to toggle sidecar WAF (calico-private EV-6977), so the escalation guard requires the rbacsync controller to hold apps/deployments patch itself, or creating and repairing that role is rejected. Nothing else grants it: the base rules cover apps/daemonsets only, scoped to calico-node, and the migration role is read-only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
@electricjesus there's one decision here I'd like you to sign off on. The WAF grants from wafRules() are repeated in rbacSyncControllerRules() without the GatewayAPI gate, because rbacsync needs them whenever RBAC management is enabled. As a result, kube-controllers can patch any Deployment in the cluster while the feature is on. That is what lets it create the calico-ui-waf-mod role, which grants the same verb for the sidecar WAF toggle (see tigera/calico-private#13388). Let me know if that's too broad for this service account. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Companion to calico-private#13388 (EV-6977). That PR cannot merge until this one does — draft until it has been reviewed alongside it.
calico-private adds resources to the managed
calico-ui-*role catalogue to close gaps against whattigera-ui-userandtigera-network-adminalready ship. Kubernetes' privilege-escalation guard only letscalico-kube-controllerscreate a ClusterRole granting permissions it already holds, so each of those grants has to be mirrored inrbacSyncControllerRules()— which is exactly what that function exists for, per its own doc comment.The failure without this change is not partial. The rbacsync controller ensures
cluster-contextfirst and returns on error, so thegatewayapisgrant alone would abort the whole sync cycle — tier roles and LMA roles included — with a forbidden error on every tick.What's added
operator.tigera.io/gatewayapisgetcalico-ui-cluster-contextapplicationlayer.projectcalico.org(6 WAF resources)calico-ui-waf-{view,mod}gateway.networking.k8s.io/gateways,httproutesget,list,watchcalico-ui-waf-{view,mod}apps/deploymentsget,list,watchcalico-ui-waf-{view,mod}policy.networking.k8s.io(3 resources)calico-ui-admin-network-policies-{view,mod}projectcalico.org/networkscalico-ui-egress-gateways-modprojectcalico.org/securityeventwebhookscalico-ui-webhooks-{view,mod}crd.projectcalico.org/securityeventwebhooksget,list,watchcalico-ui-webhooks-{view,mod}Two of these deserve a second look:
networksis already grantedwatch,list,getby the common rules, for the node controller's IPAM syncer. The egress-gateways modify role writes it, so the read-only grant does not clear the guard. It joins the existingprojectcalico.orgCRUD rule next toexternalnetworks.KubeControllersEnterpriseCommonRulesviawafRules()— but gated ongatewayAPIPresent. rbacsync needs them whenever RBAC management is enabled, independent of whether the GatewayAPI CR exists, so they are repeated inrbacSyncControllerRules()rather than leaning on that gate. Without that, the managed WAF roles would be creatable on Gateway API clusters and rejected by the escalation guard everywhere else. Open to instead widening thewafRules()gate togatewayAPIPresent || rbacManagementEnabledif that reads better — it trades the duplication for a wider blast radius.securityeventwebhooksmoves out of theprojectcalico.org-only list into its own rules now that it spans two API groups. The two groups are granted asymmetrically, mirroring the catalogue: the managed role writes through the aggregatedprojectcalico.orgAPI, which validates the object, and only reads the CRD group behind it, so the escalation guard needs write on the former and reads on the latter. A test fails if the CRD group regains the write verbs.Not needed, already held:
configmaps(common rules),servicesincludingwatch(base rules grantget,list,update,watch), and the three newlma.tigera.ioresource names (the existinglma.tigera.io/cluster getrule is unscoped by resource name).Testing
DescribeTableasserting each new grant is present on the renderedcalico-kube-controllersClusterRole when the gate is on, one entry per resource.networkscarries the modify verbs specifically, not just the IPAM syncer's reads.policy.networking.k8s.io— granted by nothing else in the role — is absent when the feature is off.gatewayapisandnetworksadditions; both fail as intended.go test ./pkg/enterprise/...passes.Affects Calico Enterprise only, and only when RBAC management is enabled.
Release Note
For PR author
make gen-filesmake gen-versions