From 90660862fe51de44de863b2c91fc64ed9b8de302 Mon Sep 17 00:00:00 2001 From: Arnob Kumar Saha Date: Sun, 26 Jul 2026 22:53:25 +0600 Subject: [PATCH 1/3] Update kmodules.xyz/client-go Picks up the ACE-extras allowlist in DelegatingClient.Impersonate (kmodules/client-go#645). Signed-off-by: Arnob Kumar Saha --- go.mod | 2 +- go.sum | 4 +-- vendor/kmodules.xyz/client-go/Makefile | 2 +- .../client-go/client/delegated.go | 29 +++++++++++++++++-- vendor/modules.txt | 4 +-- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 1a686b3acd..66a8b48aec 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 kmodules.xyz/apiversion v0.2.0 kmodules.xyz/authorizer v0.34.0 - kmodules.xyz/client-go v0.34.5 + kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a kmodules.xyz/custom-resources v0.34.0 kmodules.xyz/go-containerregistry v0.0.15 kmodules.xyz/monitoring-agent-api v0.34.3 diff --git a/go.sum b/go.sum index cfce917a4e..33cd4ef670 100644 --- a/go.sum +++ b/go.sum @@ -1175,8 +1175,8 @@ kmodules.xyz/apply v0.34.0 h1:n6kAuHKAg3uzrlJccaAhjq/O4DdeiKqig9ElzoBXfzU= kmodules.xyz/apply v0.34.0/go.mod h1:V8B55uphISoKUHWAfyntveZFEkey6WxVP3cnXOvX4eY= kmodules.xyz/authorizer v0.34.0 h1:WEDyKac9u/xmYkdrVtZqUTk4x0+8T8FYPslf3O8cNfU= kmodules.xyz/authorizer v0.34.0/go.mod h1:b/aqy4e81jp/Nz0hfmOSHLr1+qUMJ0y6YMkEZ2PtoRo= -kmodules.xyz/client-go v0.34.5 h1:mzhSQxKwGDXcEiUtABwqTNu5tVc3KsKc53foW5PHbT0= -kmodules.xyz/client-go v0.34.5/go.mod h1:myCt7AfRao4PBdUtKXu01xxbqqmLZ5U8fW0LQDaifhQ= +kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a h1:GsSi2+cC6EG8FCkzk4YwpmtqMZUvTLUf2XfkAgsA918= +kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a/go.mod h1:TGfM3P0jfFJUoVii8DTNE4An/E5mN9BRhddHDUb0zZY= kmodules.xyz/crd-schema-fuzz v0.34.1 h1:YfrFv9LcrVW54BhFSekFAyEuWxp09wic1j8xm3c41T0= kmodules.xyz/crd-schema-fuzz v0.34.1/go.mod h1:uer6PA1mrDk4SI6C+kZ2vNZFPZhHvgahuf+YRVKQiHo= kmodules.xyz/custom-resources v0.34.0 h1:ljkIYzIq0A3Awj87kkpuYqS9aifuyR3Hr9q2OVKoojM= diff --git a/vendor/kmodules.xyz/client-go/Makefile b/vendor/kmodules.xyz/client-go/Makefile index 0d1f72430c..1dc8b973ae 100644 --- a/vendor/kmodules.xyz/client-go/Makefile +++ b/vendor/kmodules.xyz/client-go/Makefile @@ -23,7 +23,7 @@ CODE_GENERATOR_IMAGE ?= ghcr.io/appscode/gengo:release-1.32 # This version-strategy uses git tags to set the version string git_branch := $(shell git rev-parse --abbrev-ref HEAD) -git_tag := $(shell git describe --exact-match --abbrev=0 2>/dev/null || echo "") +git_tag := $(shell git describe --tags --exact-match --abbrev=0 2>/dev/null || echo "") commit_hash := $(shell git rev-parse --verify HEAD) commit_timestamp := $(shell date --date="@$$(git show -s --format=%ct)" --utc +%FT%T) diff --git a/vendor/kmodules.xyz/client-go/client/delegated.go b/vendor/kmodules.xyz/client-go/client/delegated.go index 6a4c4eca76..b1a1364e96 100644 --- a/vendor/kmodules.xyz/client-go/client/delegated.go +++ b/vendor/kmodules.xyz/client-go/client/delegated.go @@ -100,13 +100,38 @@ func (d *DelegatingClient) RestConfig() *restclient.Config { return d.config } +// aceExtraPrefix is the only extra-key namespace impersonated identities carry +// through. See impersonableExtra. +const aceExtraPrefix = "ace.appscode.com/" + +// impersonableExtra keeps only the ACE extras. Every other extra key is provider +// bookkeeping injected by the apiserver or the platform -- Rancher's principalid, +// EKS' arn, the reserved authentication.kubernetes.io/* keys -- and impersonating +// any of them needs an `impersonate` grant on userextras/ that callers do not +// hold, which fails the whole request during impersonation authorization. RBAC +// ignores extras, so dropping them changes no authorization decision. +func impersonableExtra(in map[string][]string) map[string][]string { + out := make(map[string][]string, len(in)) + for k, v := range in { + if strings.HasPrefix(k, aceExtraPrefix) { + out[k] = v + } + } + if len(out) == 0 { + return nil + } + return out +} + func (d *DelegatingClient) Impersonate(u user.Info) (*restclient.Config, client.Client, error) { + extra := impersonableExtra(u.GetExtra()) + config := restclient.CopyConfig(d.config) config.Impersonate = restclient.ImpersonationConfig{ UserName: u.GetName(), UID: u.GetUID(), Groups: u.GetGroups(), - Extra: u.GetExtra(), + Extra: extra, } // share the transport between all clients @@ -117,7 +142,7 @@ func (d *DelegatingClient) Impersonate(u user.Info) (*restclient.Config, client. UserName: u.GetName(), UID: u.GetUID(), Groups: u.GetGroups(), - Extra: u.GetExtra(), + Extra: extra, }, d.options.HTTPClient.Transport), } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8582513e89..4979270387 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2580,8 +2580,8 @@ kmodules.xyz/authorizer/apiserver kmodules.xyz/authorizer/rbac kmodules.xyz/authorizer/rbac/helpers kmodules.xyz/authorizer/rbac/validation -# kmodules.xyz/client-go v0.34.5 -## explicit; go 1.24.0 +# kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a +## explicit; go 1.25.0 kmodules.xyz/client-go kmodules.xyz/client-go/api/v1 kmodules.xyz/client-go/apiextensions From 63a2381d174609ca784163f5685b0b9463be567b Mon Sep 17 00:00:00 2001 From: Arnob Kumar Saha Date: Sun, 26 Jul 2026 22:53:26 +0600 Subject: [PATCH 2/3] Impersonate only ACE extras impersonableExtra dropped just the reserved authentication.kubernetes.io/* keys and forwarded every other extra from the caller's identity. Kubernetes authorizes impersonated extras per key, as userextras/, and the chart grants kube-ui-server exactly one of those -- ace.appscode.com/org-id. So a caller carrying provider-injected extras had the whole EditorModel request denied during impersonation authorization, before its own RBAC was consulted. This is what a spoke imported through Rancher hits: Rancher forwards principalid, username, requesthost and requesttokenid, none of them ACE keys. Turn the denylist into an allowlist keeping only ace.appscode.com/* extras. Every platform invents its own -- Rancher's principalid, EKS' arn, OpenShift's scopes.authorization.openshift.io -- so widening the chart RBAC never converges, while an allowlist is correct on any provider. RBAC ignores extras, so this changes no authorization decision on an ordinary cluster. Signed-off-by: Arnob Kumar Saha --- pkg/registry/editor/editormodel/storage.go | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pkg/registry/editor/editormodel/storage.go b/pkg/registry/editor/editormodel/storage.go index 824381be00..bbb40142e2 100644 --- a/pkg/registry/editor/editormodel/storage.go +++ b/pkg/registry/editor/editormodel/storage.go @@ -90,20 +90,25 @@ func (r *Storage) callerClient(ctx context.Context) (client.Client, error) { return client.New(cfg, client.Options{Scheme: r.scheme, Mapper: r.mapper}) } -// impersonableExtra drops the reserved authentication.kubernetes.io/* extras -// (e.g. credential-id added for X509/SA auth on k8s >=1.30). These are injected -// by the apiserver and impersonating them needs a dedicated userextras RBAC verb -// that kube-ui-server does not hold; they carry no authorization identity. +// aceExtraPrefix is the only extra-key namespace kube-ui-server holds +// `impersonate` on `userextras/` for. +const aceExtraPrefix = "ace.appscode.com/" + +// impersonableExtra keeps only the ACE extras. Every other extra key is provider +// bookkeeping the apiserver or the platform injected -- Rancher's principalid, +// EKS' arn, the reserved authentication.kubernetes.io/* keys -- and impersonating +// any of them needs a userextras/ RBAC grant kube-ui-server does not hold, +// which would fail the whole request in impersonation authorization. They carry +// no identity for RBAC, which ignores extras. func impersonableExtra(in map[string][]string) map[string][]string { - if len(in) == 0 { - return nil - } out := make(map[string][]string, len(in)) for k, v := range in { - if strings.HasPrefix(k, "authentication.kubernetes.io/") { - continue + if strings.HasPrefix(k, aceExtraPrefix) { + out[k] = v } - out[k] = v + } + if len(out) == 0 { + return nil } return out } From bd373329936fcc94e65e5da6a4bac0f75b165667 Mon Sep 17 00:00:00 2001 From: Arnob kumar saha Date: Tue, 28 Jul 2026 14:42:53 +0600 Subject: [PATCH 3/3] update deps Signed-off-by: Arnob kumar saha --- go.mod | 2 +- go.sum | 4 ++-- vendor/kmodules.xyz/client-go/discovery/lib.go | 3 ++- vendor/kmodules.xyz/client-go/meta/preconditions.go | 3 ++- vendor/kmodules.xyz/client-go/openapi/render.go | 3 ++- vendor/modules.txt | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 66a8b48aec..737f79b512 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 kmodules.xyz/apiversion v0.2.0 kmodules.xyz/authorizer v0.34.0 - kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a + kmodules.xyz/client-go v0.34.6-0.20260728083845-0d1ff93aa771 kmodules.xyz/custom-resources v0.34.0 kmodules.xyz/go-containerregistry v0.0.15 kmodules.xyz/monitoring-agent-api v0.34.3 diff --git a/go.sum b/go.sum index 33cd4ef670..41a2e87b62 100644 --- a/go.sum +++ b/go.sum @@ -1175,8 +1175,8 @@ kmodules.xyz/apply v0.34.0 h1:n6kAuHKAg3uzrlJccaAhjq/O4DdeiKqig9ElzoBXfzU= kmodules.xyz/apply v0.34.0/go.mod h1:V8B55uphISoKUHWAfyntveZFEkey6WxVP3cnXOvX4eY= kmodules.xyz/authorizer v0.34.0 h1:WEDyKac9u/xmYkdrVtZqUTk4x0+8T8FYPslf3O8cNfU= kmodules.xyz/authorizer v0.34.0/go.mod h1:b/aqy4e81jp/Nz0hfmOSHLr1+qUMJ0y6YMkEZ2PtoRo= -kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a h1:GsSi2+cC6EG8FCkzk4YwpmtqMZUvTLUf2XfkAgsA918= -kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a/go.mod h1:TGfM3P0jfFJUoVii8DTNE4An/E5mN9BRhddHDUb0zZY= +kmodules.xyz/client-go v0.34.6-0.20260728083845-0d1ff93aa771 h1:aInLVWuHm216MQ2hY215HWqyWYwRLDN+8Ty+TMG0Q0I= +kmodules.xyz/client-go v0.34.6-0.20260728083845-0d1ff93aa771/go.mod h1:TGfM3P0jfFJUoVii8DTNE4An/E5mN9BRhddHDUb0zZY= kmodules.xyz/crd-schema-fuzz v0.34.1 h1:YfrFv9LcrVW54BhFSekFAyEuWxp09wic1j8xm3c41T0= kmodules.xyz/crd-schema-fuzz v0.34.1/go.mod h1:uer6PA1mrDk4SI6C+kZ2vNZFPZhHvgahuf+YRVKQiHo= kmodules.xyz/custom-resources v0.34.0 h1:ljkIYzIq0A3Awj87kkpuYqS9aifuyR3Hr9q2OVKoojM= diff --git a/vendor/kmodules.xyz/client-go/discovery/lib.go b/vendor/kmodules.xyz/client-go/discovery/lib.go index dd425b63c8..8005043618 100644 --- a/vendor/kmodules.xyz/client-go/discovery/lib.go +++ b/vendor/kmodules.xyz/client-go/discovery/lib.go @@ -223,7 +223,8 @@ func IsDefaultSupportedVersion(kc kubernetes.Interface) error { kc, DefaultConstraint, DefaultBlackListedVersions, - DefaultBlackListedMultiMasterVersions) + DefaultBlackListedMultiMasterVersions, + ) } func IsSupportedVersion(kc kubernetes.Interface, constraint string, blackListedVersions map[string]error, blackListedMultiMasterVersions map[string]error) error { diff --git a/vendor/kmodules.xyz/client-go/meta/preconditions.go b/vendor/kmodules.xyz/client-go/meta/preconditions.go index 5dddddb481..cf7d673d5d 100644 --- a/vendor/kmodules.xyz/client-go/meta/preconditions.go +++ b/vendor/kmodules.xyz/client-go/meta/preconditions.go @@ -37,7 +37,8 @@ func (s PreConditionSet) PreconditionFunc() []mergepatch.PreconditionFunc { } for _, field := range sets.List[string](s.Set) { - preconditions = append(preconditions, + preconditions = append( + preconditions, RequireChainKeyUnchanged(field), ) } diff --git a/vendor/kmodules.xyz/client-go/openapi/render.go b/vendor/kmodules.xyz/client-go/openapi/render.go index 029eea2dfa..1730b06b41 100644 --- a/vendor/kmodules.xyz/client-go/openapi/render.go +++ b/vendor/kmodules.xyz/client-go/openapi/render.go @@ -86,7 +86,8 @@ func RenderOpenAPISpec(cfg Config) (string, error) { // TODO: keep the generic API server from wanting this unversioned := schema.GroupVersion{Group: "", Version: "v1"} - cfg.Scheme.AddUnversionedTypes(unversioned, + cfg.Scheme.AddUnversionedTypes( + unversioned, &metav1.Status{}, &metav1.APIVersions{}, &metav1.APIGroupList{}, diff --git a/vendor/modules.txt b/vendor/modules.txt index 4979270387..0ab34a538c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2580,7 +2580,7 @@ kmodules.xyz/authorizer/apiserver kmodules.xyz/authorizer/rbac kmodules.xyz/authorizer/rbac/helpers kmodules.xyz/authorizer/rbac/validation -# kmodules.xyz/client-go v0.34.6-0.20260726164328-778b1ba80e3a +# kmodules.xyz/client-go v0.34.6-0.20260728083845-0d1ff93aa771 ## explicit; go 1.25.0 kmodules.xyz/client-go kmodules.xyz/client-go/api/v1