feat: let a Workspace bind Roles to its ServiceAccount, gated by a SubjectAccessReview - #1337
Open
Jefftree wants to merge 1 commit into
Open
feat: let a Workspace bind Roles to its ServiceAccount, gated by a SubjectAccessReview#1337Jefftree wants to merge 1 commit into
Jefftree wants to merge 1 commit into
Conversation
…bjectAccessReview Signed-off-by: Jefftree <jeffrey.ying86@live.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 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 |
10 tasks
7 tasks
Member
|
/ok-to-test |
Jefftree
marked this pull request as ready for review
August 25, 2026 14:52
10 tasks
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.
What this PR does
Adds
Workspace.spec.podTemplate.serviceAccount.roles[]. Each entry becomes a namespaced RoleBinding from the Workspace's controller-owned ServiceAccount to a Role of that name. Changing the list is gated by a SubjectAccessReview in the Workspace webhook:createrolebindings to add an entry,deleteto remove one.Implements rows 1 and 2 of the authorization table in #1257.
Kubernetes prevents privilege escalation through RoleBinding in the REST storage layer, and skips that check when the creator holds
bindon the referenced role. The controller must holdbindcluster-wide, since it binds roles whose permissions it does not itself hold, so the native check never fires for our bindings. The SAR is what replaces it.Decisions
bindon it. The first needs the API server's rule resolver, which a webhook cannot reach. The second is just another SAR, but neither the defaultadminnorkubeflow-adminholdsbind, so requiring it would lock out the intended user until an admin grants it.delete rolebindings, per the issue. Note this gates de-escalation, and deleting the Workspace drops the bindings with no check at all, so a caller withcreatebut notdeletecan add a Role and never remove it.kindfield onroles[], per the issue. The reconciler is already keyed on(kind, name), so the API is the only thing that would change if we ever want per-Workspace ClusterRoles.(workspace, kind, role). Without the kind, a Role and a ClusterRole of the same name collide onto one RoleBinding and the reconciler flaps between tworoleRefvalues.spec.podTemplate.serviceAccountacross PUT.ApplyWorkspaceUpdateModelToWorkspacerebuildsspec.podTemplatewholesale, so without this the field is wiped on every backend update. Inverting that function to assign field by field would make preserve the default, but that is a bigger change than belongs here.Known gaps
can-use=truelabel gate on Roles, lands with the backend API surface. The issue describes it as consistent with StorageClasses and Secrets, but this codebase gates StorageClasses withcan-useand Secrets withcan-mount, so that needs settling.reconcileRoleBindingsruns last inReconcile, after eleven paths that can return early, so a Workspace stuck inErrorkeeps its bindings after a Role is removed from the spec. Pre-existing, worth a separate fix.Testing
Controller and backend
make testandmake lintpass, no generated drift. New coverage: webhook allow and deny paths for add and remove against real non-admin identities, RoleBinding creation and deletion per entry, Role and ClusterRole name separation, and one test that creates a real Role, binds it, and confirms with a SubjectAccessReview that the ServiceAccount gains and then loses the permission.