Skip to content
_CORE
AI & Agentic Systems Core Information Systems Cloud & Platform Engineering Data Platform & Integration Security & Compliance QA, Testing & Observability IoT, Automation & Robotics Mobile & Digital Banking & Finance Insurance Public Administration Defense & Security Healthcare Energy & Utilities Telco & Media Manufacturing Logistics & E-commerce Retail & Loyalty
References Technologies Blog Know-how Tools
About Collaboration Careers
CS EN DE
Let's talk

Kubernetes Security Best Practices 2026

20. 02. 2026 11 min read advanced

Kubernetes is the de facto standard for container orchestration in 2026. But with growing adoption comes an expanding attack surface — and security incidents in Kubernetes environments are increasingly common. This article provides a comprehensive overview of security best practices that reflect the current state of technologies, threats, and regulations.

This is not a basic RBAC tutorial — we focus on advanced techniques that in 2026 make the difference between “we have Kubernetes” and “we have secure Kubernetes.”

1. Supply Chain Security: Secure What You Deploy

SBOM as a Foundation

Software Bill of Materials (SBOM) has become a requirement — not just from a best practices standpoint, but also due to regulations like NIS2 and the Cyber Resilience Act (CRA). Every container image should have an accompanying SBOM in SPDX or CycloneDX format.

# Kubernetes Security Best Practices 2026
syft packages registry.example.com/app:v2.1.0 -o spdx-json > sbom.json

# Atestace SBOM k image pomocí Cosign
cosign attest --predicate sbom.json \
  --type spdxjson \
  registry.example.com/app:v2.1.0

SLSA Framework Level 3+

Supply-chain Levels for Software Artifacts (SLSA) defines levels of trust for the build process. In 2026, production workloads should achieve at least SLSA Level 3:

  • Level 1: Documented build process
  • Level 2: Hosted build with provenance
  • Level 3: Hardened build platform, non-falsifiable provenance
  • Level 4: Two-party review, hermetic build
# GitHub Actions s SLSA provenance
jobs:
  build:
    permissions:
      id-token: write
      contents: read
      attestations: write
    steps:
      - uses: actions/attest-build-provenance@v2
        with:
          subject-name: registry.example.com/app
          subject-digest: ${{ steps.build.outputs.digest }}
          push-to-registry: true

Image Signing and Verification

Every image deployed to the cluster must be signed and verified. Cosign from the Sigstore project is the industry standard in 2026:

# Kyverno policy pro ověření podpisu
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-cosign
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences: ["registry.example.com/*"]
          attestors:
            - entries:
                - keyless:
                    subject: "[email protected]"
                    issuer: "https://token.actions.githubusercontent.com"

2. Admission Control: The Gateway to Your Cluster

Kyverno vs OPA Gatekeeper

In 2026, there are two main approaches to admission control:

Kyverno — a native Kubernetes policy engine with YAML-based rules. Easier adoption, strong integration with the Kubernetes API.

OPA Gatekeeper — a more general-purpose policy engine using the Rego language. More flexible, but with a steeper learning curve.

For most organizations, we recommend Kyverno for its accessibility and advanced features such as resource generation and mutation:

# Automatické přidání security context
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-securitycontext
spec:
  rules:
    - name: add-security-context
      match:
        any:
          - resources:
              kinds: ["Pod"]
      mutate:
        patchStrategicMerge:
          spec:
            containers:
              - (name): "*"
                securityContext:
                  runAsNonRoot: true
                  readOnlyRootFilesystem: true
                  allowPrivilegeEscalation: false
                  capabilities:
                    drop: ["ALL"]
                  seccompProfile:
                    type: RuntimeDefault

Pod Security Standards — Restricted Profile

Kubernetes Pod Security Standards (PSS) replaced the deprecated PodSecurityPolicy. In production, use the restricted profile:

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

The restricted profile requires: - runAsNonRoot: true - No privileged containers - Limited capabilities (only NET_BIND_SERVICE) - Seccomp profile RuntimeDefault or Localhost - No hostPath volumes - Privilege escalation disabled

ValidatingAdmissionPolicy — A Native Alternative

Since Kubernetes 1.30, ValidatingAdmissionPolicy (VAP) is GA. It offers native admission control without external webhooks using CEL (Common Expression Language):

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: deny-privileged-containers
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods"]
  validations:
    - expression: >-
        object.spec.containers.all(c,
          !has(c.securityContext) ||
          !has(c.securityContext.privileged) ||
          c.securityContext.privileged == false)
      message: "Privilegované kontejnery nejsou povoleny"

VAP is a lighter alternative to webhooks — it runs directly in the API server, without network calls. For simple policies, it is the ideal choice.

3. Network Security: Microsegmentation and Beyond

Network Policies — Baseline

The default behavior of Kubernetes is “allow all” — every pod can communicate with every other pod. This is unacceptable in production:

# Default deny pro namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

Then allow only the necessary communication:

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

Cilium Network Policies — Layer 7 and DNS

