Kubernetes can be confusing. Finally there is an API to take the confusion out of user privilege requests, just drop in this webhook server. It's pure Go and has zero dependencies.
How often do you sit there scratching your head thinking "surely this must be someone else's fault"? Now you can say it with confidence! Register this server as an authorization webhook and be confident there is a 50% shot things are not broken because of you.
==> main.go <==
package main
import (
"encoding/json"
"math/rand"
"net/http"
)
type Result struct {
Status bool `json:"status"`
Reason string `json:"reason"`
}
type Authorization struct {
ApiVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Result Result `json:"allowed"`
}
func AuthorizationHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case "POST":
w.WriteHeader(http.StatusOK)
var returnValue Result
if rand.Float32() < 0.5 {
returnValue = Result{false, "we both know why"}
} else {
returnValue = Result{true, "acceptable"}
}
response :=
Authorization{
"authorization.k8s.io/v1beta1",
"SubjectAccessReview",
returnValue,
}
json.NewEncoder(w).Encode(response)
default:
w.WriteHeader(http.StatusBadRequest)
response := make(map[string]string)
response["error"] = "only POST methods are supported"
json.NewEncoder(w).Encode(response)
}
}
func main() {
http.HandleFunc("/authorize", AuthorizationHandler)
http.ListenAndServe(":8080", nil)
}
==> Makefile <==
all: kubernetes-auth.raw
kubernetes-auth: main.go
CGO_ENABLED=0 go build -tags netgo
kubernetes-auth.raw: kubernetes-auth kubernetes-auth.service os-release
( rm -rf build && \
mkdir -p build/usr/bin build/usr/lib/systemd/system build/etc build/proc build/sys build/dev build/run build/tmp build/var/tmp build/var/lib/kubernetes-auth && \
cp kubernetes-auth build/usr/bin/ && \
cp kubernetes-auth.service build/usr/lib/systemd/system && \
cp os-release build/usr/lib/os-release && \
touch build/etc/resolv.conf build/etc/machine-id && \
rm -f kubernetes-auth.raw && \
mksquashfs build/ kubernetes-auth.raw )
clean:
go clean
rm -rf build
rm -f kubernetes-auth.raw
.PHONY: all clean
==> kubernetes-auth.service <==
[Unit]
Description=Kubernetes Auth Service
After=network.target
[Service]
ExecStart=/usr/bin/kubernetes-auth
Type=exec
DynamicUser=yes
ProtectProc=invisible
ProcSubset=pid
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources
==> os-release <==
PORTABLE_PRETTY_NAME="Kubernetes Auth"
PORTABLE_ID=kubernetes-auth
PRETTY_NAME=SillyOS
ID=sillyos
I agree, which is why the above is a definition for creating the
server as a squashfs filesystem image packaged with the necessary
configuration for running the server as a portable service under
systemd. With the above you can call make
and produce a
single binary of approximately 3MB. Use it on any systemd machine
with: portablectl attach --now
kubernetes-auth.raw
. That's it!
It has been a few years and I've turned this off - you'll have to use your imagination or run it yourself.
You are obviously a person of discerning taste, as such I have made
available a server for demonstration, testing and production use. It
is of course secured by TLS for topmost security, as required
by the
spec.
You can find
it
https://nprescott.com/kubernetes/authorize
curl -X POST https://nprescott.com/kubernetes/authorize
Integrating this server into your Kubernetes API server is left as an exercise for the reader — it should be a small matter of YAML programming.