Skip to content

Commit 19cec4d

Browse files
author
Gustav Paul
committed
pkg/endpoints: explicitly forward impersonate headers
1 parent c07e748 commit 19cec4d

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

pkg/endpoints/cluster.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,30 @@ func (r Resource) ProxyRequest(request *restful.Request, response *restful.Respo
5757
uri := request.PathParameter("subpath") + "?" + parsedURL.RawQuery
5858
forwardRequest := r.K8sClient.CoreV1().RESTClient().Verb(request.Request.Method).RequestURI(uri).Body(request.Request.Body)
5959
forwardRequest.SetHeader("Content-Type", request.HeaderParameter("Content-Type"))
60-
// Copy authorization (for serviceaccount clients) and impersonation headers (for user clients) from the client request to the forwarded request.
61-
for k, vs := range request.Request.Header {
62-
if k == "Impersonate-User" || k == "Impersonate-Group" || k == "Authorization" {
63-
forwardRequest.SetHeader(k, vs...)
64-
}
60+
if r.Impersonate {
61+
// If the dashboard is running with Impersonate enabled, then proxy requests using the
62+
// incoming requests Impersonate-* and Authorization headers. The Authorization header must
63+
// correspond to a serviceaccount that has `impersonate` privileges, otherwise the apiserver
64+
// will reject the request.
65+
//
66+
// In this mode, the intention is for the dashboard to be behind an authenticating reverse proxy
67+
// that authenticates the user using an OIDC flow. The reverse proxy then attaches an
68+
// Authorization header to the request containing its own authentication proof.
69+
// It also adds Impersonate-* headers that list the identity claim (e.g., `sub`, `email`, etc.)
70+
// and/or user group (i.e., `groups` claim) of the end-user.
71+
//
72+
// The apiserver receives the forwarded request, determines that the serviceaccount corresponding
73+
// to the Authorization token has `impersonate` privileges (the reverse proxy must have
74+
// `impersonate` privileges) and responds to the request as though it was performed by the
75+
// account given by the Impersonate-User header and/or Impersonate-Group header.
76+
//
77+
// In this mode, the Authorization header must be set, it is important that the
78+
// dashboard not perform this request using its own serviceaccount (the default behaviour), as
79+
// that leads to a privilege escalation whereby a less-privileged user can access resources
80+
// that the dashboard can access, but the user may not.
81+
forwardRequest.SetHeader("Authorization", request.Request.Header.Get("Authorization"))
82+
forwardRequest.SetHeader("Impersonate-User", request.Request.Header.Get("Impersonate-User"))
83+
forwardRequest.SetHeader("Impersonate-Group", request.Request.Header.Get("Impersonate-Group"))
6584
}
6685
forwardResponse := forwardRequest.Do()
6786

0 commit comments

Comments
 (0)