Challenge
DifficultyHard
Learner activity No attempts yet

Secure the Kubernetes API Server: Disable Anonymous Auth and AlwaysAllow Authorization

The API server was misconfigured with anonymous authentication enabled and authorization set to AlwaysAllow. A ClusterRoleBinding also grants explicit permissions to system:anonymous. Fix all three issues to secure the cluster.

Scenario

The cluster has three security misconfigurations that together allow unauthenticated, unrestricted access to the Kubernetes API — anyone who can reach port 6443 can query resources with no credentials.

Your job is to identify and close all three gaps.


Task

The API server manifest is at /etc/kubernetes/manifests/kube-apiserver.yaml.

Fix the following in the manifest:

  • Set --anonymous-auth=false
  • Replace --authorization-mode=AlwaysAllow with --authorization-mode=Node,RBAC

The kubelet will automatically restart the API server when the manifest changes.

Also delete the ClusterRoleBinding that grants permissions to system:anonymous:

kubectl get clusterrolebinding -o wide | grep anonymous

Once the API server restarts, anonymous requests must return 401 Unauthorized:

curl -k https://localhost:6443/api/v1/namespaces

Hint 1 — Fix Both Flags in the API Server Manifest

Grep for both flags to find the exact lines:

grep -n "anonymous-auth\|authorization-mode" \
  /etc/kubernetes/manifests/kube-apiserver.yaml

Edit the file and update both:

vi /etc/kubernetes/manifests/kube-apiserver.yaml
  • --anonymous-auth=true → --anonymous-auth=false
  • --authorization-mode=AlwaysAllow → --authorization-mode=Node,RBAC

Documentation

Hint 2 — Delete the ClusterRoleBinding for system:anonymous

List all ClusterRoleBindings referencing system:anonymous:

kubectl get clusterrolebinding -o wide | grep anonymous

Delete the binding:

kubectl delete clusterrolebinding anonymous-binding

Documentation

Hint 3 — Wait for the API Server to Restart and Verify

After saving the manifest changes, wait for the API server to come back:

kubectl wait --for=condition=Ready pod -l component=kube-apiserver \
  -n kube-system --timeout=90s

Then verify anonymous access is blocked:

curl -sk -o /dev/null -w "%{http_code}" \
  https://localhost:6443/api/v1/namespaces

401 = success. If you still get 200, check both flags in the manifest are correct and the pod has fully restarted.

Documentation


⚒ Test Cases
Problem
Start