A HTTP client proxy that transparently fetches and injects audience scoped Kubernetes ServiceAccount tokens.
A HTTP client proxy that transparently fetches and injects audience scoped Kubernetes ServiceAccount tokens.
Using Kubernetes' ServiceAccounts for authentication and authorization is an attractive option for securing Kubernetes cluster components as everything from auto-mounting over rotation is handled for you, but they're also easy to misuse as it was pointed out early when kube-rbac-proxy was created. The problem is the same token that is used to authenticate against the Kubernetes API is used to authenticate against other endpoints, which allows said endpoints to impersonate the requesting entity by simply re-using the token it received.
As the same strategy that kube-rbac-proxy uses is used by Kubernetes components such as the kubelet, controller-manager and scheduler the Kubernetes project had to come up with a solution, and that solution is Bound Service Account Tokens. Among other improvements over the initial ServiceAccount token design, Bound Service Account Tokens allows requesting a new token that is scoped to its audience preventing its use from anything but the target it was created for.
This project was initially created for use in combination with Prometheus and kube-rbac-proxy to create a more sound security story, but it can be used for any similar scenario.
In its essence kube-audience-proxy is a very simple HTTP client proxy that simply transparently requests and injects bound tokens into a request. By default the audience is selected by specifying it in the kubernetes-audience
query parameter of the client's HTTP request. In order for the proxy to intercept TLS connections, it generates and writes a CA at startup that the requesting entity needs to trust as it essentially needs to perform an intended man-in-the-middle attack, which is injecting the token.
This proxy allows creating new tokens, while that's the main purpose, it's important to understand the implications of this. This proxy should likely never be exposed to anything but the client and the one client only that it's meant for. It is not recommended to share the proxy for multiple clients, instead use one proxy per client and bind the proxy against a loopback IP, and ensure that only the process it is meant for has access to it.
The only thing that must be set is the --service-account
flag, which for convenience defaults to the value of the SERVICE_ACCOUNT
environment variable, so that can also be set instead of specifying the flag.
The kube-rbac-proxy has all klog
flags for logging purposes of Kubernetes internal libraries and the --log-level
flag for everything that makes up kube-audience-proxy.
If TLS connections are required, in which case the --ca-file-destination
flag is important, as it is the location the proxy will write its generated CA certificate which the client needs to trust.
All command line flags:
$ kube-audience-proxy -h
Usage of _output/linux/amd64/kube-audience-proxy:
--add_dir_header If true, adds the file directory to the header
--alsologtostderr log to standard error as well as files
--apiserver string Alternative apiserver so use.
--audience-parameter string Parameter name to read audience from to scope tokens to. (default "kubernetes-audience")
--ca-file-destination string File destination to write generated CA cert to. (default "ca.crt")
--insecure-listen-address string Address to bind HTTP server to.
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
--kubeconfig string Kubeconfig to use to connect to cluster.
--log-format string Log format to use. Possible values: logfmt, json. (default "logfmt")
--log-level string Log level to use. Possible values: all, debug, info, warn, error, none. (default "info")
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--namespace-file string File to read namespace of pod from. (default "/var/run/secrets/kubernetes.io/serviceaccount/namespace")
--secure-listen-address string Address to bind HTTPS server to.
--service-account string Name of serviceaccount of Pod the kube-audience-proxy process runs in.
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--tls-cert-file string File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert)
--tls-cipher-suites strings Comma-separated list of cipher suites for the server. Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). If omitted, the default Go cipher suites will be used
--tls-min-version string Minimum TLS version supported. Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants. (default "VersionTLS12")
--tls-private-key-file string File containing the default x509 private key matching --tls-cert-file.
-v, --v Level number for the log level verbosity
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging