BlogCybersecurity
Cybersecurity

Kubernetes Security Hardening in 2026: Pod Security, Network Policies, and Runtime Protection

Kubernetes is secure by default β€” said no one ever. This guide covers Pod Security Standards, Network Policies, RBAC hardening, image scanning, runtime protection with Falco, and the security configurations most clusters are missing.

S

Sarah Chen

Senior Cybersecurity Engineer with 12+ years of experience in penetration testing and security architecture.

February 24, 2026
24 min read

Kubernetes default configurations are optimized for ease of use, not security. Out of the box, any pod can communicate with any other pod, containers run as root, there are no resource limits, service accounts have broad permissions, and the Kubernetes API is accessible from within pods. A single compromised container in a default Kubernetes cluster can escalate to full cluster compromise in minutes.

This guide covers the security hardening measures that every production Kubernetes cluster needs. We've organized them by impact: start at the top and work your way down. Each section includes the specific configuration you need to apply.

Pod Security Standards: The Foundation

Pod Security Standards (PSS) replaced the deprecated PodSecurityPolicy in Kubernetes 1.25. PSS defines three security profiles β€” Privileged (unrestricted), Baseline (sensible defaults), and Restricted (maximum security) β€” and enforces them at the namespace level.

# Apply Restricted Pod Security Standard to production namespaces
# This prevents: running as root, privilege escalation, host networking,
# host path mounts, and many other dangerous configurations.

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

---
# Pod that complies with Restricted standard
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/app:v1.2.3@sha256:abc123...
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 512Mi
      ports:
        - containerPort: 8080
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir: {}
  automountServiceAccountToken: false  # Don't mount SA token unless needed

Network Policies: Zero-Trust Networking

By default, every pod can communicate with every other pod in the cluster. Network Policies implement zero-trust networking: deny all traffic by default, then explicitly allow only the traffic that's needed.

# Default deny all ingress and egress in the namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}  # Applies to all pods in the namespace
  policyTypes:
    - Ingress
    - Egress

---
# Allow backend API to receive traffic from frontend only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

---
# Allow backend to connect to database and external APIs
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Egress
  egress:
    # Allow DNS resolution
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
    # Allow database access
    - to:
        - podSelector:
            matchLabels:
              app: postgresql
      ports:
        - protocol: TCP
          port: 5432
    # Allow external API calls (HTTPS only)
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8      # Block internal network access
              - 172.16.0.0/12
              - 192.168.0.0/16
      ports:
        - protocol: TCP
          port: 443

RBAC Hardening: Principle of Least Privilege

Kubernetes RBAC controls who can do what in the cluster. The default cluster-admin ClusterRole has unrestricted access to everything β€” if compromised, the attacker owns the entire cluster. Every user and service account should have the minimum permissions needed.

# Bad: Giving developers cluster-admin access
# kubectl create clusterrolebinding dev-admin #   --clusterrole=cluster-admin --user=developer@company.com

# Good: Namespace-scoped role with specific permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: staging
  name: developer
rules:
  - apiGroups: ["", "apps"]
    resources: ["pods", "deployments", "services", "configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods/log", "pods/exec"]
    verbs: ["get", "create"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]  # Can read secrets but not create/modify

---
# Service account for CI/CD with minimal deployment permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: ci-deployer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "update", "patch"]
    resourceNames: ["backend-api", "frontend"]  # Only specific deployments
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

Image Security: Trust Nothing from the Internet

Container images are the primary vector for supply chain attacks in Kubernetes. Essential controls:

Use image digests, not tags. Tags are mutable β€” nginx:latest today is different from nginx:latest tomorrow. Use digests: nginx@sha256:abc123.... This guarantees you're running the exact image you tested.

Scan images in CI/CD. Run Trivy, Grype, or Snyk on every image before deployment. Fail the pipeline on critical or high vulnerabilities. Scan both your application images and your base images.

Use minimal base images. alpine (5MB) or distroless (2MB) instead of ubuntu (75MB). Fewer packages = fewer vulnerabilities. Distroless images don't even include a shell, making post-exploitation significantly harder.

Enforce allowed registries. Use admission controllers (OPA/Gatekeeper or Kyverno) to block images from untrusted registries. Only allow images from your private registry and verified public registries.

# Kyverno policy: Only allow images from trusted registries
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-image-registries
spec:
  validationFailureAction: Enforce
  rules:
    - name: validate-registries
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "Images must be from approved registries"
        pattern:
          spec:
            containers:
              - image: "registry.example.com/* | ghcr.io/yourorg/*"
            initContainers:
              - image: "registry.example.com/* | ghcr.io/yourorg/*"

