Skip to content
This repository was archived by the owner on Aug 28, 2025. It is now read-only.

Commit 6f9822c

Browse files
committed
feat: add the ability to perform writing actions as the actual actor rather than the mighty serviceaccount
1 parent c83410b commit 6f9822c

File tree

4 files changed

+40
-44
lines changed

4 files changed

+40
-44
lines changed

cmd/start.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ var startCmd = &cobra.Command{
4646
panic("no cache sync")
4747
}
4848

49+
cfg.Wrap(gateway.NewImpersonationTransport)
50+
4951
cl, err := client.NewWithWatch(cfg, client.Options{
5052
Scheme: schema,
5153
Cache: &client.CacheOptions{

gateway/gateway.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"golang.org/x/text/language"
2020
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2121
"k8s.io/apimachinery/pkg/runtime"
22+
utilnet "k8s.io/apimachinery/pkg/util/net"
23+
"k8s.io/client-go/transport"
2224
"sigs.k8s.io/controller-runtime/pkg/client"
2325
)
2426

@@ -585,3 +587,38 @@ func Handler(conf HandlerConfig) http.Handler {
585587
func AddUserToContext(ctx context.Context, user string) context.Context {
586588
return context.WithValue(ctx, userContextKey{}, user)
587589
}
590+
591+
func GetUserFromContext(ctx context.Context) (string, bool) {
592+
user, ok := ctx.Value(userContextKey{}).(string)
593+
return user, ok
594+
}
595+
596+
type impersonation struct {
597+
delegate http.RoundTripper
598+
}
599+
600+
func (i *impersonation) RoundTrip(req *http.Request) (*http.Response, error) {
601+
602+
// use the user header as marker for the rest.
603+
if len(req.Header.Get(transport.ImpersonateUserHeader)) != 0 {
604+
return i.delegate.RoundTrip(req)
605+
}
606+
607+
user, ok := GetUserFromContext(req.Context())
608+
if !ok || user == "" {
609+
return i.delegate.RoundTrip(req)
610+
}
611+
612+
slog.Debug("impersonating request", "user", user)
613+
614+
fmt.Println("impersonating", user)
615+
616+
req = utilnet.CloneRequest(req)
617+
req.Header.Set(transport.ImpersonateUserHeader, user)
618+
619+
return i.delegate.RoundTrip(req)
620+
}
621+
622+
func NewImpersonationTransport(rt http.RoundTripper) http.RoundTripper {
623+
return &impersonation{delegate: rt}
624+
}

gateway/resolver.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,8 @@ func (r *resolver) listItems(crd apiextensionsv1.CustomResourceDefinition, typeI
6969
opts = append(opts, client.MatchingLabelsSelector{Selector: selector})
7070
}
7171

72-
ras := authzv1.ResourceAttributes{
73-
Verb: "list",
74-
Group: crd.Spec.Group,
75-
Version: typeInformation.Name,
76-
Resource: crd.Spec.Names.Plural,
77-
}
7872
if namespace, ok := p.Args["namespace"].(string); ok && namespace != "" {
7973
opts = append(opts, client.InNamespace(namespace))
80-
ras.Namespace = namespace
81-
}
82-
83-
if err := isAuthorized(ctx, r.conf.Client, ras); err != nil {
84-
return nil, err
8574
}
8675

8776
err := r.conf.Client.List(ctx, list, opts...)
@@ -181,17 +170,6 @@ func (r *resolver) deleteItem(crd apiextensionsv1.CustomResourceDefinition, type
181170
ctx, span := otel.Tracer("").Start(p.Context, "Delete", trace.WithAttributes(attribute.String("kind", crd.Spec.Names.Kind)))
182171
defer span.End()
183172

184-
if err := isAuthorized(ctx, r.conf.Client, authzv1.ResourceAttributes{
185-
Verb: "delete",
186-
Group: crd.Spec.Group,
187-
Version: typeInformation.Name,
188-
Resource: crd.Spec.Names.Plural,
189-
Namespace: p.Args["namespace"].(string),
190-
Name: p.Args["name"].(string),
191-
}); err != nil {
192-
return nil, err
193-
}
194-
195173
us := &unstructured.Unstructured{}
196174
us.SetGroupVersionKind(schema.GroupVersionKind{
197175
Group: crd.Spec.Group,
@@ -226,16 +204,6 @@ func (r *resolver) createItem(crd apiextensionsv1.CustomResourceDefinition, type
226204

227205
logger = logger.With(slog.Group("metadata", slog.String("name", metadatInput.Name), slog.String("namespace", metadatInput.Namespace)))
228206

229-
if err := isAuthorized(ctx, r.conf.Client, authzv1.ResourceAttributes{
230-
Verb: "create",
231-
Group: crd.Spec.Group,
232-
Version: typeInformation.Name,
233-
Resource: crd.Spec.Names.Plural,
234-
Namespace: metadatInput.Namespace,
235-
}); err != nil {
236-
return nil, err
237-
}
238-
239207
us := &unstructured.Unstructured{}
240208
us.SetGroupVersionKind(schema.GroupVersionKind{
241209
Group: crd.Spec.Group,
@@ -287,17 +255,6 @@ func (r *resolver) updateItem(crd apiextensionsv1.CustomResourceDefinition, type
287255

288256
logger = logger.With(slog.Group("metadata", slog.String("name", metadatInput.Name), slog.String("namespace", metadatInput.Namespace)))
289257

290-
if err := isAuthorized(ctx, r.conf.Client, authzv1.ResourceAttributes{
291-
Verb: "update",
292-
Group: crd.Spec.Group,
293-
Version: typeInformation.Name,
294-
Resource: crd.Spec.Names.Plural,
295-
Namespace: metadatInput.Namespace,
296-
Name: metadatInput.Name,
297-
}); err != nil {
298-
return nil, err
299-
}
300-
301258
us := &unstructured.Unstructured{}
302259
us.SetGroupVersionKind(schema.GroupVersionKind{
303260
Group: crd.Spec.Group,

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
k8s.io/api v0.30.1
1616
k8s.io/apiextensions-apiserver v0.30.1
1717
k8s.io/apimachinery v0.30.1
18+
k8s.io/client-go v0.30.1
1819
sigs.k8s.io/controller-runtime v0.18.3
1920
)
2021

@@ -74,7 +75,6 @@ require (
7475
gopkg.in/inf.v0 v0.9.1 // indirect
7576
gopkg.in/yaml.v2 v2.4.0 // indirect
7677
gopkg.in/yaml.v3 v3.0.1 // indirect
77-
k8s.io/client-go v0.30.1 // indirect
7878
k8s.io/klog/v2 v2.120.1 // indirect
7979
k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect
8080
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect

0 commit comments

Comments
 (0)