Home › CKS › Topics › Practice tasks › API Access & Data Protection
CKS · Cluster Setup

Lock Down an API Server Open to Anonymous Access

First, secure the cluster's API server configuring it as follows: Forbid anonymous authentication Use authorization mode Node,RBAC Use admission controller NodeRestriction The cluster uses the Docker…

Check live lab access → All CKS tasks

Live lab access

This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.

Create an account to continue →

Read this week's free task →

On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Context

For testing purposes, the kubeadm provisioned cluster's API server was configured to allow unauthenticated and unauthorized access.

Task

First, secure the cluster's API server configuring it as follows:

The cluster uses the Docker Engine as its container runtime. If needed, use the docker command to troubleshoot running containers.

kubectl is configured to use unauthenticated and unauthorized access. You do not have to change it but be aware that kubectl will stop working once you have secured the cluster.

> You can use the cluster's original kubectl configuration file located at /etc/kubernetes/admin.conf to access the secured cluster.

Next, to clean up, remove the ClusterRoleBinding system:anonymous.

*Lab note: this practice node runs containerd rather than the Docker Engine, so use crictl (or kubectl) where you would use docker.*

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. Everything below edits a control plane node, so use a throwaway kubeadm VM, never a shared or production cluster.

Authentication, authorization and admission: the three gates of the API server

Every request to kube-apiserver passes three gates in order. Authentication decides who is calling, authorization decides whether that identity may perform the verb, and admission plugins can still reject or modify the object afterwards. Hardening tasks usually mean one gate was left open, so know which flag controls which gate and how to prove the change from outside.

request ──→ authentication ──→ authorization ──→ admission ──→ etcd
            (--anonymous-auth)  (--authorization-mode)  (--enable-admission-plugins)
no credentials? ──→ user system:anonymous, group system:unauthenticated

1. Inspect before you touch anything

On a kubeadm node the API server is a static Pod defined in /etc/kubernetes/manifests/kube-apiserver.yaml. Read the three flags first, then ask the server what a caller with no credentials can do. Replace the address with your own control plane endpoint (kubeadm listens on port 6443 by default).

sudo grep -E -- '--(anonymous-auth|authorization-mode|enable-admission-plugins)' \
  /etc/kubernetes/manifests/kube-apiserver.yaml
APISERVER=https://192.0.2.10:6443
curl -sk "$APISERVER/version"
curl -sk "$APISERVER/api"

If --anonymous-auth is missing, it defaults to true. A request that carries no credentials is then not rejected; it is relabelled as user system:anonymous in group system:unauthenticated and handed to authorization. On a healthy RBAC cluster /version typically answers, because the default system:public-info-viewer role gives unauthenticated callers read access to non-sensitive cluster information. /api should return 403 Forbidden, since the discovery role is bound only to authenticated users. If /api returns the resource list, something is authorizing anonymous callers.

2. Know what each flag really means

Also hunt for RBAC bindings that hand rights to anonymous callers, since a binding to system:anonymous or system:unauthenticated reopens the door even with a correct mode list:

kubectl get clusterrolebindings -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.subjects[*].name}{"\n"}{end}' \
  | grep -E 'system:(anonymous|unauthenticated)'
kubectl auth can-i list secrets -A --as=system:anonymous --as-group=system:unauthenticated

3. Edit the static Pod safely

Copy the manifest outside the manifests directory first (the kubelet tries to run every file it finds there), then edit in place. The kubelet notices the change and recreates the API server; there is nothing to kubectl apply.

sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /root/apiserver-before.yaml
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
watch -n 2 'sudo crictl ps -a | grep kube-apiserver'

Expect the API to be unreachable for up to a minute. If no new container appears, read sudo journalctl -u kubelet for a YAML error, or check the exited container's logs with crictl logs for an unknown flag value.

4. Verify from both sides

Repeat the anonymous curl calls, then confirm an authenticated client still works with kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes. Any kubeconfig that relied on anonymous access now fails, as intended.

Common mistakes

Example checkEvidence
Anonymous callers rejectedcurl -sk $APISERVER/api returns 401 Unauthorized
No AlwaysAllow in the chain--authorization-mode value in the running container's command
Kubelets constrainedNodeRestriction appears in --enable-admission-plugins
Admins unaffectedkubectl --kubeconfig /etc/kubernetes/admin.conf get nodes succeeds

Cleanup: on a throwaway VM, restore your saved copy into the manifests directory or simply discard the VM. References: Authenticating, Authorization, Admission controllers, Static Pods. Next, try API server audit logging or kubelet authentication.

Exam
CKS
Domain
Cluster Setup
Grading
Programmatic · partial credit

What this tests

Lock down network access, the kubelet, API authentication, and ingress TLS, and run CIS benchmark checks. On the CKS exam, Cluster Setup tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKS tasks