reject user operations on rancher-managed resource quota and limit range resources - #1757
reject user operations on rancher-managed resource quota and limit range resources#1757andreas-kupries with Copilot wants to merge 6 commits into
Conversation
The spec.hard should actually be less than the namespace's quota annotation, which is the origin for the resourcequota resource itself.
See above, this feels bogus.
|
andreas-kupries
left a comment
There was a problem hiding this comment.
Given the rancher-webhook-sudo bypass I wonder if we can simply reject anything with the marker label. Will have to verify that rancher resource quota code always uses the bypass for its own quota resource, i.e. that the validator will never see any ops for the NRQR. Best done using a local setup, with logging in the webhook, and no rejections during that test
| } | ||
|
|
||
| // Both objects have the marker label: validate that the new limits do not exceed the project quota. | ||
| return a.validateAgainstProjectQuota(newRQ) |
There was a problem hiding this comment.
validate against the namespace annotation!?
|
Setting things up locally and using an always-accept validator for inspection I find that the rancher backend does not use the To make this PR suitable rancher's RQ operations have to be modified to use the bypass. @JonCrowther As the person who worked most recently on GR and RT, is my reasoning above sensible ? If yes, where in the GR/RT code would I find the setup of the webhook bypass ? |
e2d2fff to
146652e
Compare
There was a problem hiding this comment.
Pull request overview
Adds validating webhooks to protect Rancher-managed ResourceQuota and LimitRange objects from user modifications.
Changes:
- Registers validators for create, update, and delete operations.
- Adds marker-label enforcement with Rancher bypass support.
- Adds generated decoders, tests, documentation, and effective setting validation.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Reviewed changes | Final comments |
|---|---|---|
pkg/server/handlers.go |
Registers validators. | No final comments. |
pkg/resources/management.cattle.io/v3/setting/validator.go |
Validates effective setting values. | moderate (2 votes): Add cases covering empty Value with valid and invalid Default values. |
pkg/resources/core/v1/resourcequota/validator.go |
Validates managed ResourceQuota operations. |
moderate (2 votes): Correct the update-promotion message that incorrectly says the resource is being created (lines 102 and 106). |
pkg/resources/core/v1/resourcequota/validator_test.go |
Tests ResourceQuota validation. |
nit (3 votes): Rename unmnaged to unmanaged. |
pkg/resources/core/v1/resourcequota/Resourcequota.md |
Documents ResourceQuota validation. |
No final comments. |
pkg/resources/core/v1/limitrange/validator.go |
Validates managed LimitRange operations. |
moderate (2 votes): Correct the update-promotion message that incorrectly says the resource is being created (lines 103 and 106). |
pkg/resources/core/v1/limitrange/validator_test.go |
Tests LimitRange validation. |
nit (3 votes): Rename unmnaged to unmanaged. |
pkg/resources/core/v1/limitrange/Limitrange.md |
Documents LimitRange validation. |
No final comments. |
pkg/generated/objects/core/v1/objects.go |
Adds generated object decoders. | No final comments. |
pkg/codegen/main.go |
Includes new core types in code generation. | No final comments. |
docs.md |
Updates generated documentation. | No final comments. |
Suppressed comments (5)
pkg/resources/core/v1/limitrange/Limitrange.md:1
- The filename uses
Limitrange, but the Kubernetes API type isLimitRange. The docs generator uses the markdown filename as the resource heading (pkg/codegen/docs.go:64,124), so this typo propagates intodocs.md; rename this file toLimitRange.mdand regenerate the aggregate documentation.
## Validation Checks
pkg/resources/core/v1/limitrange/validator.go:110
- The namespace controller deletes namespaced contents with
DELETECOLLECTION, and Kubernetes runs the delete admission callback for each old object assystem:serviceaccount:kube-system:namespace-controller. That identity is not the Rancher bypass, so a managed LimitRange hits this branch and is rejected, leaving its namespace stuck inTerminating. Exempt that system cleanup path while keeping direct user deletes denied.
case admissionv1.Delete:
if hasMarkerLabel(oldRq) {
// Reject the user's attempt to delete the
// rancher-managed quota resource
return admission.ResponseBadRequest(
pkg/resources/core/v1/resourcequota/Resourcequota.md:1
- The filename uses
Resourcequota, but the Kubernetes API type isResourceQuota. The docs generator uses the markdown filename as the resource heading (pkg/codegen/docs.go:64,124), so this typo propagates intodocs.md; rename this file toResourceQuota.mdand regenerate the aggregate documentation.
## Validation Checks
pkg/resources/core/v1/resourcequota/validator.go:110
- The namespace controller deletes namespaced contents with
DELETECOLLECTION, and Kubernetes runs the delete admission callback for each old object assystem:serviceaccount:kube-system:namespace-controller. That identity is not the Rancher bypass, so a managed quota hits this branch and is rejected, leaving its namespace stuck inTerminating. Exempt that system cleanup path while keeping direct user deletes denied.
if hasMarkerLabel(oldRq) {
// Reject the user's attempt to delete the
// rancher-managed quota resource
return admission.ResponseBadRequest(
"users are forbidden from deleting resources managed by Rancher",
pkg/resources/management.cattle.io/v3/setting/validator.go:379
- Now that this validation uses
effectiveValue(s), an object with an empty Value and an invalid Default is rejected, but the error still reportss.Value(the empty string) rather than the value that was parsed. Use a local effective value for both parsing and the reported bad value.
if _, err := time.ParseDuration(effectiveValue(s) + "s"); err != nil {
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
….github.com> boilerplate from copilot still present. unit tests and checks completely rewritten added validators for resource quota to webhook added docs, extended webhook codegen the new validator rejects creation, edition, deletion of rancher managed resources. the new validator further rejects promotion of unmanaged to managed resource, and vice versa. the managed resource is recognized by its marker label. the validator is written with the assumption that rancher requests are tagged with webhook bypass and therefore do not reach the validator. unit tests. all of the above for limit range resources as well.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2b159f5 to
e6d91a5
Compare
|
note to self:
trial |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
pkg/resources/management.cattle.io/v3/setting/validator.go:379
- The
auth-user-info-max-age-secondstests always populatenewSetting.Value, so they never exercise the neweffectiveValuefallback toDefault. Please add create/update cases with a valid and invalid default (whileValueis empty) to verify the behavior this change introduces and prevent regressions.
toValidate := effectiveValue(s)
| ), nil | ||
| } | ||
| case admissionv1.Delete: | ||
| if hasMarkerLabel(oldRq) { |
| } | ||
| case admissionv1.Delete: | ||
| if hasMarkerLabel(oldRq) { | ||
| // Reject the user's attempt to delete the |
Issue:
rancher/rancher#54690
Companion PR r/rancher rancher/rancher#56780
backport 2.15.2 rancher/rancher#56773 - PR rancher/rancher#56801 - PR webhook 0.11 #1797
backport 2.14.6 rancher/rancher#56774 - PR rancher/rancher#56804 - PR webhook 0.10 #1798
Problem
The NRQR (Rancher-managed namespace
ResourceQuota, identified by labelresourcequota.management.cattle.io/default-resource-quota: true) was enforced only at namespace creation time. Any user with RBAC access toresourcequotascould subsequently edit the object directly, fully bypassing project-level enforcement.The same is true for the LimitRange resource managed by Rancher.
Solution
Added validating webhooks for
ResourceQuotaandLimitRangeobjects.The companion PR modifies Rancher to send its requests using the webhook bypass.
This means that the new validators see only user initiated requests, and only have to reject operations involving the marker label. IOW