An ultra-fast, secure, and visual Webhook receiver for Kubernetes Cluster Auditing written in pure Go.
The Kubernetes Audit Webhook Backend is a microservice designed specifically to receive and store Security and Audit logs generated by the kube-apiserver (Master Control Plane).
Whenever your Kubernetes infrastructure configures an Audit Webhook, the log stream will be dispatched via HTTP POST requests containing giant JSON payloads with metadata about who modified what, when, and how within the Cluster.
This microservice captures this data in bulk, parses the structures, injects persistent UUIDs via Lexicographical sorting, stores it in MySQL/MariaDB using Batch Inserts, and finally, provides a beautiful Web Interface (created in SSR with HTMX, Tailwind, and Alpine) to search and track the events in real-time.
- Centralize the security compliance of N interconnected clusters through Multicluster support via URL (e.g.,
?cluster=prod). - Understand exactly who altered a given Secret, deployed a suspicious Pod, or deleted configurations in Kubernetes through humanized extraction of the payloads.
- Perform native reverse engineering of auditevents, directly converting them into identical
kubectlcommands used by the users (Visual Simulation).
This project was built with extreme efficiency and portability in mind using the Go Native templating tool (a-h/templ). There is no NodeJS on the server.
- Golang 1.22+
- MySQL/MariaDB server running.
You will need to create a .env file in the root of the project containing your Database credentials. The application itself will create the tables and indexes if the database is empty:
# Environment (development | production)
ENVIRONMENT=development
# HTTP Port Exposed by the Service
HTTP_PORT=8080
# Secure Authentication Key (Bearer Token) optional
# Used by Kube-APIServer to authenticate against this backend
WEBHOOK_TOKEN=my-super-secret-token
# Database Connection
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=secret
DB_NAME=audit_dbYou can run locally with our native Makefile which also automatically downloads dependencies for HTMX template compilations:
make runAccess http://localhost:8080 in your browser!
This project includes a multi-stage Dockerfile that builds a tiny, secure, and production-ready distroless image containing only the compiled Go binary.
To build the image:
docker build -t k8s-audit-webhook:latest .To run the container, remember to pass the Environment Variables using a .env file or directly in the command, and map the HTTP port:
docker run -p 8080:8080 --env-file .env k8s-audit-webhook:latestAfter publishing this API via Ingress/Docker in your company, open the master nodes of your Kubernetes cluster (where the kube-apiserver binary runs) and edit the Control Plane's initialization flags:
Create the files pointing to this tool in /etc/kubernetes:
/etc/kubernetes/audit-policy.yaml (Filters what goes to the Webhook):
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: None
userGroups: ["system:serviceaccounts", "system:nodes"]
- level: None
users: ["system:apiserver", "system:anonymous"]
- level: Metadata # The Minimum Level Required by the UI!/etc/kubernetes/webhook-config.yaml (Where this backend is hosted):
apiVersion: v1
kind: Config
clusters:
- name: k8s-audit-webhook
cluster:
server: https://YOUR-API-IN-PROD.com/webhook/audit/cluster-prod
users:
- name: k8s-apiserver
user:
# If you set the WEBHOOK_TOKEN var in the backend, put the exact SAME KEY below
token: "my-super-secret-token"
contexts:
- name: webhook-context
context:
cluster: k8s-audit-webhook
user: k8s-apiserver
current-context: webhook-contextIf using kubeadm, add these flags when editing /etc/kubernetes/manifests/kube-apiserver.yaml to activate the two webhook rules proposed above by Kubernetes:
spec:
containers:
- command:
- kube-apiserver
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-webhook-config-file=/etc/kubernetes/webhook-config.yaml
- --audit-webhook-truncate-enabled=true
- --audit-webhook-batch-max-size=500
- --audit-webhook-batch-max-wait=3s
# ... your existing commands ...
volumeMounts:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit-policy
readOnly: true
- mountPath: /etc/kubernetes/webhook-config.yaml
name: audit-webhook
readOnly: true
# ... your existing volumeMounts ...
volumes:
- hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: FileOrCreate
name: audit-policy
- hostPath:
path: /etc/kubernetes/webhook-config.yaml
type: FileOrCreate
name: audit-webhook
# ... your existing volumes ...
⚠️ CRITICAL WARNING: Because thekube-apiserverruns as a Static Pod container, it cannot see the files dynamically created on your host filesystem by default. It is mandatory that you map the two files you just created in/etc/kubernetesinto the container using thevolumesandvolumeMountskeys in the manifest!
(The Apiserver will automatically reset the container when you save the file!)
The project follows Clean Architecture principles as documented in GEMINI.md.
pkg/handler: HTMX/JSON Delivery Layer and Templates. Never touches SQL directly.pkg/service: The orchestrator brain. Abstract interfaces with vital reverse engineering logic.pkg/service/internal/repository: Contains absolute exclusivity in MySQL/MariaDB manipulation routines using dry queries without giant ORMs in order to maintain the max possible Log Ingestion performance per second.
The tool possesses a robust architecture with high coverage of all business logic using only Native Net-Http test libraries. To verify the metrics on your machine:
make coverInstantly opens the green tested blocks in an interactive .html page format.

