The OpenID Connect Webhook Authenticator allows Kubernetes cluster administrators to dynamically register new OpenID Connect providers in their clusters to use for kube-apiserver authentication.
Note: This repository still in
alpha
stage and in active development. It should not be used in production. The API can change without any backwards compatibility.
In Kubernetes, only a single OpenID Connect authenticator can be used for end-users to authenticate.
To workaround this limitations, a Webhook Token Authentication can be configured. The Kube APIServer then sends the Bearer Tokens (id_token) to an external webhook for validation:
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"spec": {
"token": "(BEARERTOKEN)"
}
}
Where upon verification, the remote webhook returns the identity of the user (if authentication succeeds):
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
"username": "janedoe@example.com",
"uid": "42",
"groups": [
"developers",
"qa"
],
"extra": {
"extrafield1": [
"extravalue1",
"extravalue2"
]
}
}
}
}
This repository is the out-of tree implementation of Dynamic Authentication KEP.
kube-apiserver
.This webhook is a Kubernetes controller that acts on OpenIDConnect
resources e.g:
apiVersion: authentication.gardener.cloud/v1alpha1
kind: OpenIDConnect
metadata:
name: foo
spec:
issuerURL: https://foo.bar
clientID: some-client-id
usernameClaim: email
usernamePrefix: "test-"
groupsClaim: groups
groupsPrefix: "baz-"
supportedSigningAlgs:
- RS256
requiredClaims:
baz: bar
caBundle: LS0tLS1CRUdJTiBDRVJU...base64-encoded CA certs for issuerURL.
Note: The fields in the specification corresponds to the kube-apiserver OIDC flags.
The flow is following:
OpenIDConnect
to the cluster.spec.issuerURL
with a well-known path (.well-known/openid-configuration).jwks_uri
obtained from the OIDC providers configuration, to fetch the OIDC provider's public keys from that endpoint.An overview of the controller:
When a user wants to authenticate to the kube-apiserver
via this new Custom OpenIDConnect IDP:
The user authenticates in Custom IDP.
id_token
is obtained from Custom IDP (e.g. ddeewfwef...
).
The user uses id_token
to perform an API call to Kube APIServer.
As the id_token
is not matched by any build-in or configured authenticators in the Kube APIServer, it is send to OpenID Connect Webhook Authenticator for validation.
{
"TokenReview": {
"kind": "TokenReview",
"apiVersion": "authentication.k8s.io/v1",
"spec": {
"token": "ddeewfwef..."
}
}
}
The webhook then iterates over all registered OpenIDConnect
Token authenticators and tries to validate the token.
Upon a successful validation it returns the TokenReview
with user, groups and extra parameters:
{
"TokenReview": {
"kind": "TokenReview",
"apiVersion": "authentication.k8s.io/v1",
"spec": {
"token": "ddeewfwef..."
},
"status": {
"authenticated": true,
"user": {
"username": "test-admin@example.com",
"groups": [
"test-some-group"
],
"extra": {
"gardener.cloud/authenticator/name": [
"gardener"
],
"gardener.cloud/authenticator/uid": [
"e5062528-e5a4-4b97-ad83-614d015b0979"
]
}
}
}
}
}
It adds the following extra information, that can be used by custom authorizers later on:
gardener.cloud/authenticator/name
contains the name of the OpenIDConnect
authenticator which was used.gardener.cloud/authenticator/uid
contains the UID of the OpenIDConnect
authenticator which was used.Docker images are available here or you can choose to pull the latest pre-release version with the following command:
docker pull europe-docker.pkg.dev/gardener-project/public/gardener/oidc-webhook-authenticator:latest
For this setup the following components are needed:
The API server is started with --authentication-token-webhook-config-file
with kubeconfig
file pointing to the Webhook.
mkdir -p ~/.minikube/files/var/lib/minikube/certs
cp config/samples/minikube-webhook-kubeconfig.yaml ~/.minikube/files/var/lib/minikube/certs/minikube-webhook-kubeconfig.yaml
minikube start \
--extra-config=apiserver.authentication-token-webhook-config-file=/var/lib/minikube/certs/minikube-webhook-kubeconfig.yaml \
--extra-config=apiserver.authentication-token-webhook-cache-ttl=10s
To allow easy communication between the kube-apiserver
and the oidc-webhook-authenticator
minikube IP is added as control-plane.minikube.internal
in /etc/hosts
sudo sed -ie '/control-plane.minikube.internal/d' /etc/hosts
echo "$(minikube ip) control-plane.minikube.internal" | sudo tee -a /etc/hosts
Add the CRD:
kubectl apply -f config/crd/bases/authentication.gardener.cloud_openidconnects.yaml
Build the image, so it's accessible by minikube
:
minikube image build -t oidc-webhook-authenticator .
Deploy the oidc webhook authenticator.
kubectl apply -f config/samples/deployment.yaml
Create an OpenIDConnect
resource configured with your identity provider's settings (see an example here). Get a token from your identity provider. You can now authenticate against the minikube cluster.
curl -k -H "Authorization: Bearer $MY_TOKEN" $(k config view -o=jsonpath="{.clusters[?(@.name=='minikube')].cluster.server}")
Alternatively you can also use a token kubeconfig or the kubelogin plugin and configure an OIDC kubeconfig.