KubernetesLXII · Pod Security StandardsPod Security Standards
Baseline profile — preventing known privilege escalations
What you'll learn
- Identify what `baseline` forbids and what it allows
- Use `baseline` for multi-tenant and untrusted workloads
- Write a manifest that passes `baseline` but fails `restricted`
- Recognise the failure modes of `baseline` and when to migrate to `restricted`
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
The baseline profile is the middle ground: it
forbids the most common privilege escalations while
allowing common operational patterns. It is the right
choice for multi-tenant clusters and untrusted
workloads; production clusters should migrate to
restricted where possible.
What baseline forbids
| Field | Baseline | Rationale |
|---|---|---|
securityContext.privileged: true | Forbidden | Privileged containers can escape the runtime |
hostNetwork: true | Forbidden | Sharing the node network namespace is a privilege escalation primitive |
hostPID: true | Forbidden | Sharing the node PID namespace allows process inspection |
hostIPC: true | Forbidden | Sharing the node IPC namespace allows memory access |
hostPath volumes | Limited (specific paths) | HostPath can escape the runtime to the host filesystem |
Specific capabilities (SYS_ADMIN, etc.) | Forbidden | Broad capabilities enable privilege escalation |
The baseline profile is the floor for hardening; it
prevents the well-known escalation paths.
What baseline allows
| Field | Baseline |
|---|---|
securityContext.runAsUser: 0 (root) | Allowed |
hostPath (specific paths) | Allowed |
capabilities.add: ["NET_BIND_SERVICE"] | Allowed |
allowPrivilegeEscalation: true | Allowed |
seccompProfile: Unconfined | Allowed |
These fields are allowed because they are common in
operational workloads. The restricted profile
tightens each one.
A baseline manifest
A Pod that passes baseline but fails restricted:
apiVersion: v1
kind: Pod
metadata:
name: ci-runner
namespace: ci
spec:
securityContext:
runAsUser: 0 # baseline: allowed
fsGroup: 1000
containers:
- name: runner
image: ci-runner:v1.0
securityContext:
allowPrivilegeEscalation: true # baseline: allowed
capabilities:
add: ["NET_ADMIN"] # baseline: allowed (NET_ADMIN is not on the forbidden list)
volumeMounts:
- name: workspace
mountPath: /workspace
- name: cache
mountPath: /cache
volumes:
- name: workspace
emptyDir: {}
- name: cache
hostPath:
path: /var/cache/ci # baseline: allowed (specific path)
type: Directory
The Pod is admitted in ci (enforce: baseline).
In prod (enforce: restricted), it would be
rejected for: running as root with no
runAsNonRoot, allowPrivilegeEscalation: true, the
NET_ADMIN capability without drop: ["ALL"], the
hostPath volume, and the missing seccompProfile.
A baseline with restricted migration plan
The baseline profile is a step on the way to
restricted. The migration:
warn: restricted. Surface the violations without rejecting workloads.- Fix the small violations. Add
runAsNonRoot: true,seccompProfile: RuntimeDefault. - Fix the medium violations. Replace
hostPathwith CSI volumes; remove root. - Switch to
audit: restricted. Capture remaining violations in the audit log. - Switch to
enforce: restricted. Reject the remaining violations.
The migration is per-namespace; the team tracks each namespace’s progress in a spreadsheet.
Production patterns
baselinefor multi-tenant. Untrusted workloads run withbaseline. The discipline is noprivileged, no host namespaces.baselineas a transition. Workloads that cannot passrestrictedrun withbaselinetemporarily. The team has a deadline to migrate.baselinefor build runners. CI runners needhostPathfor cache mounts and broad capabilities for tooling.baselineallows them;restricteddoes not.
Production failure modes
- A workload uses
privileged: truein abaselinenamespace. The Pod is rejected; the team changes the namespace toprivilegedto “fix” it. The fix is to remove the field, not to relax the namespace’s PSS. - A
hostPathto a non-allowed path. The Pod is rejected inbaseline. The fix is to useemptyDiror a CSI volume. hostNetwork: trueon a workload that does not need it. The Pod is rejected inbaseline. The fix is to remove the field.- No migration to
restricted. A namespace stays onbaselineindefinitely. The fix is to set a migration deadline per namespace.
Cross-course references
- The Observability course covers the audit log
entries for
baselineviolations. - The Linux course covers the kernel features that
baselineenforces.
Quiz
Knowledge check · 4 questions
Q1. Which of the following fields is *allowed* by `baseline` but *forbidden* by `restricted`?
Q2. The `baseline` profile forbids all `hostPath` volumes.
Q3. Your `ci` namespace has `enforce: baseline`. The CI runners use `hostPath: /var/cache/ci` for cache mounts and `capabilities.add: ["NET_ADMIN"]` for network tooling. You want to migrate to `restricted`. Walk the response.
The CI runners have been running on `baseline` for two years. The `hostPath` is needed for performance (cache mount); the `NET_ADMIN` capability is needed for an iperf-based network test. The migration to `restricted` requires removing both.
Q4. Name three fields that are allowed by `baseline` but forbidden by `restricted`.
Passing score: 75%. Answers are checked in this browser.
Production discipline
The baseline profile is the right choice for
multi-tenant clusters and as a transition to
restricted. The discipline is to default to
restricted for trusted workloads, use baseline
for untrusted or transitional workloads, and document
every namespace that is on baseline. A cluster
whose namespaces are mostly restricted and has
documented baseline exceptions has a PSS programme
that is auditable.