Implementing a Webhook for Authorization
Learn how to implement a webhook authorization service.
Implement a webhook authorization service
A webhook authorization service is a web server, because the kube-apiserver
invokes it through HTTPS POST
requests.
Now, let’s implement such a service step by step.
Step 1: Write a simple HTTP server
Let’s write a simple HTTP server that responds with the mock authenticated user mock
when requested for the /authorize
resource over port 443
.
package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" authorizationapi "k8s.io/api/authorization/v1beta1" ) func authZ(sar *authorizationapi.SubjectAccessReview) { // now we do some mock for demo // Please replace this with your logic if sar.Spec.User == "demo-user" { sar.Status.Allowed = true } else { sar.Status.Reason = fmt.Sprintf("User %q is not allowed to access %q", sar.Spec.User, sar.Spec.ResourceAttributes.Resource) } } func helloHandler(w http.ResponseWriter, r *http.Request) { log.Printf("Receiving %s", r.Method) if r.Method != "POST" { http.Error(w, "Only Accept POST requests", http.StatusMethodNotAllowed) return } // Read body of POST request payload, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } log.Printf("Receiving SubjectAccessReview: %s\n", string(payload)) // Unmarshal JSON from POST request to SubjectAccessReview object sar := &authorizationapi.SubjectAccessReview{} err = json.Unmarshal(payload, sar) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } authZ(sar) // Marshal the SubjectAccessReview to JSON and send it back result, err := json.Marshal(*sar) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(result) w.Header().Set("Content-Type", "application/json") } func main() { // Set up a /authorize resource handler http.HandleFunc("/authorize", helloHandler) // Listen to port 443 and wait log.Println("Listening on port 443 for requests...") log.Fatal(http.ListenAndServe(":443", nil)) }
HTTP server
In a real-world scenario, we only need to replace the mock codes in the function authZ()
with our actual implementations to determine user privileges. This function should set Status.Allowed
to true
if the request performed by the user is allowed and false
for invalid requests. For the denied reason, it can be set to the field Status.Reason
.
The rest of the code is a simple ...
Access this course and 1400+ top-rated courses and projects.