List safe subresources instead of sensitive ones - #25
Open
Artem Kolomeetc (arxhive) wants to merge 1 commit into
Open
List safe subresources instead of sensitive ones#25Artem Kolomeetc (arxhive) wants to merge 1 commit into
Artem Kolomeetc (arxhive) wants to merge 1 commit into
Conversation
The subresource handling in getResourceAndAction listed the subresources that must keep their own DataAction and collapsed everything else into the parent resource action. That default is wrong way round: any subresource nobody has classified yet - including ones added by later Kubernetes versions, by CRDs or by aggregated API servers - is silently covered by the parent resource permission, and the list has to be extended every time a new one is noticed. Invert it. Collapse only the subresources that upstream Kubernetes treats as part of the parent resource's permission - the read-only view ClusterRole grants pods/log, pods/status and the /status and /scale subresources alongside their parent - and give every other subresource its own "<resource>/<subresource>/action" DataAction. Wildcard requests and the special verbs (bind, escalate, use, impersonate) keep their existing mapping: for those the verb, not the subresource, identifies the operation being authorized. Signed-off-by: Artem Kolomeetc <akolomeetc@microsoft.com>
Artem Kolomeetc (arxhive)
requested
a lite review from Copilot
and removed request for
Copilot
August 12, 2026 07:27
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.
Follow-up to #22, addressing Mo Khan (@enj)'s review comment: #22 (comment)
Why
getResourceAndActionlisted the subresources that must keep their own DataAction and collapsed everything else into the parent resource action. That default is the wrong way round - a subresource nobody has classified yet is silently covered by the parent resource's permission, so the list has to grow every time someone notices a new one. That list has in fact grown three times (exec, thennodeclient, thenproxy, thenattach/portforward), each time after the gap was found rather than before.What changed
Collapse only the subresources upstream treats as part of the parent resource's permission, and give every other subresource its own
<resource>/<subresource>/action.The safe set is taken from the upstream
viewClusterRole (bootstrappolicy.viewRules), which grants exactly these subresource kinds alongside their parent:status,scale, andpods/log. SosafeSubresources = {status, scale, log, logs}(logsbecause guard has historically seen the plural spelling).Unchanged by design:
*resource/subresource/verb) - expanded from the operations map elsewhere.bind,escalate,use,impersonate,inference) - there the verb, not the subresource, identifies the operation, souserextras/scopes+impersonatestaysuserextras/impersonate/action.Behavioral impact - please review
Anything not on the safe list now resolves to
<resource>/<subresource>/action. TheMicrosoft.ContainerServiceoperations registry currently defines onlymanagedClusters/pods/{read,write,delete}andmanagedClusters/pods/exec/action, so these actions match only roles carrying a wildcard (managedClusters/*,pods/*) and are denied for roles that enumerate leaf actions. That is the intended fail-closed direction, but it is a behavioral change.Two points that need an explicit decision:
certificatesigningrequests/approvaland/approvalsno longer collapse into the parent write/delete, and the same rule would apply to/nodeclient. Revert "fix: CSR subresource action collapse allowing unauthorized kubelet certificate issuance"聽#23 reverted fix: CSR subresource action collapse allowing unauthorized kubelet certificate issuance聽#12, which had gatednodeclient, so this rule partially re-applies what that revert removed. If CSR should stay collapsed until the corresponding DataActions exist in the registry, say so and I will add the CSR subresources to the safe set explicitly.safeSubresourcesrather than discovered through a denial.Testing
go build ./...,gofmt -l,golangci-lint runinghcr.io/appscode/golang-dev:1.25- 0 issuesgo test ./authz/providers/azure/rbac/... ./auth/providers/azure/graph/...- all passstatus/log/scalecollapsing, an unclassified subresource getting its own action (the fail-closed default), and the existing exec/attach/portforward/proxy and special-verb cases.