Standard Kubernetes Network Policies operate at L3/L4. Cilium extends capabilities with L7 filtering, DNS-aware policies, and identity-based security:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-l7-policy
spec:
  endpointSelector:
    matchLabels:
      app: api-gateway
  egress:
    - toEndpoints:
        - matchLabels:
            app: user-service
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/v1/users/.*"
              - method: "POST"
                path: "/api/v1/users"
    - toFQDNs:
        - matchName: "api.external-service.com"
      toPorts:
        - ports:
            - port: "443"
              protocol: TCP

Automatic Mutual TLS (mTLS)

Service mesh solutions such as Cilium (with mTLS support), Istio, or Linkerd provide automatic encrypted communication between pods. In 2026, Cilium is the preferred choice thanks to eBPF — no sidecar proxy, lower latency, smaller resource overhead:

# Cilium mTLS konfigurace
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: require-mtls
spec:
  endpointSelector:
    matchLabels:
      app: payment-service
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: order-service
      authentication:
        mode: required

4. Runtime Security: Real-Time Detection

Falco — Syscall Monitoring

Falco monitors syscalls and detects suspicious behavior at runtime. In 2026, Falco is a mature CNCF graduated project:

# Falco pravidlo pro detekci reverse shell
- rule: Reverse Shell
  desc: Detect reverse shell
  condition: >
    spawned_process and
    proc.name in (bash, sh, zsh) and
    fd.type = ipv4 and
    fd.direction = out
  output: >
    Reverse shell detected
    (user=%user.name command=%proc.cmdline
     connection=%fd.name container=%container.name
     image=%container.image.repository)
  priority: CRITICAL
  tags: [network, process, mitre_execution]

# Detekce čtení citlivých souborů
- rule: Read Sensitive Files
  desc: Detect reading of sensitive files
  condition: >
    open_read and
    sensitive_files and
    container and
    not trusted_containers
  output: >
    Sensitive file read in container
    (file=%fd.name container=%container.name
     image=%container.image.repository)
  priority: WARNING

Tetragon — eBPF Security Observability

Cilium Tetragon is a newer alternative to Falco, built on eBPF. It offers real-time enforcement (not just detection) with minimal overhead:

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: block-sensitive-file-access
spec:
  kprobes:
    - call: "security_file_open"
      syscall: false
      args:
        - index: 0
          type: "file"
      selectors:
        - matchArgs:
            - index: 0
              operator: "Prefix"
              values:
                - "/etc/shadow"
                - "/etc/passwd"
                - "/run/secrets/kubernetes.io"
          matchActions:
            - action: Sigkill

The key difference: Falco detects and reports, while Tetragon can actively block. For critical workloads, we recommend a combination of both — Tetragon for enforcement, Falco for the audit trail.

Audit Logging

The Kubernetes audit log is essential for forensic analysis and compliance:

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # Log all requests to secrets
  - level: RequestResponse
    resources:
      - group: ""
        resources: ["secrets"]
  # Log exec into pods
  - level: RequestResponse
    resources:
      - group: ""
        resources: ["pods/exec", "pods/attach"]
  # Log all changes to RBAC
  - level: RequestResponse
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings",
                     "roles", "rolebindings"]
  # Metadata for everything else
  - level: Metadata
    omitStages:
      - RequestReceived

Route audit logs to a central SIEM system (Elasticsearch, Splunk, or a cloud SIEM) and set up alerting on critical events.

5. Secrets Management

Never in Git, Never in Environment Variables

Kubernetes Secrets are base64-encoded, not encrypted. For production you need:

  1. External Secrets Operator (ESO) — syncing secrets from external vaults:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 5m
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: db-credentials
  data:
    - secretKey: username
      remoteRef:
        key: secret/data/production/database
        property: username
    - secretKey: password
      remoteRef:
        key: secret/data/production/database
        property: password
  1. Sealed Secrets — encrypted secrets in Git:
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
# sealed-secret.yaml je bezpečné commitnout
  1. SOPS + Age/KMS — file encryption with keys managed via KMS:
sops --encrypt --age age1... secrets.yaml > secrets.enc.yaml

Secret Rotation

Automatic rotation is a necessity in 2026. Set TTLs on secrets and use dynamic credentials wherever possible (e.g., Vault database secrets engine):

# Vault dynamic database credentials
resource "vault_database_secret_backend_role" "app" {
  backend = vault_mount.database.path
  name    = "app-role"
  db_name = "postgres"

  creation_statements = [
    "CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';",
    "GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"
  ]

  default_ttl = 3600   # 1 hodina
  max_ttl     = 86400  # 24 hodin
}

6. Image Security

Minimal Base Images

Use distroless or scratch images. The fewer components in the image, the smaller the attack surface:

# Multi-stage build s distroless
FROM golang:1.23 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o /server

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /server /server
USER 65534:65534
ENTRYPOINT ["/server"]

Vulnerability Scanning in CI/CD

Integrate scanning into your pipeline — never deploy images with critical CVEs:

# GitHub Actions s Trivy
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: registry.example.com/app:${{ github.sha }}
    format: sarif
    output: trivy-results.sarif
    severity: CRITICAL,HIGH
    exit-code: 1  # Fail pipeline na critical/high

Admission Control for Image Quality Gates

