Learn how to implement Kubernetes Pod Security Standards using built-in admission controllers and OPA Gatekeeper for comprehensive policy enforcement, security compliance, and workload protection in production clusters.
Prerequisites
- Kubernetes cluster 1.25+
- kubectl configured
- Cluster admin permissions
- Basic understanding of Kubernetes YAML
What this solves
Kubernetes Pod Security Standards provide a built-in framework for enforcing security policies across your cluster workloads. This tutorial shows you how to configure Pod Security Standards using admission controllers and implement OPA Gatekeeper for advanced policy enforcement. You'll learn to prevent privilege escalation, enforce resource limits, and ensure compliance with security best practices.
Understanding Pod Security Standards and admission controllers
Pod Security Standards define three security policies for workloads:
- Privileged - Unrestricted policy for system-level workloads
- Baseline - Minimally restrictive policy preventing known privilege escalations
- Restricted - Heavily restricted policy following current Pod hardening best practices
Admission controllers evaluate these policies at three enforcement levels:
- enforce - Policy violations cause pod rejection
- audit - Policy violations are logged but allowed
- warn - Policy violations trigger user-facing warnings
Step-by-step configuration
Verify cluster requirements
Check that your Kubernetes cluster supports Pod Security Standards. This requires Kubernetes 1.25 or later with the PodSecurity admission plugin enabled.
kubectl version --short
kubectl api-resources | grep podsecurity
Verify the PodSecurity admission controller is enabled:
kubectl get --raw /api/v1 | jq '.resources[] | select(.name=="namespaces")'
Create test namespaces with different security levels
Create namespaces to demonstrate different Pod Security Standard enforcement levels.
apiVersion: v1
kind: Namespace
metadata:
name: test-privileged
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
apiVersion: v1
kind: Namespace
metadata:
name: test-baseline
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
apiVersion: v1
kind: Namespace
metadata:
name: test-restricted
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Apply the namespace configurations:
kubectl apply -f test-privileged-ns.yaml
kubectl apply -f test-baseline-ns.yaml
kubectl apply -f test-restricted-ns.yaml
Configure cluster-wide Pod Security Standards
Set default Pod Security Standards for all namespaces by configuring the admission controller. Create an admission configuration file:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
exemptions:
usernames: ["system:serviceaccount:kube-system:*"]
runtimeClasses: []
namespaces: ["kube-system", "kube-public", "kube-node-lease"]
Test baseline policy enforcement
Create a pod that violates baseline security standards to test enforcement:
apiVersion: v1
kind: Pod
metadata:
name: privileged-test
namespace: test-baseline
spec:
containers:
- name: test-container
image: nginx:1.25
securityContext:
privileged: true
ports:
- containerPort: 80
Attempt to create the pod:
kubectl apply -f privileged-pod.yaml
This should fail with a Pod Security Standards violation. Create a compliant pod instead:
apiVersion: v1
kind: Pod
metadata:
name: compliant-test
namespace: test-baseline
spec:
containers:
- name: test-container
image: nginx:1.25
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
ports:
- containerPort: 8080
kubectl apply -f compliant-pod.yaml
Install OPA Gatekeeper for advanced policies
Install OPA Gatekeeper to implement custom admission policies beyond Pod Security Standards:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yaml
Wait for Gatekeeper components to be ready:
kubectl wait --for=condition=Ready pod -l control-plane=controller-manager -n gatekeeper-system --timeout=90s
kubectl wait --for=condition=Ready pod -l control-plane=audit-controller -n gatekeeper-system --timeout=90s
Create Gatekeeper constraint templates
Define a constraint template to enforce resource limits on all pods:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredresources
spec:
crd:
spec:
names:
kind: K8sRequiredResources
validation:
openAPIV3Schema:
type: object
properties:
limits:
type: array
items:
type: string
requests:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredresources
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits
msg := "Container missing resource limits"
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.requests
msg := "Container missing resource requests"
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
required := input.parameters.limits[_]
not container.resources.limits[required]
msg := sprintf("Container missing required resource limit: %v", [required])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
required := input.parameters.requests[_]
not container.resources.requests[required]
msg := sprintf("Container missing required resource request: %v", [required])
}
kubectl apply -f resource-limits-template.yaml
Apply resource limit constraints
Create a constraint using the template to enforce CPU and memory limits:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredResources
metadata:
name: must-have-resources
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "kube-public", "kube-node-lease", "gatekeeper-system"]
parameters:
limits: ["cpu", "memory"]
requests: ["cpu", "memory"]
kubectl apply -f require-resources-constraint.yaml
Create image security policies
Define a template to restrict container images to trusted registries:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sallowedrepos
spec:
crd:
spec:
names:
kind: K8sAllowedRepos
validation:
openAPIV3Schema:
type: object
properties:
repos:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sallowedrepos
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
not any(satisfied)
msg := sprintf("Container image <%v> is not from an allowed repository", [container.image])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
not any(satisfied)
msg := sprintf("Init container image <%v> is not from an allowed repository", [container.image])
}
Apply the template and create a constraint:
kubectl apply -f allowed-repos-template.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
name: repo-must-be-trusted
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
- apiGroups: ["apps"]
kinds: ["Deployment"]
excludedNamespaces: ["kube-system", "kube-public", "kube-node-lease", "gatekeeper-system"]
parameters:
repos:
- "docker.io/library/"
- "gcr.io/"
- "quay.io/"
- "registry.k8s.io/"
kubectl apply -f allowed-repos-constraint.yaml
Configure security context constraints
Create a template to enforce security context requirements:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8ssecuritycontext
spec:
crd:
spec:
names:
kind: K8sSecurityContext
validation:
openAPIV3Schema:
type: object
properties:
runAsNonRoot:
type: boolean
readOnlyRootFilesystem:
type: boolean
allowPrivilegeEscalation:
type: boolean
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8ssecuritycontext
violation[{"msg": msg}] {
input.parameters.runAsNonRoot
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := "Container must set runAsNonRoot to true"
}
violation[{"msg": msg}] {
input.parameters.readOnlyRootFilesystem
container := input.review.object.spec.containers[_]
not container.securityContext.readOnlyRootFilesystem
msg := "Container must set readOnlyRootFilesystem to true"
}
violation[{"msg": msg}] {
not input.parameters.allowPrivilegeEscalation
container := input.review.object.spec.containers[_]
container.securityContext.allowPrivilegeEscalation != false
msg := "Container must set allowPrivilegeEscalation to false"
}
kubectl apply -f security-context-template.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sSecurityContext
metadata:
name: security-context-required
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "kube-public", "kube-node-lease", "gatekeeper-system"]
parameters:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
kubectl apply -f security-context-constraint.yaml
Testing and monitoring Pod Security Standards compliance
Test policy enforcement with compliant workloads
Create a deployment that meets all security requirements:
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: test-restricted
spec:
replicas: 2
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 2001
containers:
- name: app
image: docker.io/library/nginx:1.25
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/nginx
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
kubectl apply -f secure-deployment.yaml
Monitor policy violations and audit logs
Check Gatekeeper violations and constraint status:
kubectl get constraints
kubectl describe k8srequiredresources must-have-resources
kubectl describe k8sallowedrepos repo-must-be-trusted
View audit logs for policy violations:
kubectl logs -l control-plane=audit-controller -n gatekeeper-system
kubectl get events --field-selector reason=FailedCreate
Set up monitoring with Prometheus
Configure monitoring to track policy violations. If you have Prometheus installed, you can link it to existing monitoring tutorials like monitor Kubernetes cluster with Prometheus Operator.
apiVersion: v1
kind: Service
metadata:
name: gatekeeper-audit-metrics
namespace: gatekeeper-system
labels:
app: gatekeeper-audit
spec:
ports:
- name: metrics
port: 8888
targetPort: 8888
selector:
control-plane: audit-controller
kubectl apply -f gatekeeper-metrics-service.yaml
Create policy exception workflows
Configure exemptions for specific workloads that need elevated privileges:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sSecurityContext
metadata:
name: security-context-with-exemptions
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "kube-public", "kube-node-lease", "gatekeeper-system", "monitoring"]
parameters:
runAsNonRoot: true
readOnlyRootFilesystem: false
allowPrivilegeEscalation: false
You can also exempt specific workloads by labels:
kubectl label namespace monitoring policy-exemption=true
Verify your setup
Check that Pod Security Standards are enforcing correctly:
# Verify namespace labels
kubectl get namespaces --show-labels
Check Gatekeeper status
kubectl get pods -n gatekeeper-system
kubectl get constraints
Test with a non-compliant pod
kubectl run test-pod --image=nginx --dry-run=server -n test-restricted
View policy violations
kubectl get events --field-selector reason=FailedCreate
kubectl describe constraints
Verify security contexts are being enforced:
# Check running pods comply with security standards
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.securityContext}{"\n"}{end}'
Verify resource limits are set
kubectl top pods
kubectl describe pod secure-app -n test-restricted
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Pods rejected with "violates PodSecurity" | Security context doesn't meet policy requirements | Add required security context fields: runAsNonRoot: true, allowPrivilegeEscalation: false |
| Gatekeeper constraints not enforcing | Template or constraint syntax error | Check constraint status: kubectl describe constraint constraint-name |
| System pods failing to start | Policy applied to system namespaces | Add system namespaces to excludedNamespaces in constraints |
| Resource limit violations | Pods don't specify CPU/memory limits | Add resources.requests and resources.limits to container specs |
| Image registry violations | Using untrusted container registries | Update allowed registries in constraint parameters or use trusted images |
| Admission webhook timeouts | Gatekeeper webhook not responding | Check webhook pods: kubectl get pods -n gatekeeper-system |
Next steps
- Configure Falco runtime security for Kubernetes threat detection for runtime threat monitoring
- Configure Kubernetes secrets management with Sealed Secrets for secure secret handling
- Implement network policies with Calico CNI for network microsegmentation
- Configure advanced RBAC policies with OPA Gatekeeper authorization
- Implement image vulnerability scanning with Trivy operator
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_DIR="/tmp/k8s-pod-security-config"
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Configure Kubernetes Pod Security Standards with admission controllers"
echo ""
echo "Options:"
echo " --kubeconfig PATH Path to kubeconfig file (default: ~/.kube/config)"
echo " --skip-verification Skip final verification checks"
echo " -h, --help Show this help message"
exit 1
}
# Cleanup function
cleanup() {
if [ $? -ne 0 ]; then
echo -e "${RED}[ERROR] Script failed. Cleaning up...${NC}"
rm -rf "$CONFIG_DIR" 2>/dev/null || true
fi
}
trap cleanup ERR EXIT
# Parse arguments
KUBECONFIG_PATH="$HOME/.kube/config"
SKIP_VERIFICATION=false
while [[ $# -gt 0 ]]; do
case $1 in
--kubeconfig)
KUBECONFIG_PATH="$2"
shift 2
;;
--skip-verification)
SKIP_VERIFICATION=true
shift
;;
-h|--help)
usage
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian) PKG_MGR="apt"; PKG_INSTALL="apt install -y" ;;
almalinux|rocky|centos|rhel|ol|fedora) PKG_MGR="dnf"; PKG_INSTALL="dnf install -y" ;;
amzn) PKG_MGR="yum"; PKG_INSTALL="yum install -y" ;;
*) echo -e "${RED}Unsupported distro: $ID${NC}"; exit 1 ;;
esac
else
echo -e "${RED}Cannot detect Linux distribution${NC}"
exit 1
fi
echo -e "${BLUE}Kubernetes Pod Security Standards Configuration Script${NC}"
echo -e "${BLUE}Detected OS: $PRETTY_NAME${NC}"
# Check prerequisites
echo -e "${YELLOW}[1/8] Checking prerequisites...${NC}"
if [ "$EUID" -eq 0 ]; then
echo -e "${YELLOW}Warning: Running as root. Consider running as regular user with kubectl access.${NC}"
fi
# Update package manager
if [ "$PKG_MGR" = "apt" ]; then
apt update -qq
elif [ "$PKG_MGR" = "dnf" ]; then
dnf makecache --quiet
elif [ "$PKG_MGR" = "yum" ]; then
yum makecache --quiet
fi
# Install required tools
echo -e "${YELLOW}[2/8] Installing required tools...${NC}"
if ! command -v kubectl &> /dev/null; then
if [ "$PKG_MGR" = "apt" ]; then
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
apt update -qq
$PKG_INSTALL kubectl
else
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
EOF
$PKG_INSTALL kubectl
fi
fi
if ! command -v jq &> /dev/null; then
$PKG_INSTALL jq
fi
# Verify cluster requirements
echo -e "${YELLOW}[3/8] Verifying cluster requirements...${NC}"
if [ ! -f "$KUBECONFIG_PATH" ]; then
echo -e "${RED}Kubeconfig file not found: $KUBECONFIG_PATH${NC}"
exit 1
fi
export KUBECONFIG="$KUBECONFIG_PATH"
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Cannot connect to Kubernetes cluster${NC}"
exit 1
fi
# Check Kubernetes version
K8S_VERSION=$(kubectl version --short --client -o json | jq -r '.clientVersion.gitVersion' | sed 's/v//')
MAJOR=$(echo $K8S_VERSION | cut -d. -f1)
MINOR=$(echo $K8S_VERSION | cut -d. -f2)
if [ "$MAJOR" -lt 1 ] || ([ "$MAJOR" -eq 1 ] && [ "$MINOR" -lt 25 ]); then
echo -e "${RED}Kubernetes 1.25 or later required. Found: v$K8S_VERSION${NC}"
exit 1
fi
echo -e "${GREEN}Kubernetes version v$K8S_VERSION detected${NC}"
# Create configuration directory
mkdir -p "$CONFIG_DIR"
chmod 755 "$CONFIG_DIR"
# Create test namespaces
echo -e "${YELLOW}[4/8] Creating test namespaces with different security levels...${NC}"
cat > "$CONFIG_DIR/test-privileged-ns.yaml" <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: test-privileged
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
EOF
cat > "$CONFIG_DIR/test-baseline-ns.yaml" <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: test-baseline
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
EOF
cat > "$CONFIG_DIR/test-restricted-ns.yaml" <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: test-restricted
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
EOF
kubectl apply -f "$CONFIG_DIR/test-privileged-ns.yaml"
kubectl apply -f "$CONFIG_DIR/test-baseline-ns.yaml"
kubectl apply -f "$CONFIG_DIR/test-restricted-ns.yaml"
echo -e "${GREEN}Test namespaces created successfully${NC}"
# Create admission configuration
echo -e "${YELLOW}[5/8] Creating admission configuration...${NC}"
cat > "$CONFIG_DIR/admission-config.yaml" <<EOF
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
exemptions:
usernames: ["system:serviceaccount:kube-system:*"]
runtimeClasses: []
namespaces: ["kube-system", "kube-public", "kube-node-lease"]
EOF
echo -e "${GREEN}Admission configuration created${NC}"
# Test baseline policy enforcement
echo -e "${YELLOW}[6/8] Testing baseline policy enforcement...${NC}"
cat > "$CONFIG_DIR/privileged-pod.yaml" <<EOF
apiVersion: v1
kind: Pod
metadata:
name: privileged-test
namespace: test-baseline
spec:
containers:
- name: test-container
image: nginx:1.25
securityContext:
privileged: true
ports:
- containerPort: 80
EOF
cat > "$CONFIG_DIR/compliant-pod.yaml" <<EOF
apiVersion: v1
kind: Pod
metadata:
name: compliant-test
namespace: test-baseline
spec:
containers:
- name: test-container
image: nginx:1.25
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
ports:
- containerPort: 80
EOF
# Test privileged pod (should fail in baseline)
if kubectl apply -f "$CONFIG_DIR/privileged-pod.yaml" 2>/dev/null; then
echo -e "${YELLOW}Warning: Privileged pod was allowed in baseline namespace${NC}"
else
echo -e "${GREEN}Privileged pod correctly rejected in baseline namespace${NC}"
fi
# Apply compliant pod
kubectl apply -f "$CONFIG_DIR/compliant-pod.yaml"
echo -e "${GREEN}Compliant pod created successfully${NC}"
# Test restricted policy
echo -e "${YELLOW}[7/8] Testing restricted policy enforcement...${NC}"
cat > "$CONFIG_DIR/restricted-compliant-pod.yaml" <<EOF
apiVersion: v1
kind: Pod
metadata:
name: restricted-compliant-test
namespace: test-restricted
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: test-container
image: nginx:1.25
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
capabilities:
drop:
- ALL
ports:
- containerPort: 80
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
EOF
kubectl apply -f "$CONFIG_DIR/restricted-compliant-pod.yaml"
echo -e "${GREEN}Restricted compliant pod created successfully${NC}"
# Verification
if [ "$SKIP_VERIFICATION" = false ]; then
echo -e "${YELLOW}[8/8] Running verification checks...${NC}"
# Check namespace labels
echo "Verifying namespace pod security labels..."
kubectl get namespace test-baseline -o yaml | grep -q "pod-security.kubernetes.io/enforce: baseline"
kubectl get namespace test-restricted -o yaml | grep -q "pod-security.kubernetes.io/enforce: restricted"
# Check pod status
echo "Verifying pod deployments..."
kubectl wait --for=condition=Ready pod/compliant-test -n test-baseline --timeout=60s
kubectl wait --for=condition=Ready pod/restricted-compliant-test -n test-restricted --timeout=60s
echo -e "${GREEN}All verification checks passed!${NC}"
else
echo -e "${YELLOW}[8/8] Skipping verification checks...${NC}"
fi
echo -e "${GREEN}Kubernetes Pod Security Standards configuration completed successfully!${NC}"
echo -e "${BLUE}Summary:${NC}"
echo "- Test namespaces created with different security levels"
echo "- Admission configuration prepared"
echo "- Policy enforcement tested and verified"
echo "- Configuration files saved in: $CONFIG_DIR"
Review the script before running. Execute with: bash install.sh