Kubernetes RBAC authorizing HTTP proxy for a single upstream.
Kubernetes RBAC authorizing HTTP proxy for a single upstream.
NOTE: This project is alpha stage. Flags, configuration, behavior and design may change significantly in following releases.
The kube-rbac-proxy is a small HTTP proxy for a single upstream, that can perform RBAC authorization against the Kubernetes API using SubjectAccessReview.
In Kubernetes clusters without NetworkPolicies any Pod can perform requests to every other Pod in the cluster. This proxy was developed in order to restrict requests to only those Pods, that present a valid and RBAC authorized token or client TLS certificate.
The project is seeking to be accepted as a k8s project and therefore we need to align tighter with k8s. As a result, we use more of the k8s code and need to deprecate features, while introducing others.
The reasons for deprecation are that k8s doesn't support them anymore and partially because it is not a best practice. An example of "not a best practice" is to offer insecure listening and an example of upstream deprecations are some of the logging flags.
The project states above that it is alpha and "flags, configuration, and behavior" can change significantly. Nevertheless, the project was treated like a production-v1 project: no breaking changes were introduced.
We will introduce a feature branch called sig-auth-acceptance that shows how kube-rbac-proxy will change.
We try to keep the current release secure by making necessary updates when necessary, but this is best effort.
An update of Kubernetes from v0.25.2 to v0.25.5 was rolled back as it removed the --logtostderr flag.
The kube-rbac-proxy has all glog flags for logging purposes. To use the kube-rbac-proxy there are a few flags you may want to set:
--upstream: This is the upstream you want to proxy to.--config-file: This file specifies details on the SubjectAccessReview you want to be performed on a request. For example, this could contain that an entity performing a request has to be allowed to perform a get on the Deployment called my-frontend-app, as well as the ability to configure whether SubjectAccessReviews are rewritten based on requests.See the examples/ directory for the following examples:
All command line flags:
…To update the Go dependencies run make update-go-deps.
This might be useful to do during a release.
You may ask yourself, why not just use the Kubernetes apiserver proxy functionality? There are two reasons why this makes sense, the first is to take load off of the Kubernetes API, so it can be used for actual requests serving the cluster components, rather than in order to serve client requests. The second and more important reason is, this proxy is intended to be a sidecar that accepts incoming HTTP requests. This way, one can ensure that a request is truly authorized, instead of being able to access an application simply because an entity has network access to it.
I developed this proxy in order to be able to protect Prometheus metrics endpoints. In a scenario, where an attacker might obtain full control over a Pod, that attacker would have the ability to discover a lot of information about the workload as well as the current load of the respective workload. This information could originate for example from the node-exporter and kube-state-metrics. Both of those metric sources can commonly be found in Prometheus monitoring stacks on Kubernetes.
This project was created to specifically solve the above problem, however, I felt there is a larger need for such a proxy in general.
On an incoming request, kube-rbac-proxy first figures out which user is performing the request. The kube-rbac-proxy supports using client TLS certificates, as well as tokens. In case of a client certificates, the certificate is simply validated against the configured CA. In case of a bearer token being presented, the authentication.k8s.io is used to perform a TokenReview.
Once a user has been authenticated, again the authentication.k8s.io is used to perform a SubjectAccessReview, in order to authorize the respective request, to ensure the authenticated user has the required RBAC roles.
Note that when using tokens for authentication, the receiving side can use the token to impersonate the client. Only use token authentication, when the receiving side is already higher privileged or the token itself is super low privileged, such as when the only roles bound to it are for authorization purposes with this project. Passing around highly privileged tokens is a security risk, and is not recommended.
This project was built to be used to protect metrics of cluster components. These cluster components are much higher privileged than the Prometheus Pod, so if those Pods were to use the token provided by Prometheus it would actually be lower privileged. It is not recommended to use this method for non infrastructure components.
For better security properties use mTLS for authentication instead, and for user authentication, other methods have yet to be added.
There are a couple of reasons why the existence of NetworkPolicies may not cover the same use case(s):
This projects is not intended to compete with Envoy or IstioMesh. Although on the surface they seem similar, the goals and usage complement each other. It's perfectly ok to use Envoy as the ingress point of traffic of a Pod, which then forwards traffic to the kube-rbac-proxy, which in turn then proxies to the actually serving application.
Additionally, to my knowledge Envoy neither has nor plans Kubernetes specific RBAC/AuthZ support (maybe it shouldn’t even). My knowledge may very well be incomplete, please point out if it is. After all I'm happy if I don't have to maintain more code, but as long as this serves a purpose to me and no other project can provide it, I'll maintain this.
To run tests locally, you need to have kind installed. By default it uses the default cluster, so be aware that it overrides your default kind cluster.
The command to execute the tests is: make test-local.
PRs are more than welcome!
No open issues yet, or sync has not completed.