Skip to main content

Pod Security Admission

Purpose: For security officers, provides PSA configuration via Kubespray including admission controller list and API server flags.

Overview

Pod Security Admission (PSA) is a built-in Kubernetes admission controller that enforces the Pod Security Standards at the namespace level. openCenter configures PSA at cluster provisioning time through Kubespray's k8s_hardening.yml, applying cluster-wide defaults that affect all namespaces unless explicitly exempted.

Configuration

PSA is configured via the following Kubespray variables in group_vars/all/k8s_hardening.yml:

# Admission controllers enabled on the API server
kube_apiserver_enable_admission_plugins:
- PodSecurity
- EventRateLimit
- AlwaysPullImages

# Pod Security Admission defaults (cluster-wide)
kube_pod_security_default_enforce: baseline
kube_pod_security_default_enforce_version: latest
kube_pod_security_default_audit: restricted
kube_pod_security_default_audit_version: latest
kube_pod_security_default_warn: restricted
kube_pod_security_default_warn_version: latest

These translate to API server flags:

--admission-control-config-file=/etc/kubernetes/admission-control/admission-control-config.yaml

Pod Security Standards

LevelEnforcementBehavior
baselineenforceRejects pods that violate baseline rules (privileged, hostPID, hostNetwork, etc.)
restrictedauditLogs violations to the API server audit log but does not reject
restrictedwarnReturns a warning to the client (visible in kubectl output) but does not reject

The baseline profile blocks the most dangerous pod configurations. The restricted profile is stricter (requires runAsNonRoot, drops all capabilities, restricts volume types) but is applied only in audit/warn mode to avoid breaking workloads that have not yet been hardened.

Namespace-Level Overrides

Individual namespaces can override the cluster defaults using labels:

apiVersion: v1
kind: Namespace
metadata:
name: hardened-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest

Platform namespaces (e.g., flux-system, kyverno) may require baseline or privileged enforcement depending on their workload requirements. These exemptions are documented in the cluster's overlay configuration.

Verification

Check the effective PSA configuration for a namespace:

kubectl get namespace <namespace> -o jsonpath='{.metadata.labels}' | jq .

Test a pod against the enforced profile without creating it:

kubectl run test-pod --image=nginx --dry-run=server -o yaml

If the pod violates the enforced profile, the API server returns an error. If it violates the audit/warn profile, the response includes a warning header.

Review audit log entries for PSA violations:

# On a control plane node
grep "PodSecurity" /var/log/kubernetes/audit/audit.log | tail -20

Behaviors and Edge Cases

  • PSA evaluates the pod spec at admission time. Changing namespace labels does not retroactively affect running pods.
  • The latest version tracks the cluster's Kubernetes version. Pinning to a specific version (e.g., v1.29) freezes the policy definitions.
  • PSA runs before webhook-based admission controllers (Kyverno). A pod rejected by PSA never reaches Kyverno.
  • The privileged level permits all pod configurations and is equivalent to disabling PSA for that namespace.

Further Reading