# Kyverno — povolte pouze images ze schváleného registru
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 musí pocházet ze schváleného registru"
        pattern:
          spec:
            containers:
              - image: "registry.example.com/*"
            initContainers:
              - image: "registry.example.com/*"

7. RBAC — Least Privilege in Practice

The Principle of Least Privilege

Create granular roles instead of using cluster-admin:

# Role pro deployment pipeline
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: production
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "patch", "update"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "create", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

Regular RBAC Auditing

Use tools like kubectl-who-can and rakkess for permission auditing:

# Kdo může číst secrets?
kubectl who-can get secrets -n production

# Audit všech cluster-admin bindings
kubectl get clusterrolebindings -o json | \
  jq '.items[] | select(.roleRef.name=="cluster-admin") |
  {name: .metadata.name, subjects: .subjects}'

Service Account Tokens — Bound and Short-Lived

Since Kubernetes 1.24, long-lived SA tokens are no longer automatically created. Use bound service account tokens with limited validity:

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  serviceAccountName: app-sa
  containers:
    - name: app
      image: registry.example.com/app:v2
      volumeMounts:
        - mountPath: /var/run/secrets/tokens
          name: app-token
  volumes:
    - name: app-token
      projected:
        sources:
          - serviceAccountToken:
              path: token
              expirationSeconds: 3600  # 1 hodina
              audience: "api.example.com"

8. Cluster Hardening

API Server

  • Disable anonymous auth: --anonymous-auth=false
  • Enable audit logging
  • Restrict API server access to trusted networks
  • Use OIDC for user authentication

etcd

  • Encrypt data at rest using EncryptionConfiguration
  • Use mTLS for communication with the API server
  • Isolate etcd from worker nodes
  • Regular backups with encryption
# EncryptionConfiguration pro etcd
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
      - configmaps
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-key>
      - identity: {}

Node Security

  • Automatic OS patching (e.g., Bottlerocket, Flatcar, Talos)
  • CIS Kubernetes Benchmark compliance
  • Minimal node OS — only what is needed for the kubelet
# Kontrola CIS compliance pomocí kube-bench
kube-bench run --targets node
kube-bench run --targets master

9. Monitoring and Incident Response

Security-Focused Metrics

Monitor metrics relevant to security:

  • Number of failed authentication attempts
  • RBAC denied requests (apiserver_authorization_decisions_total{decision="denied"})
  • Admission webhook rejects
  • Network policy drops
  • Anomalies in resource consumption

Incident Response Playbook

Prepare runbooks for common scenarios:

  1. Compromised pod — isolation via network policy, forensic snapshot, credential rotation
  2. Secret leak — immediate rotation, audit trail analysis, scope assessment
  3. Privileged access — revocation, RBAC audit, lateral movement check
  4. Supply chain attack — identification of affected images, rollback, SBOM analysis
# Emergency network isolation
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: emergency-isolate
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: compromised-app
  policyTypes:
    - Ingress
    - Egress
  # Prázdné ingress/egress = deny all

10. AI-Driven Security — 2026 Trend

In 2026, an increasing number of organizations are turning to AI for security operations:

  • Anomaly detection — ML models analyze network traffic and syscall patterns, identifying deviations from baseline behavior
  • Automated triage — AI prioritizes security alerts and reduces alert fatigue
  • Predictive patching — predicting CVE exploitability based on environment context
  • Natural language policies — experimental tools allow defining security policies in natural language

Tools like ARMO Kubescape, Aqua Security, and Sysdig integrate AI-driven analysis into their platforms. It is a complement, not a replacement — always have solid foundations (RBAC, network policies, admission control) in place.

Checklist: Kubernetes Security 2026

Before declaring a cluster “production ready,” verify:

  • [ ] Pod Security Standards — restricted profile on production namespaces
  • [ ] Network Policies — default deny, explicit allow
  • [ ] RBAC — least privilege, no unnecessary cluster-admin
  • [ ] Image signing and verification — Cosign + Kyverno/Gatekeeper
  • [ ] SBOM generation and attestation
  • [ ] Vulnerability scanning in CI/CD with quality gates
  • [ ] Secrets in an external vault (not in Git, not plain in etcd)
  • [ ] Runtime security — Falco or Tetragon
  • [ ] Audit logging to SIEM
  • [ ] etcd encryption at rest
  • [ ] mTLS between services
  • [ ] Incident response playbook
  • [ ] Regular CIS benchmark audits

Conclusion

Kubernetes security is not a one-time task — it is a continuous process. Technologies evolve (eBPF, VAP, AI-driven detection), attackers adapt, and regulations tighten requirements.

The key to success is defense in depth: no single security layer is sufficient. Combine supply chain security, admission control, network segmentation, runtime protection, and monitoring into a coherent strategy.

Start with what delivers the most value with the least effort — Network Policies and Pod Security Standards. Then gradually add layers based on your team’s maturity and the criticality of your workloads.

securitykubernetesk8sdevsecopsebpfsupply-chainsbomkyvernofalcotetragon
Share:

CORE SYSTEMS team

We build core systems and AI agents that keep operations running. 15 years of experience with enterprise IT.