A library for writing admission webhooks based on k8s.io/apiserver
import "github.com/openshift/generic-admission-server/pkg/cmd"
func main() {
cmd.RunAdmissionServer(&admissionHook{})
}
// where to host it
func (a *admissionHook) ValidatingResource() (plural schema.GroupVersionResource, singular string) {}
// your business logic
func (a *admissionHook) Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse {}
// any special initialization goes here
func (a *admissionHook) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {}
This library helps you to write secure Admission Webhooks. It uses TLS authentication and authorization mechanisms which are built into the Kubernetes aggregated API server library, which means that your webhooks are secure by default.
Using this library allows you to avoid the complication of creating and maintaining a client key and certificate for each webhook server;
you only need to maintain a server key and certificate for each webhook server.
And by using this library your webhook will also perform authorization which uses Kubernetes' own SubjectAccessReview
and RBAC
mechanisms.
Deploy your webhook as an aggregated API server.
This provides one or more new Kubernetes API endpoints which are served by the Kubernetes API server its self.
E.g. /apis/admission.core.example.com/v1/flunders
Ensure that these endpoints are accessible before continuing.
Then configure admission webhooks which target this new endpoint on the Kubernetes API server. E.g.
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: example-webhook
webhooks:
- name: admission.core.example.com
rules:
- apiGroups:
- "core.example.com"
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- flunders
failurePolicy: Fail
clientConfig:
service:
name: kubernetes
namespace: default
path: /apis/admission.core.example.com/v1/flunders
caBundle: $CA_BUNDLE
In this way, the MutatingAdmissionWebhook or ValidatingAdmissionWebhook admission controllers, running in the Kubernetes API server process, are looping back to the main Kubernetes API service.
Kubernetes API servers connect to webhook servers using TLS encrypted HTTPS connections.
In a production environment, the Kubernetes API servers should also be configured to authenticate themselves to webhook servers,
and your webhook servers should verify the authenticity of the requests they receive from Kubernetes API servers.
But this is (currently) rather complicated to maintain because you have to provide a kubeConfig
file containing the client authentication configuration for each webhook server.
An alternative approach, used by this library, is to deploy the webhook server as a Kubernetes aggregated API server.
The advantage of this approach is that the mechanism for establishing mutual authentication between the Kubernetes API server and aggregate API servers is more mature and easier to maintain.
In this mechanism, Kubernetes takes care of generating the client authentication credentials that it uses when connecting to aggregate API servers.
And the aggregate API server then reads these client credentials from a standardized ConfigMap
at kube-system/extension-apiserver-authentication
.
The Kubernetes API server library takes care of all this for you.
Additional security is provided because the webhook aggregate API server authorizes the request.
The webhook aggregate API server will receive the username and group of the user or service account that made the request that triggered the web hook.
And it will check, using a SubjectAccessReview
, that that original user has permission to interact with this webhook API.
Admission webhooks have tremendous power over what can and cannot be created in the API. They can see, validate, and in some cases mutate every object in the cluster, so it is vital that the API server can verify that it is connecting to an authentic webhook server. And it is also vital that a webhook server can verify that it is receiving requests from an authentic Kubernetes API server. Kubernetes will eventually deprecate and remove all unencrypted HTTP APIs.
For testing purposes, you can create a private key and a self-signed certificate using openssl
or cfssl
.
In production, you must implement a process for rotating the certificates. For example:
- OpenShift Service CA Operator: Controller to mint and manage serving certificates for Kubernetes services.
- cert-manager: A controller for automatically provisioning and managing TLS certificates in Kubernetes.
Here are a selection of webhooks which use the Openshift Generic Admission Server:
- Openshift Kubernetes Namespace Reservation: An admission webhook that prevents the creation of specified namespaces.
- Quack: In-Cluster templating for Kubernetes manifests.
- Cert-Manager Validating Webhook: Allows cert-manager to validate that Issuer, ClusterIssuer and Certificate resources that are submitted to the apiserver are syntactically valid.
- Anchore Image Validator: Lets you automatically detect or block security issues just before a Kubernetes pod starts.