Asterrr's Handbook

Kubernetes security

The 4Cs of cloud native security, the API request path (authentication, authorization, admission), RBAC and ServiceAccounts, Pod Security Standards, Secrets, and image and supply chain security for KCNA.

Exam tasks: 2.2 (security)

The decision: for a given risk (a stolen kubeconfig, an over-privileged Pod, a leaked password, a vulnerable image), which layer of the stack and which Kubernetes control addresses it?

The 4Cs

  • Cloud (or data center): IAM for the provider account, firewalling the control plane, hardening nodes.
  • Cluster: who can call the API, what they may do, what Pods may run, how etcd is protected.
  • Container: trusted images, non-root users, no privileged mode, minimal capabilities.
  • Code: your application and its libraries.
  • Each layer depends on the one outside it. Perfect code doesn't help if anyone can reach an unprotected API server.

The API request path

Every request to the API server, from kubectl or a Pod, passes three gates in order:

GateQuestionMechanisms
AuthenticationWho is calling?X.509 client certificates, bearer tokens, OIDC (corporate identity providers), ServiceAccount tokens
AuthorizationIs this identity allowed this verb on this resource?RBAC (the standard), Node authorizer (for kubelets), Webhook, ABAC (rarely used)
AdmissionIs this object acceptable, and should it be changed?Built-in admission plugins, Pod Security Admission, ValidatingAdmissionPolicy (CEL), admission webhooks such as OPA Gatekeeper or Kyverno
  • Kubernetes has no User object. Human users exist only as names in certificates or tokens from an external identity source. ServiceAccounts are the in-cluster identities for workloads.
  • Admission runs mutating controllers first (they can change the object, for example add defaults), then validating ones (accept or reject).

Exam signal

"Reject Pods that use images from unapproved registries" or "require a team label on every Deployment" is an admission job (a policy engine such as Gatekeeper or Kyverno, or a ValidatingAdmissionPolicy). "Let this group read Pods in one namespace" is authorization (RBAC). "Log in with the company's SSO" is authentication (OIDC).

RBAC and ServiceAccounts

  • A Role lists allowed verbs (get, list, watch, create, update, delete...) on resources in one namespace. A ClusterRole does the same cluster-wide or for cluster-scoped resources such as nodes.
  • A RoleBinding or ClusterRoleBinding grants a role to subjects: users, groups or ServiceAccounts.
  • RBAC is allow-only. There are no deny rules; anything not granted is refused.
  • Every namespace has a default ServiceAccount, and Pods use it unless you set serviceAccountName.
  • Pods get a short-lived, automatically rotated projected token for their ServiceAccount. Set automountServiceAccountToken: false for Pods that never call the API.
  • Check permissions with kubectl auth can-i list secrets --as=system:serviceaccount:billing:invoice-worker -n billing.

Legacy: use bound, projected ServiceAccount tokens instead

Older clusters stored a non-expiring token for every ServiceAccount in an auto-created Secret. Since v1.24 these Secrets are no longer generated; Pods get time-bound tokens through the TokenRequest API instead.

Bind cluster-admin to fix a permission error

When a Pod gets 403 Forbidden, the tempting answer is a ClusterRoleBinding to cluster-admin. The exam wants least privilege: a Role with just the needed verbs and resources, bound in the right namespace to the Pod's own ServiceAccount.

Pod Security Standards

The Pod Security Standards define three profiles, and the built-in Pod Security Admission controller applies them per namespace through labels.

ProfileWhat it allowsUse for
PrivilegedEverythingSystem and infrastructure components (CNI, storage drivers)
BaselineBlocks known privilege escalations: privileged containers, host namespaces, hostPath, most added capabilitiesMost applications, as a default
RestrictedBaseline plus hardening: must run as non-root, drop all capabilities, no privilege escalation, a seccomp profileSecurity-sensitive workloads

Each namespace can set a profile per mode: enforce (reject violating Pods), audit (record in the audit log) and warn (show a warning to the user).

apiVersion: v1
kind: Namespace
metadata:
  name: reports
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/warn: restricted
  • Inside the Pod, the securityContext sets the actual values: runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation: false, capabilities.drop: ["ALL"], seccompProfile.

Legacy: use Pod Security Admission instead

PodSecurityPolicy was deprecated in v1.21 and removed in v1.25. Answers that create a PodSecurityPolicy are wrong for current Kubernetes.

Secrets

  • A Secret holds small sensitive values (passwords, tokens, TLS keys) and is mounted as files or exposed as environment variables.
  • Values are base64-encoded, not encrypted. Anyone who can read the Secret object can decode it.
  • Protect them by:
    • enabling encryption at rest in etcd (an EncryptionConfiguration on the API server, ideally with a KMS provider),
    • limiting get and list on Secrets with RBAC,
    • or keeping values in an external store (HashiCorp Vault, a cloud secret manager) synced by the External Secrets Operator or the Secrets Store CSI driver.
  • Mark Secrets immutable: true when they don't change, to prevent accidental edits.

base64 is encryption

"The Secret is safe because it's encoded" is wrong. Encoding is reversible by anyone. Real protection is encryption at rest plus tight RBAC, or an external secrets manager.

Images and supply chain

PracticeWhat it meansTools
Minimal imagesDistroless, Alpine or scratch base images: fewer packages, fewer CVEsMulti-stage builds
ScanningCheck images for known vulnerabilities in CI and in the registryTrivy, Grype, registry scanners
Signing and verificationSign images at build, verify signatures at admissionSigstore cosign, Notary Project
SBOMA software bill of materials lists every component in an imageSyft, SPDX, CycloneDX
Pin by digestReference image@sha256:... instead of a mutable tag like latestAdmission policies
Trusted registriesAllow only approved registriesGatekeeper or Kyverno policies

Protecting the cluster

  • API server: TLS everywhere, no anonymous access, RBAC, audit logging, private endpoint where possible.
  • etcd: holds all cluster state including Secrets. Restrict access to the API server only, use TLS, encrypt at rest, protect backups.
  • Nodes: patched OS, minimal packages, kubelet authentication and authorization enabled.
  • Runtime detection: Falco (CNCF graduated) watches system calls and alerts on suspicious behaviour, such as a shell started inside a container.
  • Network: default-deny NetworkPolicies, and mTLS from a service mesh for encryption in transit.
3 gates
Authentication, authorization, admission, in that order.
3 profiles
Privileged, Baseline, Restricted.
3 modes
enforce, audit, warn.
v1.25
PodSecurityPolicy removed.
base64
Secret encoding. Not encryption.

For RBAC hands-on, see the CKA page RBAC.

Scenarios

Scenario
A security team wants to make sure no Pod in namespace analytics can run as a privileged container or use the host network, while still allowing most normal applications. What is the simplest built-in way to do this?
Scenario
A developer says database passwords are safe because they are stored in Kubernetes Secrets. An auditor disagrees. Which statement is correct?
Scenario
Which step happens FIRST when the API server receives a request to create a Deployment?

Further reading

On this page