<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-pod-security-standards
description: >-
  Implement and enforce Kubernetes Pod Security Standards (PSS) using Pod
  Security Admission (PSA) controllers, namespace labels, and policy engines
  to prevent privileged workload deployment.
domain: cybersecurity
subdomain: container-security
tags:
  - pod-security-standards
  - psa
  - pss
  - kubernetes
  - admission-control
  - least-privilege
  - namespace-security
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1610"]
---

# Implementing Pod Security Standards

## Overview

Pod Security Standards (PSS) define three levels of pod security restriction —
Privileged, Baseline, and Restricted — enforced through Pod Security Admission
(PSA) namespace labels or policy engines like Kyverno and OPA Gatekeeper. This
skill covers assessment, labeling, policy authoring, and dry-run validation to
incrementally harden cluster workloads without breaking deployments.

Mode: `[MODE: BLUE]` — Defensive admission control and workload hardening.

## Prerequisites

- Kubernetes >= 1.25 (PSA GA)
- kubectl configured with cluster-admin access
- OPA Gatekeeper or Kyverno for custom policies
- Namespace-level RBAC permissions

## Key Concepts

### Pod Security Standards Levels

| Level | Description |
|-------|-------------|
| **Privileged** | Unrestricted — allows all pod configurations |
| **Baseline** | Minimally restrictive — prevents known privilege escalations |
| **Restricted** | Heavily restricted — follows hardening best practices |

### Applying PSA Labels to Namespaces

```bash
# Enforce restricted standard on production namespace
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

# Verify namespace labels
kubectl get namespace production -o jsonpath='{.metadata.labels}' | jq .

# Apply baseline to staging with warning
kubectl label namespace staging \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/warn=restricted
```

### Dry-Run Evaluation

```bash
# Check if existing pods would violate a standard
kubectl label --dry-run=server --overwrite namespace default \
  pod-security.kubernetes.io/enforce=restricted

# List pods violating restricted standard
kubectl get pods -n default -o json | jq '
  .items[] | select(.spec.containers[].securityContext.runAsNonRoot != true)
  | .metadata.name'
```

### Kyverno Policy Enforcement

```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged-containers
spec:
  validationFailureAction: Enforce
  rules:
    - name: deny-privileged
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Privileged containers are not allowed."
        pattern:
          spec:
            containers:
              - securityContext:
                  privileged: "false"
```

### OPA Gatekeeper Constraint

```yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
  name: deny-privileged-containers
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    excludedNamespaces:
      - kube-system
```

## Workflow

### Step 1: Audit Current Namespace Standards

```bash
kubectl get namespaces -o json | jq '.items[] | {
  name: .metadata.name,
  enforce: .metadata.labels["pod-security.kubernetes.io/enforce"] // "none"
}'
```

### Step 2: Run PSS Compliance Check

```bash
node scripts/agent.js --context ~/.kube/config --namespace production \
  --output /tmp/pss-report.json
```

### Step 3: Apply Enforcement Labels

```bash
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted --overwrite
```

### Step 4: Verify Enforcement

```bash
# Attempt to create a privileged pod (should fail)
kubectl run test-priv --image=nginx --restart=Never \
  --overrides='{"spec":{"containers":[{"name":"test","image":"nginx","securityContext":{"privileged":true}}]}}' \
  -n production
```

## Detection

```yaml
title: Pod Security Standards Detection
id: 3b84eeab-71d1-46ec-9878-4af06f079cae
status: experimental
description: Detects suspicious activity related to implementing pod security standards techniques in container security context
logsource:
  product: kubernetes
  service: audit
detection:
  selection:
    eventName: "*Unauthorized*"
  condition: selection
level: medium
tags:
  - attack.t1610
  - attack.execution
falsepositives:
  - Container orchestration platform performing routine health checks
```

## Verification

- [ ] All production namespaces enforce restricted PSS
- [ ] Staging namespaces enforce baseline with restricted warnings
- [ ] No pods run as root in restricted namespaces
- [ ] Kyverno/Gatekeeper policies block privilege escalation
- [ ] Dry-run evaluation passes for all deployments
- [ ] PSA audit logs captured in cluster audit policy

## References

- [Kubernetes Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
- [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/)
- [Kyverno Policies](https://kyverno.io/policies/)
- [CIS Kubernetes Benchmark 5.2 — Pod Security](https://www.cisecurity.org/benchmark/kubernetes)
- [NIST SP 800-190 §4.3 — Container Runtime Security](https://csrc.nist.gov/publications/detail/sp/800-190/final)
