521adffb17
This change updates the impersonator logic to use the delegated authorizer for all non-rest verbs such as impersonate. This allows it to correctly perform authorization checks for incoming requests that set impersonation headers while not performing unnecessary checks that are already handled by KAS. The audit layer is enabled to track the original user who made the request. This information is then included in a reserved extra field original-user-info.impersonation-proxy.concierge.pinniped.dev as a JSON blob. Signed-off-by: Monis Khan <mok@vmware.com>
43 lines
2.4 KiB
Go
43 lines
2.4 KiB
Go
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
/*
|
|
Package impersonator implements an HTTP server that reverse proxies all requests
|
|
to the Kubernetes API server with impersonation headers set to match the calling
|
|
user. Since impersonation cannot be disabled, this allows us to dynamically
|
|
configure authentication on any cluster, even the cloud hosted ones.
|
|
|
|
The specifics of how it is implemented are of interest. The most novel detail
|
|
about the implementation is that we use the "front-end" of the aggregated API
|
|
server logic, mainly the DefaultBuildHandlerChain func, to handle how incoming
|
|
requests are authenticated, authorized, etc. The "back-end" of the proxy is a
|
|
reverse proxy that impersonates the user (instead of serving REST APIs).
|
|
|
|
In terms of authentication, we aim to handle every type of authentication that
|
|
the Kubernetes API server supports by delegating most of the checks to it. We
|
|
also honor client certs from a CA that is specific to the impersonation proxy.
|
|
This approach allows clients to use the Token Credential Request API even when
|
|
we do not have the cluster's signing key.
|
|
|
|
In terms of authorization, we rely mostly on the Kubernetes API server. Since we
|
|
impersonate the user, the proxied request will be authorized against that user.
|
|
Thus for all regular REST verbs, we perform no authorization checks.
|
|
|
|
Nested impersonation is handled by performing the same authorization checks the
|
|
Kubernetes API server would (we get this mostly for free by using the aggregated
|
|
API server code). We preserve the original user in the reserved extra key
|
|
original-user-info.impersonation-proxy.concierge.pinniped.dev as a JSON blob of
|
|
the authenticationv1.UserInfo struct. This is necessary to make sure that the
|
|
Kubernetes audit log contains all three identities (original user, impersonated
|
|
user and the impersonation proxy's service account). Capturing the original
|
|
user information requires that we enable the auditing stack (WithImpersonation
|
|
only shares this information with the audit stack). To keep things simple,
|
|
we use the fake audit backend at the Metadata level for all requests. This
|
|
guarantees that we always have an audit event on every request.
|
|
|
|
For all normal requests, we only use http/2.0 when proxying to the API server.
|
|
For upgrade requests, we only use http/1.1 since these always go from http/1.1
|
|
to either websockets or SPDY.
|
|
*/
|
|
package impersonator
|