kubernetes / apiserver

Library for writing a Kubernetes-style API server.
Apache License 2.0
647 stars 400 forks source link

Expose username and group from the appropriate headers #110

Closed braghettos closed 4 months ago

braghettos commented 4 months ago

Hi everyone! We're implementing an aggregation layer leveraging the apiserver package. In our use case we need to retrieve the headers in order to understand who's the user making the request.

We were looking at the documentation: https://kubernetes.io/docs/tasks/extend-kubernetes/configure-aggregation-layer/#extension-apiserver-authenticates-the-request - in particular the following paragraph:

Check that the TLS connection was authenticated using a client certificate which:

But it seems that the apiserver package is not exposing these headers. Could anyone help me pointing out if there's a way to retrieve these headers after the authn/authz phases?

Thanks for any help!

braghettos commented 4 months ago

To date, we put all the custom logic here => https://github.com/kubernetes/apiserver/blob/master/pkg/registry/generic/registry/store.go#L170 that is, after the CR has been taken from the store (etcd). The ideal would be to have the object here in this method https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go#L20

fedebongio commented 4 months ago

/cc @deads2k @enj @liggitt

I'll let the experts comment on this one. I have the feeling that there is a reason why such functionality is not already implemented, but I'm not a security expert.

enj commented 4 months ago

All of this stuff is done automatically for you if you wire your server correctly, for example DelegatingAuthenticationOptions takes care of authentication.

https://github.com/kubernetes/apiserver/blob/b58ca9c01b646bef73eea4b5549ebaba383dd59e/pkg/server/options/authentication.go#L301

request.UserFrom can be used in later layers to get the user.Info:

https://github.com/kubernetes/apiserver/blob/b58ca9c01b646bef73eea4b5549ebaba383dd59e/pkg/endpoints/request/context.go#L75

enj commented 4 months ago

Use this code as an example for wiring up an aggregated API server correctly.

lucasepe commented 4 months ago

Hi @enj thank you very much for your quick response!

What we would like to do is to access the user.Info struct from this Decorator => apiserver/pkg/registry/generic/registry/store.go#L170.

Decorator that is used, for instance, here => apiserver/pkg/registry/generic/registry/store.go#L812.

Since this Decorator des not expose the Context, we can’t do the UserFrom(ctx context.Context) call.

Taking as reference the sample-apiserver, exists a way to access to the user.Info who is asking for the resource from within the Decorator?

All the best, Luca

enj commented 4 months ago

@lucasepe I am not sure that I would recommend that you change the resource based on the user, but you can do that via:

  1. Wrap the GenericConfig.RESTOptionsGetter of your server
  2. Have it return a RESTOptions that further wraps the existing StorageDecorator
  3. Have the new StorageDecorator wrap the storage.Interface
  4. Have your new storage.Interface methods such as Get use the request context to perform whatever mutation you want on the returned resource
lucasepe commented 4 months ago

Thank you very much @enj ! It works!

All the best, Luca

enj commented 4 months ago

/close

k8s-ci-robot commented 4 months ago

@enj: Closing this issue.

In response to [this](https://github.com/kubernetes/apiserver/issues/110#issuecomment-2116176438): >/close Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.