Secrets Management: Don't Put Secrets in ConfigMaps

Kubernetes Secrets are base64-encoded, not encrypted. Anyone with get secrets RBAC permission can read them. For production, use external secret management:

Option 1: External Secrets Operator β€” Syncs secrets from Vault, AWS Secrets Manager, or Azure Key Vault into Kubernetes Secrets. The Git repo contains only references, not secret values.

Option 2: Sealed Secrets β€” Encrypt secrets with a cluster-specific public key. Only the controller in the cluster can decrypt them. Safe to commit to Git.

Option 3: CSI Secrets Store Driver β€” Mounts secrets from external stores as files in pods. No Kubernetes Secret object is created β€” secrets go directly from the external store to the pod filesystem.

Runtime Security: Detect and Respond

Everything above is preventive. Runtime security is detective β€” it monitors running containers for suspicious behavior and alerts or blocks in real-time. Falco (CNCF) is the standard tool for Kubernetes runtime security.

Deploy Falco as a DaemonSet on every node. It monitors syscalls using eBPF and detects: shell spawning inside containers, unauthorized process execution, file access to sensitive paths (/etc/shadow, /proc), network connections to known malicious IPs, privilege escalation attempts, and cryptominer deployment.

Audit Logging: Know What Happened

Enable Kubernetes audit logging to track all API server requests. This is essential for: investigating security incidents (who deployed that container?), compliance requirements (who accessed this namespace?), and detecting unauthorized access patterns.

# Audit policy: log security-relevant events
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # Log all changes to pods, deployments, services
  - level: RequestResponse
    resources:
      - group: ""
        resources: ["pods", "services", "secrets", "configmaps"]
      - group: "apps"
        resources: ["deployments", "statefulsets", "daemonsets"]
    verbs: ["create", "update", "patch", "delete"]

  # Log all RBAC changes
  - level: RequestResponse
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]

  # Log authentication failures
  - level: Metadata
    stages: ["ResponseComplete"]
    omitStages: ["RequestReceived"]

  # Don't log read-only requests to reduce volume
  - level: None
    verbs: ["get", "list", "watch"]
    resources:
      - group: ""
        resources: ["events"]

Security Checklist for Production Clusters

Use this checklist before deploying to production: ☐ Pod Security Standards enforced (Restricted for production). ☐ Network Policies deny all by default. ☐ RBAC follows least privilege (no cluster-admin for humans). ☐ Images use digests and are scanned for vulnerabilities. ☐ Images come only from approved registries. ☐ Secrets are managed externally (not plain Kubernetes Secrets). ☐ Runtime security monitoring deployed (Falco or equivalent). ☐ Audit logging enabled and forwarded to SIEM. ☐ etcd is encrypted at rest. ☐ API server authentication uses OIDC (not static tokens). ☐ Nodes are hardened and auto-updated.

ZeonEdge provides Kubernetes security assessments, hardening implementation, and ongoing monitoring. View our security services.

S

Sarah Chen

Senior Cybersecurity Engineer with 12+ years of experience in penetration testing and security architecture.

Related Articles

Cloud & Infrastructure

DNS Deep Dive in 2026: How DNS Works, How to Secure It, and How to Optimize It

DNS is the invisible infrastructure that makes the internet work. Every website visit, every API call, every email delivery starts with a DNS query. Yet most developers barely understand how DNS works, let alone how to secure it. This exhaustive guide covers DNS resolution, record types, DNSSEC, DNS-over-HTTPS, DNS-over-TLS, split-horizon DNS, DNS-based load balancing, failover strategies, and common misconfigurations.

Marcus Rodriguezβ€’42 min read
Best Practices

Data Privacy Engineering and GDPR Compliance in 2026: A Developer's Complete Guide

Data privacy regulations are becoming stricter and more widespread. GDPR, CCPA, LGPD, and India's DPDPA create a complex web of requirements for any application that handles personal data. This technical guide covers privacy-by-design architecture, data classification, consent management, right-to-erasure implementation, data minimization, pseudonymization, encryption strategies, breach notification workflows, and audit logging.

Emily Watsonβ€’38 min read
Cloud & Infrastructure

Linux Server Hardening for Production in 2026: The Complete Security Checklist

A default Linux server installation is a playground for attackers. SSH with password auth, no firewall, unpatched packages, and services running as root. This exhaustive guide covers every hardening step from initial setup through ongoing maintenance β€” SSH configuration, firewall rules, user management, kernel hardening, file integrity monitoring, audit logging, automatic updates, and intrusion detection.

Alex Thompsonβ€’42 min read

Ready to Transform Your Infrastructure?

Let's discuss how we can help you achieve similar results.