Skip to content

Instantly share code, notes, and snippets.

@sttts
Created January 24, 2025 09:16
Show Gist options
  • Save sttts/173074350fc3a738d4457d256e9e6f3d to your computer and use it in GitHub Desktop.
Save sttts/173074350fc3a738d4457d256e9e6f3d to your computer and use it in GitHub Desktop.
diff --git a/pkg/registry/rbac/validation/kcp.go b/pkg/registry/rbac/validation/kcp.go
index 6695bcb42e9..6fdab0846cf 100644
--- a/pkg/registry/rbac/validation/kcp.go
+++ b/pkg/registry/rbac/validation/kcp.go
@@ -2,6 +2,7 @@ package validation
import (
"context"
+ "fmt"
"strings"
"github.com/kcp-dev/logicalcluster/v3"
@@ -34,8 +35,7 @@ var appliesToUserWithScopes = withScopes(appliesToUser)
// withScopes wraps the appliesToUser predicate to check for the base user and any warrants.
func withScopes(appliesToUser appliesToUserFunc) appliesToUserFuncCtx {
- var recursive appliesToUserFuncCtx
- recursive = func(ctx context.Context, u user.Info, bindingSubject rbacv1.Subject, namespace string) bool {
+ return func(ctx context.Context, u user.Info, bindingSubject rbacv1.Subject, namespace string) bool {
var clusterName logicalcluster.Name
if cluster := genericapirequest.ClusterFrom(ctx); cluster != nil {
clusterName = cluster.Name
@@ -43,13 +43,23 @@ func withScopes(appliesToUser appliesToUserFunc) appliesToUserFuncCtx {
if IsInScope(u, clusterName) && appliesToUser(u, bindingSubject, namespace) {
return true
}
+ if IsServiceAccount(u) {
+ nsNameSuffix := strings.TrimPrefix(u.GetName(), "system:serviceaccount:")
+ rewritten := &user.DefaultInfo{
+ Name: fmt.Sprintf("system:kcp:serviceaccount:%s:%s", clusterName, nsNameSuffix),
+ Groups: []string{user.AllAuthenticated},
+ Extra: u.GetExtra(),
+ }
+ if appliesToUser(rewritten, bindingSubject, namespace) {
+ return true
+ }
+ }
if appliesToUser(scopeDown(u), bindingSubject, namespace) {
return true
}
return false
}
- return recursive
}
var (
diff --git a/pkg/registry/rbac/validation/kcp_test.go b/pkg/registry/rbac/validation/kcp_test.go
index 9142fc6f69d..1bafd3a6148 100644
--- a/pkg/registry/rbac/validation/kcp_test.go
+++ b/pkg/registry/rbac/validation/kcp_test.go
@@ -220,6 +220,18 @@ func TestAppliesToUserWithScopes(t *testing.T) {
sub: rbacv1.Subject{Kind: "ServiceAccount", Namespace: "ns", Name: "sa"},
want: false,
},
+ {
+ name: "service account with cluster as global kcp service account",
+ user: &user.DefaultInfo{Name: "system:serviceaccount:ns:sa", Extra: map[string][]string{"authentication.kubernetes.io/cluster-name": {"this"}}},
+ sub: rbacv1.Subject{Kind: "User", Name: "system:kcp:serviceaccount:this:ns:sa"},
+ want: true,
+ },
+ {
+ name: "service account with scope as global kcp service account",
+ user: &user.DefaultInfo{Name: "system:serviceaccount:ns:sa", Extra: map[string][]string{"authentication.kcp.io/scopes": {"cluster:this"}}},
+ sub: rbacv1.Subject{Kind: "User", Name: "system:kcp:serviceaccount:this:ns:sa"},
+ want: true,
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment