diff --git a/pkg/server/handler.go b/pkg/server/handler.go index dcefb27844d7..af653db518b4 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -280,6 +280,10 @@ func WithServiceAccountRewrite(handler http.Handler) http.Handler { default: } } + + // call rest of the chain + ctx = request.WithUser(ctx, &rewritten) + handler.ServeHTTP(w, req.WithContext(ctx)) }) } diff --git a/pkg/virtual/apiexport/builder/build.go b/pkg/virtual/apiexport/builder/build.go index d5a74de82ac1..0e952fc842e6 100644 --- a/pkg/virtual/apiexport/builder/build.go +++ b/pkg/virtual/apiexport/builder/build.go @@ -18,6 +18,7 @@ package builder import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -100,19 +101,41 @@ func BuildVirtualWorkspace( return nil, fmt.Errorf("error getting valid cluster from context: %w", err) } + user, found := genericapirequest.UserFrom(ctx) + if !found { + return nil, fmt.Errorf("error getting user from context") + } + // Wildcard requests cannot be impersonated against a concrete cluster. if cluster.Wildcard { return dynamicClient, nil } - impersonationConfig := rest.CopyConfig(cfg) - impersonationConfig.Impersonate = rest.ImpersonationConfig{ - UserName: "system:serviceaccount:default:rest", - Groups: []string{bootstrap.SystemKcpAdminGroup}, + // Add a warrant of a fake local service account giving full access + warrant := authorization.Warrant{ + User: "system:serviceaccount:default:rest", + Groups: []string{bootstrap.SystemKcpAdminGroup}, Extra: map[string][]string{ serviceaccount.ClusterNameKey: {cluster.Name.Path().String()}, }, } + bs, err := json.Marshal(warrant) + if err != nil { + return nil, fmt.Errorf("error marshaling warrant: %w", err) + } + + // Impersonate the request user and add the warrant as an extra + impersonationConfig := rest.CopyConfig(cfg) + impersonationConfig.Impersonate = rest.ImpersonationConfig{ + UserName: user.GetName(), + Groups: user.GetGroups(), + UID: user.GetUID(), + Extra: user.GetExtra(), + } + if impersonationConfig.Impersonate.Extra == nil { + impersonationConfig.Impersonate.Extra = map[string][]string{} + } + impersonationConfig.Impersonate.Extra[authorization.WarrantExtraKey] = append(impersonationConfig.Impersonate.Extra[authorization.WarrantExtraKey], string(bs)) impersonatedClient, err := kcpdynamic.NewForConfig(impersonationConfig) if err != nil { return nil, fmt.Errorf("error generating dynamic client: %w", err)