kubernetes/kubernetes
Security
Kubernetes' security model has many layers. This page is a tour of where each layer lives in the codebase, in the order an attacker (or operator) would encounter it.
Trust boundaries
| Boundary | Defense |
|---|---|
| External user → kube-apiserver | TLS, authentication, authorization, admission, audit |
| kube-apiserver → etcd | mTLS + on-disk encryption-at-rest |
| Pod → kube-apiserver | Service-account tokens, NetworkPolicy |
| Pod → Pod | NetworkPolicy (enforced by CNI) |
| Pod → Node host | Pod Security Standards, AppArmor / SELinux / seccomp, runtime sandboxing |
| Node → kube-apiserver | Kubelet authn (cert), Node authorizer, NodeRestriction admission |
| Operator → secrets at rest | KMS encryption providers |
Authentication, authorization, admission
The triple-A pipeline is the front line. See systems/auth-and-admission.
Key takeaways:
- Anonymous requests get the
system:anonymousidentity unless explicitly disabled. - The Node authorizer + NodeRestriction admission together prevent a compromised kubelet from reading other nodes' Secrets.
- PodSecurity admission enforces the Pod Security Standards (Privileged / Baseline / Restricted) at namespace granularity.
- ValidatingAdmissionPolicy lets cluster admins write declarative CEL rules without webhooks.
Encryption at rest
Etcd content can be encrypted by the apiserver before write. Configuration via --encryption-provider-config (staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig).
Providers:
identity— no encryption (testing only).aescbc/aesgcm— symmetric, in-process keys read from the config file.kmsv1 / v2 — delegate envelope encryption to a KMS plugin (staging/src/k8s.io/kms). Vendors run a sidecar that talks to AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault, etc.secretbox— NaCl secretbox (legacy; consider AES instead).
Best practice for production: KMS v2.
Service-account tokens
A Pod's identity is its ServiceAccount. The default behaviour:
- The kubelet projects a bound token into the Pod via
projectedvolume'sserviceAccountTokensource. The token has an audience and an expiration; the kubelet rotates it before expiry. - Legacy auto-generated tokens (the SA controller's secrets) are disabled by default in modern clusters via the
LegacyServiceAccountTokenNoAutoGenerationfeature gate.
Token issuance is in pkg/serviceaccount/. The TokenRequest API is in staging/src/k8s.io/api/authentication/v1.
Bound tokens are validated by the apiserver via JWT signature + audience check. Custom audiences let workloads use the same SA token to talk to non-Kubernetes services that trust the cluster's issuer.
Pod security
staging/src/k8s.io/pod-security-admission/ implements the Pod Security Standards. Three levels:
| Level | Default | Privileged ops |
|---|---|---|
privileged |
All Pods | All allowed |
baseline |
Most Pods | No HostNetwork/PID/IPC, no privileged containers, no host paths to system dirs |
restricted |
Hardened workloads | + drop all capabilities, runAsNonRoot, seccomp RuntimeDefault, etc. |
Namespaces opt into a level via labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restrictedThe admission plugin is registered in pkg/kubeapiserver/options/plugins.go.
Runtime hardening
Kubernetes itself doesn't sandbox containers — that's the runtime's job. But the kubelet plumbs through:
- AppArmor / SELinux profile names to the runtime.
- seccomp profiles (
RuntimeDefaultis the recommended default; custom profiles viasecurityContext.seccompProfile). runAsNonRoot,runAsUser,fsGroup— UID / GID enforcement at the runtime.- User namespaces (alpha) — map container UIDs to non-root host UIDs. Code in
pkg/kubelet/userns/. - Capabilities — drop / add Linux capabilities per container.
CertificateSigningRequest
CSR is the cluster's way of issuing certificates without operator intervention. The kubelet uses CSRs to:
- Bootstrap its initial client cert (signed by
kubernetes.io/kube-apiserver-client-kubelet). - Rotate its serving cert (signed by
kubernetes.io/kubelet-serving).
Approval is automated by the certificate-approval controller (pkg/controller/certificates/approver/) for predictable patterns; signing is done by the certificate-signing controller (pkg/controller/certificates/signer/). Manual approval (kubectl certificate approve) is the escape hatch.
Supply-chain controls
- The repo uses Go modules with a vendored
vendor/directory.hack/lint-dependencies.shcheckshack/unwanted-dependencies.json. - All commits require DCO sign-off and CLA.
- Release artifacts are signed; checksums are published.
- Container images are pushed to
registry.k8s.iowith image signing via Sigstore / cosign (out-of-tree tooling).
Reporting a vulnerability
The repo's SECURITY_CONTACTS lists the responsible disclosure addresses. The process is documented at kubernetes.io/security. Do not open a public issue.
Key source files
| File | Purpose |
|---|---|
pkg/kubeapiserver/authenticator/config.go |
Authentication chain |
pkg/kubeapiserver/authorizer/config.go |
Authorization chain |
pkg/kubeapiserver/admission/config.go |
Admission chain |
staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/ |
Encryption-at-rest |
staging/src/k8s.io/pod-security-admission/ |
Pod Security Standards |
plugin/pkg/auth/authorizer/node/ |
Node authorizer |
plugin/pkg/admission/noderestriction/ |
NodeRestriction admission |
pkg/serviceaccount/ |
Service-account token minting + validation |
pkg/controller/certificates/ |
CSR controllers |
staging/src/k8s.io/kms/ |
KMS plugin contract |
pkg/kubelet/userns/ |
User namespaces |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.