Proof-Of-Concept : Kubernetes webhook authentication and authorization for OpenStack Keystone
Steps to use this webook with Kubernetes
- Save the following into webhook.kubeconfig.
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://localhost:8443/webhook
name: webhook
contexts:
- context:
cluster: webhook
user: webhook
name: webhook
current-context: webhook
kind: Config
preferences: {}
users:
- name: webhook
- Add the following flags to your Kubernetes api server.
--authentication-token-webhook-config-file=/path/to/your/webhook.kubeconfig
--authorization-mode=Node,RBAC
- Start webhook process with the following flags
--tls-cert-file /var/run/kubernetes/serving-kube-apiserver.crt
--tls-private-key-file /var/run/kubernetes/serving-kube-apiserver.key
--keystone-policy-file examples/policy.json
--keystone-url https://my.keystone:5000/v3
- Copy the examples/policy.json and edit it to your needs.
- Add the following flags to your Kubernetes api server.
--authorization-mode=Webhook,Node --authorization-webhook-config-file=/path/to/your/webhook.kubeconfig
- When you start the webhook process make sure you also have the following flags (in addition to the flags in the case of authentication)
--keystone-policy-file examples/policy.json
- Run
openstack token issue
to generate a token - Run
kubectl --token $TOKEN get po
orcurl -k -v -XGET -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" https://localhost:6443/api/v1/namespaces/default/pods
The client is able to read the OS_
env variables used also by the openstackclient. You dont have to pass a token with --token
, but the client will contact Keystone directly, will get a token and will use it. To configure the client to the following:
- Run
kubectl config set-credentials openstackuser --auth-provider=openstack
This command creates the following entry in your ~/.kube/config
- name: openstackuser
user:
as-user-extra: {}
auth-provider:
name: openstack
- Run
kubectl config set-context --cluster=kubernetes --user=openstackuser openstackuser@kubernetes
- Run
kubectl config use-context openstackuser@kubernetes
to activate the context
Source your env vars. Make sure you include OS_DOMAIN_NAME
or the client will fallback to Keystone V2 that is not supported by the webhook.This env should be ok:
OS_AUTH_URL="https://keystone.example.com:5000/v3"
OS_DOMAIN_NAME="default"
OS_IDENTITY_API_VERSION="3"
OS_PASSWORD="mysecret"
OS_PROJECT_NAME="myproject"
OS_REGION_NAME="myRegion"
OS_USERNAME="username"
- Try:
kubectl get pods
In case you are using this Webhook just for the authentication, you should get an authorization error:
Error from server (Forbidden): pods is forbidden: User "username" cannot list pods in the namespace "default"
You need to configure the RBAC with roles to be authorized to do something, for example:
kubectl create rolebinding username-view --clusterrole view --user username --namespace default
Try now again to see the pods with kubectl get pods
More details about Kubernetes Authentication Webhook using Bearer Tokens is at : https://kubernetes.io/docs/admin/authentication/#webhook-token-authentication
and the Authorization Webhook is at: https://kubernetes.io/docs/admin/authorization/webhook/
- You can directly test the webhook with
cat << EOF | curl -kvs -XPOST -d @- https://localhost:8443/webhook | python -mjson.tool
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"metadata": {
"creationTimestamp": null
},
"spec": {
"token": "$TOKEN"
}
}
EOF
cat << EOF | curl -kvs -XPOST -d @- https://localhost:8443/webhook | python -mjson.tool
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "kittensandponies",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
EOF