diff --git a/pkg/authorization/requiredgroups_authorizer.go b/pkg/authorization/requiredgroups_authorizer.go index 98139e30843..791a4eb91be 100644 --- a/pkg/authorization/requiredgroups_authorizer.go +++ b/pkg/authorization/requiredgroups_authorizer.go @@ -101,6 +101,11 @@ func (a *requiredGroupsAuthorizer) Authorize(ctx context.Context, attr authorize return authorizer.DecisionNoOpinion, "", err } + // always let external-logical-cluster-admins through + if sets.NewString(attr.GetUser().GetGroups()...).Has(bootstrap.SystemExternalLogicalClusterAdmin) { + return DelegateAuthorization("external logical cluster admin access", a.delegate).Authorize(ctx, attr) + } + // check required groups value, found := logicalCluster.Annotations[RequiredGroupsAnnotationKey] if !found { diff --git a/pkg/authorization/requiredgroups_authorizer_test.go b/pkg/authorization/requiredgroups_authorizer_test.go index 0081cc2c332..27b78c50009 100644 --- a/pkg/authorization/requiredgroups_authorizer_test.go +++ b/pkg/authorization/requiredgroups_authorizer_test.go @@ -57,6 +57,12 @@ func TestRequiredGroupsAuthorizer(t *testing.T) { wantDecision: authorizer.DecisionAllow, wantReason: "delegating due to logical cluster admin access", }, + "system:kcp:external-logical-cluster-admin can always pass": { + requestedWorkspace: "root:ready", + requestingUser: newUser("external-lcluster-admin", "system:kcp:external-logical-cluster-admin"), + wantDecision: authorizer.DecisionAllow, + wantReason: "delegating due to external logical cluster admin access", + }, "service account from other cluster is granted access": { requestedWorkspace: "root:ready", requestingUser: newServiceAccountWithCluster("sa", "anotherws"),