Skip to main content
Gatekeeper and Kyverno are full-featured policy engines, but they require installing external controllers and CRDs. Pod Security Standards (PSS) are built into Kubernetes and let you enforce security baselines at the namespace level simply by adding labels — no extra operators required.
Pod Security Standards are label-driven and evaluated by Kubernetes’ built-in admission controller. Use warn to discover issues, audit to log them, and enforce to block non-compliant requests.

Profiles

PSS defines three profiles targeting common security postures:
A screenshot of the Kubernetes documentation page titled "Pod Security Standards." It shows a table describing the Privileged, Baseline, and Restricted policy profiles along with site navigation links in the sidebars.

Modes

Each profile can be applied in one of three modes:

How PSS is applied

PSS is label-driven. To set a profile and mode on a namespace, add one or more of these labels:
  • pod-security.kubernetes.io/enforce
  • pod-security.kubernetes.io/audit
  • pod-security.kubernetes.io/warn
Each label’s value is the profile name: privileged, baseline, or restricted. For example:
  • pod-security.kubernetes.io/enforce=baseline
  • pod-security.kubernetes.io/warn=restricted

Inspect namespaces and labels

List namespaces and show current labels:
Example output:

Apply PSS labels

Label the pss-baseline namespace to enforce baseline while auditing and warning for restricted:
Expected response:
Applying enforce can immediately block workloads in the target namespace. Verify workloads are compliant (or use warn/audit first) before enforcing to avoid downtime.

Test admission with a privileged pod (should be blocked)

Here is a manifest for a privileged pod that requests host networking and privilege escalation:
Apply it to the pss-baseline namespace:
Expected blocked response:

Test with a non-privileged pod (allowed by baseline, warns for restricted)

Create a simple nginx pod that does not request privileges:
Because audit=restricted and warn=restricted were set, you will see a warning showing how this pod fails the stricter restricted profile while the pod is still admitted: Example output:
This is useful to discover what changes are required before you move to enforce.

Enforce the restricted profile

Label the pss-restricted namespace to enforce restricted:
Expected:
Attempt to create the same simple nginx pod in the restricted namespace:
You should see the request blocked with specific violations:

Example compliant pod for restricted

A pod compliant with restricted typically:
  • runs as a non-root user (runAsNonRoot: true, runAsUser: 1000)
  • disables privilege escalation (allowPrivilegeEscalation: false)
  • drops all capabilities (capabilities.drop: ["ALL"])
  • sets a seccomp profile (seccompProfile.type: RuntimeDefault)
Example manifest:
Apply it to the pss-restricted namespace:
Expected:

Audit (warn) workflow — discover violations before enforcing

  • Use warn to surface violations when pods are created or updated. This helps teams discover compatibility issues without breaking workloads.
  • Use audit to log violations for monitoring and reporting.
Example — create a namespace and set warn=baseline:
Since the pod conforms to baseline, no warnings are produced and the pod is created:
Now change the warning label to restricted (use --overwrite to update labels) and create another pod:
You will see a warning at admission time identifying what would violate restricted, but the pod remains created:
Warnings appear at admission time in your terminal; you can also inspect events to find them.

Summary

  • Pod Security Standards provide a simple, built-in mechanism to enforce namespace-level security baselines without additional tooling.
  • Use:
    • warn — discover violations at admission time,
    • audit — log violations for later inspection,
    • enforce — block non-compliant requests.
  • Add labels to namespaces: pod-security.kubernetes.io/enforce|audit|warn=<profile>.
  • Iterate: start with warn/audit, fix workloads to be compliant, then move to enforce.
With this workflow you can progressively harden namespaces from baseline to restricted while avoiding surprises in production.

Watch Video

Practice Lab