Kubernetes security checklist — 50 best practices across five defense layers

Kubernetes Security Checklist: 50 Best Practices (2026)

All 50 Kubernetes security best practices in one place — access control, pod security, network policy, secrets, and operations, each with YAML you can apply today and the compliance frameworks it satisfies.

Introduction to Kubernetes Security: Why a Comprehensive Approach Matters

Kubernetes security is inherently complex and multi-layered, spanning access control and authentication, network isolation and traffic policies, secrets and sensitive data management, container image security and vulnerability scanning, runtime security and threat detection, cluster hardening and infrastructure protection, and compliance with regulatory frameworks like SOC 2, HIPAA, PCI-DSS, and GDPR. A single misconfiguration or oversight in any of these layers can expose your entire infrastructure to severe security incidents including unauthorized data access where attackers read sensitive customer information or proprietary business data, privilege escalation where attackers gain cluster-admin rights and take complete control of the cluster, lateral movement where compromised containers access other pods, databases, or cloud resources they shouldn't reach, data exfiltration where attackers steal databases or secrets and transmit them externally, cryptomining where attackers deploy resource-intensive cryptocurrency miners consuming your cloud budget, ransomware attacks encrypting persistent volumes and demanding payment, supply chain attacks through compromised base images or malicious dependencies, and compliance violations resulting in regulatory fines, failed audits, loss of certifications, and reputational damage that drives customers away.

The challenge is that Kubernetes security isn't a single toggle or configuration it requires implementing dozens of interconnected controls across multiple dimensions. You can have perfect RBAC preventing unauthorized human access, but if you allow privileged containers, attackers can escape containers and compromise nodes. You can lock down pod security, but if network policies aren't implemented, compromised pods can scan and attack other services across your cluster. You can secure the cluster itself, but if you pull untrusted container images without vulnerability scanning, you deploy pre-compromised applications directly into production.

This comprehensive Kubernetes security checklist provides 50 actionable, production-tested security practices organized into logical categories, based on official security frameworks including the CIS Kubernetes Benchmark (industry-standard security configuration guide), NSA and CISA Kubernetes Hardening Guide (government security guidance), Kubernetes Security documentation and CVE analysis, and real-world production security incidents and lessons learned from breaches. Each practice includes clear implementation instructions, explains why it matters with real attack scenarios, provides ready-to-use YAML configurations or kubectl commands, and indicates compliance frameworks it addresses (CIS, SOC 2, HIPAA, PCI-DSS). We'll also show how a one-click posture scan can check many of these controls against your live cluster, so you know which of the 50 you already fail before you start.

By methodically implementing these 50 practices, you'll establish defense-in-depth security posture for your Kubernetes infrastructure, dramatically reduce attack surface and risk exposure, meet regulatory compliance requirements with auditable controls, prevent the most common Kubernetes security incidents that plague improperly secured clusters, and gain security confidence enabling your organization to move faster with Kubernetes while maintaining strong security rather than treating security and velocity as opposing forces.

The 50 Kubernetes security practices organised as five layers of defense

The 50 practices form five layers of defense — an attacker has to get through all of them.

Category 1: Access Control & Authentication (Practices 1-10)

Practice 1: Enable RBAC Authorization

Implementation: Ensure Kubernetes API server runs with --authorization-mode=RBAC (default in Kubernetes 1.6+)

Verification:

# Check RBAC is enabled
kubectl api-versions | grep rbac
# Should show:
# rbac.authorization.k8s.io/v1

Why it matters: RBAC is the foundation of Kubernetes security. Without it, you have no access control anyone who can authenticate can do anything. This is the most critical security control.

Compliance: Required by CIS 3.1.1, SOC 2, HIPAA, PCI-DSS

Practice 2: Disable Anonymous Authentication

Implementation: Set --anonymous-auth=false on API server

Why it matters: Anonymous auth allows unauthenticated requests to API server with default permissions. This creates unnecessary attack surface. All requests should require authentication.

Verification:

# Try anonymous request (should fail)
curl -k https://CLUSTER_IP:6443/api/v1/namespaces
# Should return 401 Unauthorized if anonymous auth disabled

Compliance: CIS 1.2.1, NSA/CISA Hardening Guide

Practice 3: Implement Strong Authentication (OIDC/LDAP)

Implementation: Configure OIDC or LDAP instead of static client certificates

# API server OIDC flags
--oidc-issuer-url=https://accounts.google.com
--oidc-client-id=kubernetes
--oidc-username-claim=email
--oidc-groups-claim=groups

Why it matters: Client certificates don't expire, can't be revoked easily, and lack MFA support. OIDC enables SSO, MFA, automatic expiration, centralized revocation, and group-based RBAC.

Compliance: SOC 2 (CC6.1), HIPAA (164.312)

Practice 4: Never Grant cluster-admin to Regular Users

Implementation: Audit and remove unnecessary cluster-admin bindings

# List all cluster-admin bindings
kubectl get clusterrolebindings -o json | \\
  jq '.items[] | select(.roleRef.name=="cluster-admin") | 
      {name: .metadata.name, subjects: .subjects}'
# Remove binding for regular user
kubectl delete clusterrolebinding alice-admin

Why it matters: cluster-admin grants unlimited cluster access can read all secrets, delete all resources, modify RBAC, access nodes. Principle of least privilege: grant specific permissions needed, not god-mode access.

Compliance: CIS 5.1.1, SOC 2, all frameworks

Practice 5: Enable Comprehensive Audit Logging

Implementation: Configure API server audit policy

--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-maxage=30
--audit-log-maxbackup=10
--audit-log-maxsize=100
--audit-policy-file=/etc/kubernetes/audit-policy.yaml

Audit policy example:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log secret access at Metadata level (who accessed, not content)
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
# Log RBAC changes at Request level (full details)
- level: RequestResponse
  resources:
  - group: "rbac.authorization.k8s.io"
    resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
# Log pod exec/attach at Metadata level
- level: Metadata
  resources:
  - group: ""
    resources: ["pods/exec", "pods/attach"]

Why it matters: Audit logs provide forensics for security incidents, compliance evidence for auditors, debugging trail for "who changed what when," and detect unauthorized access attempts. Without auditing, you're blind to security events.

Compliance: SOC 2 (CC7.2), HIPAA (164.312(b)), PCI-DSS (10.2)

Practice 6: Disable ServiceAccount Token Auto-Mount

Implementation: Set automountServiceAccountToken: false by default

# Namespace-wide default
apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: production
automountServiceAccountToken: false
# Or per-pod
spec:
  automountServiceAccountToken: false

Why it matters: By default, every pod gets ServiceAccount token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token. If pod compromised, attacker gets token for Kubernetes API access. Only mount when actually needed.

Compliance: CIS 5.1.5

Practice 7: Create Dedicated ServiceAccounts per Application

Implementation: Never use default ServiceAccount

# Create app-specific ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: payment-service-sa
  namespace: production
---
# Use in deployment
spec:
  serviceAccountName: payment-service-sa

Why it matters: Default ServiceAccount is shared by all pods in namespace. Compromising one pod compromises all if they share ServiceAccount. Separate ServiceAccounts enable least-privilege RBAC per application.

Compliance: CIS 5.1.5, SOC 2

Practice 8: Implement Multi-Factor Authentication for Admin Access

Implementation: Require MFA for kubectl access via OIDC provider

Why it matters: Passwords alone are weak (phishing, credential stuffing, password reuse). MFA (something you know + something you have) dramatically reduces account takeover risk. Critical for privileged access.

Compliance: SOC 2 (CC6.1), PCI-DSS (8.3)

Practice 9: Rotate Credentials Regularly

Implementation: Automate credential rotation

  • ServiceAccount tokens: Every 90 days
  • TLS certificates: Before expiration (typically 1 year)
  • Database passwords in Secrets: Every 90 days
  • API keys: Every 180 days

Why it matters: Credential rotation limits exposure window if credentials compromised. Stolen credentials become useless after rotation.

Compliance: SOC 2, PCI-DSS (8.2.4)

Practice 10: Implement Session Timeout and Token Expiration

Implementation: Configure short-lived tokens via OIDC

--oidc-username-claim=email
--oidc-groups-claim=groups
# Tokens expire based on OIDC provider config (15-60 minutes typical)

Why it matters: Long-lived tokens remain valid even after user leaves company or role changes. Short expiration forces re-authentication, ensuring access reflects current authorization.

Category 2: Pod Security Standards (Practices 11-20)

Practice 11: Enforce Pod Security Standards at Namespace Level

Implementation: Label namespaces with Pod Security Standard level

# Production: Restricted (most secure)
kubectl label namespace production \\
  pod-security.kubernetes.io/enforce=restricted \\
  pod-security.kubernetes.io/audit=restricted \\
  pod-security.kubernetes.io/warn=restricted
# Staging: Baseline
kubectl label namespace staging \\
  pod-security.kubernetes.io/enforce=baseline
# Dev: Privileged (unrestricted)
kubectl label namespace dev \\
  pod-security.kubernetes.io/enforce=privileged

Why it matters: Pod Security Standards replaced deprecated PodSecurityPolicies in Kubernetes 1.25+. They enforce security baselines preventing privileged containers, host namespace sharing, and other dangerous configurations.

Compliance: CIS 5.2.x, NSA/CISA Hardening

Practice 12: Never Run Containers as Root

Implementation: Set runAsNonRoot: true and runAsUser: 1000

securityContext:
  runAsNonRoot: true  # Enforces non-root
  runAsUser: 1000     # Specific UID
  runAsGroup: 3000
  fsGroup: 2000       # For volume permissions

Why it matters: Running as root (UID 0) inside containers increases risk of container escape attacks. If attacker escapes container, they have root on host. Non-root limits damage.

Compliance: CIS 5.2.6, Required by PSS "restricted" level

Practice 13: Drop All Linux Capabilities

Implementation: Drop ALL capabilities, add only specific ones needed

securityContext:
  capabilities:
    drop:
    - ALL                # Drop everything
    add:
    - NET_BIND_SERVICE  # Only if need to bind to port < 1024

Why it matters: Linux capabilities grant partial root privileges (CAP_SYS_ADMIN, CAP_NET_ADMIN, etc.). Dropping ALL removes dangerous capabilities attackers could exploit for privilege escalation.

Compliance: CIS 5.2.9, PSS "restricted"

Practice 14: Use Read-Only Root Filesystem

Implementation:

securityContext:
  readOnlyRootFilesystem: true
# Use emptyDir for writable paths
volumes:
- name: tmp
  emptyDir: {}
- name: cache
  emptyDir: {}
volumeMounts:
- name: tmp
  mountPath: /tmp
- name: cache
  mountPath: /var/cache

Why it matters: Read-only filesystem prevents attackers from writing malware, modifying binaries, or persisting backdoors. Forces immutable infrastructure pattern.

Compliance: PSS "restricted" recommended

Practice 15: Disable Privilege Escalation

Implementation:

securityContext:
  allowPrivilegeEscalation: false

Why it matters: Prevents setuid/setgid binaries from gaining elevated privileges. Blocks common container escape techniques relying on privilege escalation.

Compliance: CIS 5.2.5, PSS "restricted" required

Practice 16: Set Resource Limits on All Containers

Implementation:

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi

Why it matters: Prevents resource exhaustion attacks (cryptominers consuming all CPU, memory bombs crashing nodes). Limits blast radius of compromised containers. Also prevents noisy neighbor problems.

Compliance: CIS 5.2.1, CIS 5.2.2

Practice 17: Implement Liveness and Readiness Probes

Implementation:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

Why it matters: Detects and automatically restarts compromised or malfunctioning containers. Prevents zombie processes from serving traffic.

Compliance: High availability best practice

Practice 18: Scan Container Images for Vulnerabilities

Implementation: Integrate Trivy, Snyk, or Aqua in CI/CD

# Trivy image scan in pipeline
trivy image --severity HIGH,CRITICAL my-app:v1.2.3
# Fail build if HIGH or CRITICAL vulnerabilities found

Why it matters: Container images often contain known vulnerabilities (CVEs). Scanning prevents deploying vulnerable software. Most breaches exploit known vulnerabilities with available patches.

Compliance: CIS 5.4.1, SOC 2

Practice 19: Use Minimal Base Images (Distroless or Alpine)

Implementation: Use Google Distroless or Alpine Linux base images

# Instead of:
FROM ubuntu:22.04  # 77MB, many packages, large attack surface
# Use:
FROM gcr.io/distroless/static-debian11  # 2MB, no shell, minimal attack surface
# Or
FROM alpine:3.19  # 7MB, minimal packages

Why it matters: Fewer packages = fewer vulnerabilities = smaller attack surface. Distroless images have no shell, package managers, or unnecessary binaries attackers could use.

Compliance: CIS 5.4.3

Practice 20: Implement Image Signing and Verification

Implementation: Use Sigstore/Cosign or Docker Content Trust

# Sign image with Cosign
cosign sign --key cosign.key my-registry.com/my-app:v1.2.3
# Verify signature in admission controller
# (prevents running unsigned or tampered images)

Why it matters: Prevents supply chain attacks where attackers replace legitimate images with malicious versions. Signing ensures image integrity and authenticity.

Compliance: SLSA Level 3, Supply Chain Security

Category 3: Network Security (Practices 21-30)

Practice 21: Implement Default Deny Network Policies

Implementation: Create deny-all as baseline

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

Why it matters: Default deny = zero-trust networking. Nothing can communicate unless explicitly allowed. Limits lateral movement if container compromised.

See which of these 50 your cluster already fails.

Free, read-only security scan. One click. Nothing changes in your cluster.

Scan your cluster →

Compliance: CIS 5.3.2, Zero Trust Architecture

Practice 22: Explicitly Allow Only Required Traffic

Implementation: Create allow policies for legitimate communication

# Allow frontend -> backend on port 8080 only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080  # Only this port

Why it matters: Whitelist-only approach prevents unexpected connections. If backend database compromised, it can't initiate outbound connections to exfiltrate data (egress blocked).

Practice 23: Always Allow DNS (Critical)

Implementation: Allow egress to kube-dns/CoreDNS

egress:
- to:
  - namespaceSelector:
      matchLabels:
        name: kube-system  # DNS pods in kube-system
  ports:
  - protocol: UDP
    port: 53  # DNS

Why it matters: Everything breaks without DNS. This is the #1 Network Policy mistake — blocking DNS and wondering why nothing works.

Practice 24: Enforce mTLS Between Services with a Service Mesh

Implementation: Enable strict mTLS in your service mesh (e.g., Istio, Linkerd) so all pod-to-pod traffic is encrypted and authenticated.

Example (Istio):

apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata:
              name: default
              namespace: production spec:
              mtls:
                mode: STRICT  # Require mTLS for all workloads in this namespace
            --- apiVersion: security.istio.io/v1beta1 kind: DestinationRule metadata:
              name: backend-mtls
              namespace: production spec:
              host: backend.production.svc.cluster.local
              trafficPolicy:
                tls:
                  mode: ISTIO_MUTUAL 

Why it matters: mTLS encrypts traffic in transit and verifies the identity of both client and server using certificates. This prevents eavesdropping, spoofing, and man-in-the-middle attacks between microservices and enforces strong, workload-level identity.

Compliance: Zero Trust Architecture, SOC 2 (CC6.x), HIPAA (164.312(e)), PCI-DSS 4.0 (Data in Transit Encryption)

Practice 25: Enforce TLS for Ingress — HTTPS Everywhere

Implementation: Terminate HTTPS at the Ingress (or API gateway) using valid certificates (Let's Encrypt via cert-manager, or enterprise PKI). Redirect all HTTP to HTTPS.

Example (Nginx Ingress + cert-manager):

apiVersion: networking.k8s.io/v1 kind: Ingress metadata:
              name: prod-app
              namespace: production
              annotations:
                cert-manager.io/cluster-issuer: letsencrypt-prod
                nginx.ingress.kubernetes.io/force-ssl-redirect: "true" spec:
              ingressClassName: nginx
              tls:
              - hosts:
                - app.example.com
                secretName: prod-app-tls
              rules:
              - host: app.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: app-service
                        port:
                          number: 80 

Why it matters: Without TLS, credentials, tokens, and data travel in plaintext and can be intercepted or modified. Enforcing HTTPS for all external traffic is a fundamental security control and often a regulatory requirement.

Compliance: PCI-DSS (4.x — Strong Cryptography), HIPAA (164.312(e)), SOC 2 (CC6.1)

Practice 26: Isolate and Protect the Kubernetes Control Plane

Implementation: Restrict access to the Kubernetes API server to trusted networks only (VPN, bastion hosts, office IPs). Avoid exposing the API directly to the public internet.

Examples:

Use private API endpoints for managed clusters (EKS/GKE/AKS) where possible.

Restrict public access with firewall rules / security groups / master authorized networks.

Force admins to access the API via VPN or bastion.

Example: allow API access only from VPN CIDR (conceptual)
security group / firewall rule:
ALLOW tcp 443 FROM 10.0.0.0/16 (VPN)
DENY tcp 443 FROM 0.0.0.0/0 (Internet)

Why it matters: The Kubernetes API is the brain of the cluster. If an attacker reaches it and finds misconfigurations or weak credentials, they can compromise everything. Network isolation dramatically reduces the attack surface and brute-force attempts.

Compliance: CIS Kubernetes Benchmark (API server controls), SOC 2 (CC6.x), Zero Trust Network principles

Practice 27: Enable CNI Network Flow Logging for Forensics

Implementation: Turn on network flow logging in your CNI plugin (e.g., Calico Flow Logs, Cilium Hubble) and send logs to your central logging/SIEM system.

Example (Calico — FelixConfiguration):

apiVersion: projectcalico.org/v3 kind: FelixConfiguration metadata:
              name: default spec:
              flowLogsFlushInterval: 10s
              flowLogsFileEnabled: true
              flowLogsFileDirectory: /var/log/calico/flows 

Ship /var/log/calico/flows to Loki/ELK/SIEM with an agent (Fluent Bit, Vector, etc.).

Why it matters: Flow logs show who talked to whom, when, and on which ports. They are invaluable for incident investigations, detecting suspicious lateral movement, and validating that NetworkPolicies work as intended.

Compliance: SOC 2 (CC7.x — logging & monitoring), PCI-DSS (10.x — log all network access to cardholder data)

Practice 28: Use Private Container Registries and Restrict Image Sources

Implementation: Store images in private registries (ECR, GCR, ACR, Harbor) and restrict nodes to pull only from approved registries.
Create an imagePullSecret:

apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: production
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-dockerconfigjson>

Attach it to your ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
imagePullSecrets:
name: regcred

At the network layer, allow egress from nodes only to your approved registries (via firewall rules, VPC endpoints, or NetworkPolicies).

Why it matters: Pulling images from random public registries is a major supply chain risk. Private, controlled registries plus restricted egress prevent untrusted or malicious images from entering your environment.

Compliance: Supply Chain Security (SLSA), SOC 2 (CC6.x), PCI-DSS 4.0 (Software Integrity)

Practice 29: Implement Egress Filtering and Outbound Firewalls

Implementation: Use NetworkPolicies, egress gateways, and/or cloud firewalls to explicitly control outbound traffic from pods and nodes.

Example (restrict egress to a specific external service):

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:
              name: allow-egress-to-payments
              namespace: production spec:
              podSelector:
                matchLabels:
                  app: backend
              policyTypes:
              - Egress
              egress:
              - to:
                - ipBlock:
                    cidr: 203.0.113.10/32  # payments-api.example.com
                ports:
                - protocol: TCP
                  port: 443 

Combine with cloud firewall rules (NACLs / Security Groups) so that default is deny and only specific destinations (databases, payment gateways, APIs, logging endpoints) are allowed.

Why it matters: Without egress controls, a compromised pod can exfiltrate data to any IP on the internet or connect to attacker C2 servers. Egress filtering limits damage and is essential for Zero Trust.

Compliance: Zero Trust Architecture, PCI-DSS (restrict outbound connections), SOC 2 (CC6.x)

Practice 30: Monitor Network Traffic with IDS/NDR

Implementation: Deploy network detection and response (NDR) or IDS tooling that monitors Kubernetes traffic patterns for anomalies:

Use eBPF-based tools (e.g., Cilium Hubble, Tetragon) to observe connections.

Mirror traffic to IDS (Zeek/Suricata) using cloud traffic mirroring / SPAN.

Send alerts to your SIEM when suspicious patterns appear (port scans, unusual outbound connections, spikes in failed connections).

Conceptual example (Hubble UI deployment):

# Assumes Cilium is installed with Hubble enabled
            cilium hubble enable
            cilium hubble ui
            

Why it matters: Even with strong NetworkPolicies, you need visibility into what is actually happening on the wire. Network monitoring detects stealthy attacks, lateral movement attempts, and policy misconfigurations that logs alone might miss.

Compliance: SOC 2 (CC7.2 — detect and respond to security events), PCI-DSS (10.x & 11.x — monitoring and intrusion detection)

Category 4: Secrets & Configuration Management (Practices 31-40)

Practice 31: Encrypt Kubernetes Secrets at Rest

Implementation: Ensure secrets are encrypted at rest in etcd and any underlying storage.

For managed clusters, enable provider-managed encryption (EKS, GKE, AKS all support etcd/secret encryption configurations).

For self-managed clusters, configure an EncryptionConfiguration for the API server:

kind: EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

Then start the API server with:

--encryption-provider-config=/path/to/encryption-config.yaml
            

Why it matters: By default, secrets are only base64-encoded, not truly encrypted. If an attacker gains access to etcd or underlying disk snapshots, they can read all secrets. Encryption at rest ensures an additional layer of protection even if storage is compromised.

Compliance: CIS Kubernetes Benchmark (Secret Encryption), SOC 2 (CC6.x), PCI-DSS 4.0 (Strong Cryptography for Sensitive Data)

Practice 32: Use an External Secrets Manager (Vault, AWS Secrets Manager, etc.)

Implementation: Store sensitive values in an external secrets manager and sync them into Kubernetes using an operator like External Secrets Operator, Secrets Store CSI Driver, or Vault Agent Injector.

Example (External Secrets Operator + AWS Secrets Manager):

apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata:
              name: app-db-credentials
              namespace: production spec:
              refreshInterval: 1h
              secretStoreRef:
                name: aws-secrets
                kind: ClusterSecretStore
              target:
                name: app-db-secret
                creationPolicy: Owner
              data:
              - secretKey: username
                remoteRef:
                  key: prod/app/db
                  property: username
              - secretKey: password
                remoteRef:
                  key: prod/app/db
                  property: password 

Why it matters: External managers give you strong access controls, auditing, rotation, and key management capabilities that Kubernetes alone doesn't provide. Kubernetes then only holds short-lived copies of secrets needed at runtime. For a full comparison of the options, see our Kubernetes secrets management guide.

Compliance: SOC 2 (CC6.x, CC7.x), PCI-DSS (3.x, 7.x), HIPAA (164.312(a))

Practice 33: Keep Secrets Out of Git (Git Hygiene)

Implementation:

  • Never commit real passwords, API keys, or certificates to Git.
  • Use placeholders in manifests (e.g., {{DB_PASSWORD}}) and populate them from a CI/CD or GitOps tool using environment variables or secret stores.
  • Add .env, secrets/*.yaml, and similar files to .gitignore.
  • Use automated secret scanners (TruffleHog, GitLeaks, GitHub secret scanning) and pre-commit hooks.

Example pre-commit configuration:

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks

If secrets were accidentally committed, revoke & rotate them; do not just delete the file from Git history.

Why it matters: Once a secret is in Git, it's effectively permanent — clones, forks, and backups can expose it indefinitely. Git is for code, not real credentials.

Compliance: SOC 2 (Change Management & Access Control), PCI-DSS (Secure Development Practices), OWASP ASVS (V1.9 Secret Management)

Practice 34: Implement Regular Secret Rotation

Implementation:

Define rotation intervals per secret type (e.g., API keys every 90 days, DB passwords every 30–60 days).

Use your external secrets manager's rotation features (AWS Secrets Manager, Vault, etc.).

In Kubernetes, rely on operators that auto-refresh secrets used by workloads.

Example (ExternalSecret with automatic refresh):

apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata:
              name: app-api-key
              namespace: production spec:
              refreshInterval: 15m  # pick based on rotation policy
              secretStoreRef:
                name: aws-secrets
                kind: ClusterSecretStore
              target:
                name: app-api-key
              data:
              - secretKey: api-key
                remoteRef:
                  key: prod/app/api
                  property: key 

Workloads should reload secrets either via rolling deployments (triggered by secret changes) or by watching mounted volumes.

Why it matters: Long-lived credentials are easier to abuse and harder to revoke if leaked. Regular rotation reduces attacker dwell time and limits blast radius.

Compliance: PCI-DSS (password/API key rotation), SOC 2 (CC6.x), NIST 800-53 (IA-5)

Practice 35: Never Inject Secrets via Environment Variables

Implementation: Mount secrets as files from volumes instead of exposing them as environment variables.

spec:
  containers:
  - name: app
    volumeMounts:
    - name: db-creds
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: db-creds
    secret:
      secretName: app-db-secret

Why it matters: Environment variables leak in ways files do not — they are inherited by every child process, dumped by crash handlers and debug endpoints, and routinely printed by application frameworks and logging libraries on startup. Volume-mounted secrets also update in place when the Secret changes, while env vars are frozen until the pod restarts.

Compliance: Kubernetes Secrets good practices (kubernetes.io), SOC 2 (CC6.x), PCI-DSS (protect sensitive data in memory and logs)

Practice 36: Use Sealed Secrets / Encrypted Manifests for GitOps

Implementation: Use tools like Sealed Secrets, SOPs, or SOPS + KMS to store encrypted secret manifests in Git, so they are only decrypted inside the cluster.

Example (Bitnami SealedSecret):

apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata:
              name: app-db-secret
              namespace: production spec:
              encryptedData:
                username: AgBsdY...
                password: AgC34k...
              template:
                type: Opaque
                metadata:
                  name: app-db-secret
                  namespace: production 

The controller in the cluster decrypts this into a normal Secret object. The private key never leaves the cluster; Git only sees encrypted values.

Why it matters: This enables GitOps workflows while still keeping real secret values encrypted at rest in version control. Even if the repo leaks, the attacker cannot read the plaintext secrets.

Compliance: GitOps + Secret Management Best Practices, SOC 2 (Change Management), PCI-DSS (protect stored sensitive data)

Practice 37: Enable Audit Logging for Secret Access

Implementation:

  • Enable Kubernetes API audit logs (or the managed equivalent) and ensure get / list calls on secrets are logged with user identity.
  • Forward audit logs to a central log system (Loki, ELK, cloud-native logging, SIEM).
  • Create alerts for:
    • Unusual spikes in get secrets calls
    • Attempts from unexpected service accounts or users
    • Access to secrets in restricted namespaces

Conceptual example (high-level only):

  • Enable an audit policy that includes:
resources: ["secrets"]
verbs: ["get", "list"]
level: RequestResponse
  • Ship logs to a SIEM and create detections.

Why it matters: Without audit logs, you can't answer "who accessed which secret and when?" during an incident. Audit trails are essential for investigations and compliance.

Compliance: PCI-DSS (10.x — logging), SOC 2 (CC7.2 — detect anomalies), HIPAA (audit controls)


Practice 38: Separate Secrets by Environment and Namespace

Implementation:

  • Use separate namespaces and secrets per environment: dev, staging, production.
  • Avoid sharing the same secret object across environments.
  • Use clear naming conventions, for example:
Namespace: production
Secret names:
  app-db-credentials
  app-payment-api
  app-jwt-keys
Namespace: staging
Secret names:
  app-db-credentials
  app-payment-api
  app-jwt-keys

Combined with network and RBAC rules, this ensures dev/stage workloads never access production secrets.

Why it matters: Mixing environments increases the risk of a lower-security environment (dev) being used as a stepping stone to production secrets. Environment isolation is foundational to a secure deployment model.

Compliance: PCI-DSS (segregation of environments), SOC 2 (Change Management & Segregation of Duties)

Practice 39: Version and Track Secret Changes

Implementation:

  • Use your secret manager's versioning features (e.g., AWS Secrets Manager versions, Vault versions).
  • In GitOps, treat secret definitions (templates/placeholders) like any other config — code review, PRs, approvals.
  • Add annotations/labels to Kubernetes Secrets to record purpose and rotation information:
apiVersion: v1
kind: Secret
metadata:
  name: app-db-secret
  namespace: production
  labels:
    app: backend
  annotations:
    security.squareops.com/owner: "platform-team"
    security.squareops.com/rotation-frequency: "30d"
    security.squareops.com/last-rotated: "2025-01-10"
type: Opaque
data:
  username: ...
  password: ...
  • Ensure every change to secret values is traceable to:
    • Who initiated it
    • When it was done
    • Why it changed (ticket/PR reference)

Why it matters: Versioning and traceability help you roll back quickly if a change breaks something and provide evidentiary records for audits and incident analysis.

Compliance: SOC 2 (Change Management & Auditability), PCI-DSS (configuration & change control), ISO 27001 (A.12.1.2)

Practice 40: Monitor Secret Expiration and Misconfigurations

Implementation:

  • Track expiration of:
    • TLS certificates
    • API keys and tokens
    • Database credentials (where applicable)
  • Use monitoring tools or custom scripts/CronJobs that:
    • Parse certificates stored in Secrets
    • Check notAfter dates
    • Emit metrics or logs when certificates are close to expiry (e.g., < 30 days)

Example (conceptual CronJob):

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cert-expiry-checker
  namespace: platform
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: cert-checker
          containers:
          - name: checker
            image: your-registry/cert-checker:latest
            args:
              - "--namespace=production"
              - "--warning-days=30"
          restartPolicy: OnFailure
  • Alert on:
    • Secrets nearing expiry
    • Secrets without rotation annotations
    • Secrets with overly broad access (identified via periodic RBAC review)

Why it matters: Many outages and incidents are caused by expired certificates or forgotten tokens. Proactive monitoring turns expiration from an emergency into a routine maintenance task and reduces the risk of unexpected downtime.

Compliance: SOC 2 (Availability & Security), PCI-DSS (certificate/key lifecycle management), NIST 800-53 (Key Management & Maintenance)

Category 5: Cluster Operations & Runtime Security (Practices 41-50)

Practice 41: Keep Kubernetes Updated with Security Patches

Implementation:

  • Track the Kubernetes version lifecycle (end-of-support dates) for your distribution or cloud provider.
  • Standardize on a set of supported versions (e.g., N-1 or N-2 from the latest stable).
  • Use managed cluster upgrade mechanisms (EKS/GKE/AKS) or automation (kOps, kubeadm, Cluster API) to:
    • Upgrade control plane first.
    • Then upgrade worker nodes using rolling node pool/node group updates.
  • Test upgrades in a staging cluster before production and verify key workloads/CI/CD flows.
  • Combine with node OS patching (managed node images, golden images, or OS patch management tools).

Why it matters: Older Kubernetes versions lose security support and may contain known vulnerabilities and deprecated APIs. Regular cluster and node OS patching closes known CVEs, keeps your environment compatible with modern tooling, and is often required by compliance frameworks.

Compliance: CIS Kubernetes Benchmark, SOC 2 (Change Management & Security), PCI-DSS (system components must be kept current with security patches), ISO 27001 (A.12.6.1)

Practice 42: Enforce Admission Controls (OPA Gatekeeper / Kyverno)

Implementation:

  • Deploy a policy engine such as OPA Gatekeeper or Kyverno as an admission controller.
  • Define policies that enforce baseline security rules, for example:
    • No privileged containers.
    • No hostPath volumes unless explicitly allowed.
    • Only approved container registries.
    • Mandatory labels/annotations for ownership and environment.
  • Start in audit mode to see violations without blocking deployments, then gradually switch to enforce mode.

Example (Kyverno policy to block privileged containers):

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

Why it matters: Admission controllers are the last checkpoint before workloads land in the cluster. They prevent risky configurations from ever being created and standardize security requirements across teams and namespaces.

Compliance: CIS Kubernetes Benchmark (Admission Control), SOC 2 (preventive controls), PCI-DSS (secure configuration & change control)

Practice 43: Disable or Strongly Secure the Kubernetes Dashboard

Implementation:

  • Best option: Do not deploy the legacy Kubernetes Dashboard in production. Use managed UIs (EKS/GKE/AKS consoles) or a hardened third-party dashboard.
  • If you must run it:
    • Never expose it directly to the public internet.
    • Require authentication via OIDC/SSO or a short-lived kubeconfig.
    • Bind it only to least-privileged service accounts (no cluster-admin by default).
    • Restrict access using NetworkPolicies, firewall rules, or VPN-only access.

Why it matters: Historically, misconfigured dashboards have been a frequent cause of full-cluster compromise. An exposed, high-privilege dashboard is effectively a remote root console for your cluster.

Compliance: CIS Kubernetes Benchmark (Dashboard), SOC 2 (Access Control), PCI-DSS (restrict access to management interfaces)

Practice 44: Enforce ResourceQuotas and LimitRanges

Implementation:

  • Define ResourceQuota per namespace to limit total CPU, memory, and object counts (pods, services, PVCs).
  • Define LimitRange to ensure containers set sensible requests and limits and to cap max usage per container/pod.
  • Apply stricter quotas for multi-tenant or shared namespaces.

Example (ResourceQuota and LimitRange):

apiVersion: v1
kind: ResourceQuota
metadata:
  name: prod-quota
  namespace: production
spec:
  hard:
    requests.cpu: "20"
    requests.memory: 40Gi
    limits.cpu: "40"
    limits.memory: 80Gi
    pods: "200"

---
apiVersion: v1
kind: LimitRange
metadata:
  name: prod-limits
  namespace: production
spec:
  limits:
    - type: Container
      default:
        cpu: "500m"
        memory: 512Mi
      defaultRequest:
        cpu: "100m"
        memory: 128Mi
      max:
        cpu: "4"
        memory: 4Gi

Why it matters: Without quotas and limits, a single misbehaving workload can starve the node or cluster (CPU/memory exhaustion), causing cascading outages. Resource controls are a reliability and security boundary for multi-tenant clusters.

Compliance: SOC 2 (Availability & Capacity Management), SRE Best Practices (multi-tenant isolation), PCI-DSS (availability of critical services)

Practice 45: Use PodDisruptionBudgets (PDBs) for Safer Upgrades

Implementation:

  • Define PodDisruptionBudget for critical deployments and stateful services to control how many pods can be voluntarily disrupted at once (e.g., during node drains, upgrades, or autoscaling).
  • Use either:
    • minAvailable — minimum number of replicas that must stay running, or
    • maxUnavailable — maximum number of replicas that can be down simultaneously.
  • Validate that rolling upgrades and node maintenance respect the PDB and keep enough healthy pods serving traffic.

Example (PodDisruptionBudget for a 3-replica deployment):

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: backend-pdb
  namespace: production
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: backend

Why it matters: Without PDBs, automated node drains or rolling updates can briefly take down all replicas of a service, causing outages even when the overall system is healthy. PDBs enforce availability guarantees during planned disruptions.

Compliance: SOC 2 (Availability), SRE Best Practices (graceful maintenance), PCI-DSS (maintain availability of systems that store, process, or transmit cardholder data)

Practice 46: Monitor Runtime Threats with Falco (or Similar)

Implementation:

  • Deploy a runtime security tool such as Falco, Sysdig Secure, or other eBPF-based detectors to watch for suspicious behavior at the node and container level.
  • Use built-in Falco rules to detect:
    • Shell spawned inside containers
    • Unexpected file changes in system directories
    • Privilege escalation attempts
    • Unexpected outbound connections or port scans
  • Configure Falco to send alerts to your logging stack or incident response tools (Slack, PagerDuty, SIEM, etc.).
  • Start with alert-only mode, then refine rules and severities to reduce noise.

Example (simplified Falco rule to detect a shell in a container):

- rule: Terminal shell in container
  desc: Detect interactive shell in a container
  condition: >
    spawned_process and container and
    proc.name in (bash, sh, zsh, ash)
  output: >
    Shell spawned in container (user=%user.name container_id=%container.id
    image=%container.image.repository:%container.image.tag cmdline=%proc.cmdline)
  priority: WARNING
  tags: [container, shell, mitre_execution]

Why it matters: Static scans and policies catch misconfigurations before deployment, but attackers (or buggy apps) can still behave maliciously at runtime. Runtime threat detection adds a final layer of defense by spotting abnormal behavior inside containers and nodes.

Compliance: SOC 2 (CC7.x — detect and respond to anomalies), PCI-DSS (11.x — intrusion detection), NIST 800-53 (SI family — Security Monitoring)

Practice 47: Implement Backup & Disaster Recovery for Cluster State and Data

Implementation:

  • Back up:
    • Cluster state (etcd or control-plane config for self-managed clusters).
    • Kubernetes objects (Deployments, Services, Ingresses, CRDs, etc.).
    • Persistent volume data (databases, file stores) using tools like Velero or storage provider snapshots.
  • Use Velero (or similar) to back up namespaces, resources, and volumes to an object store (S3/GCS/Azure Blob/minio).
  • Define and regularly test restore procedures in a separate cluster or environment.
  • Document RPO/RTO targets and verify backups meet those requirements.

Example (Velero backup schedule):

apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: daily-prod-backup
  namespace: velero
spec:
  schedule: "0 1 * * *" # daily at 01:00
  template:
    includedNamespaces:
      - production
    ttl: 168h # retain for 7 days
    snapshotVolumes: true

Why it matters: Even with strong security, accidents happen: bad deployments, corruption, or cloud-region incidents. Without tested backups and DR, you risk extended downtime and data loss. A hardened cluster must be recoverable, not just secure.

Compliance: SOC 2 (Availability & Processing Integrity), PCI-DSS (12.x — backup & DR), ISO 27001 (A.17 — Business continuity)

Practice 48: Harden Worker Nodes and Underlying OS

Implementation:

  • Use minimal, Kubernetes-optimized OS images (e.g., EKS-optimized AMIs, COS, Flatcar, or other hardened images).
  • Restrict SSH access:
    • Disable SSH entirely where possible or allow only via bastion/VPN.
    • Enforce key-based auth, no password login, and short-lived access.
  • Apply OS-level hardening:
    • Enable automatic security updates or frequent patching.
    • Disable unnecessary services/daemons.
    • Configure firewall rules (iptables/nftables/security groups) with least privilege.
  • Harden cloud metadata access (IMDSv2 only, restricted hops) so pods cannot freely read instance credentials.
  • Use nodegroups or autoscaling groups with immutable images (bake changes into new images and roll out).

Why it matters: Kubernetes security depends on the host OS. If an attacker escapes a container or exploits a kernel vulnerability, poorly hardened nodes can give them full control. A secure, patched, minimal OS dramatically reduces this risk.

Compliance: CIS Benchmarks (Linux/OS hardening), SOC 2 (Infrastructure Security), PCI-DSS (system hardening & patching), NIST 800-53 (SC & CM families)

Practice 49: Run Regular Security Audits with kube-bench and Other Scanners

Implementation:

  • Use kube-bench to check your cluster against the CIS Kubernetes Benchmark regularly (manually or via scheduled jobs).
  • Complement with:
    • kube-hunter or similar tools for network-facing vulnerabilities.
    • kubescape or Trivy Kubernetes to evaluate cluster posture & workload misconfigurations.
  • Integrate these tools into CI/CD or a periodic scanning job and store reports centrally.
  • Track remediation of high/critical findings like normal vulnerability management (tickets, SLAs, owners).

Example (running kube-bench as a Job):

apiVersion: batch/v1
kind: Job
metadata:
  name: kube-bench
  namespace: security
spec:
  template:
    spec:
      serviceAccountName: kube-bench
      hostPID: true
      containers:
        - name: kube-bench
          image: aquasec/kube-bench:latest
          securityContext:
            privileged: true
          volumeMounts:
            - name: var-lib-kubelet
              mountPath: /var/lib/kubelet
              readOnly: true
            - name: etc-systemd
              mountPath: /etc/systemd
              readOnly: true
            - name: etc-kubernetes
              mountPath: /etc/kubernetes
              readOnly: true
      restartPolicy: Never
      volumes:
        - name: var-lib-kubelet
          hostPath:
            path: /var/lib/kubelet
        - name: etc-systemd
          hostPath:
            path: /etc/systemd
        - name: etc-kubernetes
          hostPath:
            path: /etc/kubernetes

Why it matters: Security posture drifts over time — new components are added, configs change, and best practices evolve. Regular automated audits make sure your cluster continues to meet hardening baselines instead of relying on one-time setups. For a full walkthrough of the benchmark itself, see our CIS Kubernetes Benchmark implementation guide.

Compliance: CIS Kubernetes Benchmark, SOC 2 (ongoing risk assessment), PCI-DSS (vulnerability management), ISO 27001 (A.12.6 — Technical vulnerability management)

Practice 50: Establish Ongoing Security & Compliance Monitoring

Implementation:

  • Define a minimal set of security SLOs/metrics for your clusters, such as:
    • Number of critical vulnerabilities open > X days
    • Number of policy violations (privileged pods, hostPath usage)
    • Mean time to detect (MTTD) and mean time to respond (MTTR) for incidents
  • Centralize:
    • Logs (audit, application, system)
    • Metrics (Prometheus, cloud monitoring)
    • Security events (Falco, IDS, scanners) into a SIEM or observability platform.
  • Create dashboards that show:
    • Current security posture for each cluster/environment.
    • Trend of vulnerabilities, misconfigurations, and policy violations.
  • Set up recurring security reviews (e.g., monthly or quarterly) to:
    • Review findings and incidents.
    • Prioritize remediation work.
    • Update policies and controls as the platform evolves.
  • Integrate alerts into your on-call / incident management process so security signals are handled like reliability incidents.

Why it matters: Security is not a one-time checklist. Without ongoing monitoring and feedback loops, even a well-hardened cluster will slowly drift into an unknown and risky state. Regular visibility and reviews keep Kubernetes security aligned with business and compliance needs.

Compliance: SOC 2 (monitoring & governance), PCI-DSS (monitoring & improvement), ISO 27001 (ISMS continual improvement), NIST CSF (Detect & Respond Functions)

Checking the 50 Without Doing It by Hand

Roughly 30 of these practices are machine-verifiable from a live cluster — which means you do not have to work through the list manually to know where you stand. In Atmosly, a one-click, on-demand security scan (built on Kubescape) evaluates your cluster against CIS v1.10.0, MITRE ATT&CK, SOC 2, and ISO 27001 frameworks and flags exactly which controls fail, on which workloads. Three things make the results actionable rather than just a report:

  • Findings resolve to a field path, not a lecture. Each failed control lists the affected Kind, name, and namespace plus the exact manifest field that fails — for example spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem should be true (Practice 14, verified for you).
  • Guided remediation, with a human in the loop. AI analysis generates the verification command and the fix, pre-loaded into an audited in-browser terminal scoped to that namespace. You review and run them — nothing is auto-applied — and a re-scan confirms the control now passes.
  • Access governance covers Practices 4, 9, and 10 structurally. RBAC roles created through Atmosly carry an expiry (30 days by default, enforced by a reaper every 2 minutes), so standing cluster-admin access — the finding behind most breach paths — cannot silently accumulate.

Everything above is configuration and compliance posture. Image CVE scanning (Practice 18) and runtime detection (Practice 46) are separate disciplines with their own tools — pair the scan with Trivy in CI and Falco at runtime for full coverage. Security scanning is available on every Atmosly plan, including the free tier.

Three-phase rollout plan for the 50 Kubernetes security best practices

Roll the checklist out in three phases — seven critical practices first, then layers.

Implementing the Checklist: Prioritized Roadmap

Phase 1: Critical (Week 1) - Practices that prevent immediate breaches

  • Practice 1: Enable RBAC
  • Practice 4: Remove cluster-admin from regular users
  • Practice 11: Enforce Pod Security Standards
  • Practice 12: Never run as root
  • Practice 21: Default deny Network Policies
  • Practice 31: Encrypt secrets at rest
  • Practice 41: Update Kubernetes (patch CVEs)

Phase 2: High Priority (Week 2-3) - Defense in depth

These practices strengthen cluster defenses beyond the basics and significantly reduce lateral movement, privilege escalation, and secret exposure risks.

Practice 13: Enforce strict container capabilities (drop all, add minimal)

Practice 14: Enforce read-only root filesystem where possible

Practice 15: Disable privilege escalation on all containers

Practice 16: Set resource limits on every container

Practice 17: Use non-root, dedicated service accounts per workload

Practice 22: Explicitly allow only required traffic

Practice 23: Always allow DNS in egress policies

Practice 24: Enforce mTLS between services with a service mesh

Practice 25: Enforce TLS for all ingress traffic

Practice 32: Adopt an external secrets manager (Vault, AWS Secrets Manager, etc.)

Practice 33: Keep all secrets out of Git (Git hygiene + scanners)

Practice 34: Automate secret rotation at defined intervals

Practice 35: Never inject secrets via environment variables

Practice 36: Use Sealed Secrets or SOPS for GitOps-safe encryption

Practice 42: Enforce admission controls (OPA Gatekeeper / Kyverno)
Prevent privileged pods, hostPath mounts, unapproved registries.

Practice 43: Disable or secure the Kubernetes Dashboard (SSO-only)

Practice 44: Apply ResourceQuotas + LimitRanges for resource boundaries

Practice 45: Use PodDisruptionBudgets for safe upgrades/rollouts

This phase creates defense-in-depth, ensuring that even if one control fails, multiple layers still protect the cluster.

Phase 3: Medium Priority (Month 1) - Hardening and compliance

These practices finalize your production-grade security posture, ensuring long-term compliance, resilience, and operational integrity.

Practice 18: Scan container images for vulnerabilities in CI/CD

Practice 19: Use minimal base images (Distroless or Alpine)

Practice 20: Implement image signing and verification

Practice 26: Isolate and protect the Kubernetes control plane

Practice 27: Enable CNI network flow logging for forensics

Practice 28: Use private registries and restrict image sources

Practice 29: Implement egress filtering and outbound firewalls

Practice 30: Monitor network traffic with IDS/NDR

Practice 37: Enable audit logging for secret access & API actions

Practice 38: Separate secrets by environment and namespace

Practice 39: Track secret versions and changes for compliance

Practice 40: Monitor secret expiration (TLS certs, API tokens, DB credentials)

Practice 46: Monitor runtime threats using Falco or eBPF sensors

Practice 47: Implement backup & disaster recovery (Velero, snapshots)

Practice 48: Harden worker nodes and underlying OS image

Practice 49: Run regular CIS + vulnerability audits (kube-bench, Trivy, Kubescape)

Practice 50: Establish ongoing security & compliance monitoring

By the end of Phase 3, your clusters reach a hardened, audit-ready state aligned with SOC 2, PCI-DSS, ISO 27001, and the CIS Kubernetes Benchmark — evidence for those frameworks is covered in depth in our SOC 2 for Kubernetes guide and ISO 27001 Annex A mapping.

Conclusion: Building Defense-in-Depth Security

Kubernetes security requires implementing controls across multiple layers — no single practice protects completely. These 50 best practices provide comprehensive defense-in-depth security posture.

Critical Priorities:

  1. Enable RBAC with least privilege
  2. Enforce Pod Security Standards (restricted for production)
  3. Never run containers as root
  4. Implement Network Policies (default deny)
  5. Encrypt secrets, use external secrets manager
  6. Scan images for vulnerabilities
  7. Keep Kubernetes patched and updated
  8. Enable comprehensive audit logging

Working through all 50 practices manually is time-consuming — and knowing where to start is half the problem. A posture scan tells you which of the machine-verifiable controls your cluster already fails, so the roadmap above starts from your real gaps instead of from zero.

Ready to see where your cluster stands? Run a free security scan with Atmosly — read-only, one click, and every finding comes with the field path that fails and the command that fixes it.

Frequently Asked Questions

What is a Kubernetes security checklist?
A Kubernetes security checklist is an ordered set of verifiable hardening controls covering access control, pod security, network policy, secrets management, and cluster operations. This guide contains 50 production-tested practices, each with implementation YAML, the reason it matters, and the compliance frameworks it addresses.
Which Kubernetes security best practices should I implement first?
Start with seven: enable RBAC, remove cluster-admin from regular users, enforce Pod Security Standards, run containers as non-root, apply default-deny NetworkPolicies, encrypt secrets at rest, and keep Kubernetes patched. These stop the most common immediate breach paths and take roughly a week to land.
What are the most common Kubernetes security mistakes?
The biggest ones are access-shaped: cluster-admin granted to regular users, service account tokens auto-mounted into every pod, no NetworkPolicies (a flat pod network), containers running as root, and secrets stored only base64-encoded in etcd. All five are Kubernetes defaults, not exotic mistakes.
Is Kubernetes secure by default?
No. Kubernetes ships with permissive defaults optimised for getting workloads running: audit logging off on managed clusters, tokens auto-mounted, no network segmentation, and no enforced pod security. Production security requires deliberately layering the controls in this checklist on top.
How do I enforce Pod Security Standards in Kubernetes?
Use Pod Security Admission namespace labels: warn=restricted alongside enforce=baseline first, read the warnings for a week, fix the workload specs, then raise enforce to restricted. The restricted profile blocks privileged containers, host namespaces, and root users.
How should I roll out Kubernetes NetworkPolicies safely?
Start with a default-deny ingress policy per namespace, then add explicit allow rules for legitimate flows, and always allow DNS egress to kube-system or nothing will resolve. Roll out namespace by namespace rather than cluster-wide in one step, watching for broken flows before moving on.
What is the best way to manage Kubernetes secrets securely?
Encrypt them at rest in etcd, source values from an external manager such as Vault or AWS Secrets Manager, keep real values out of Git (use Sealed Secrets or SOPS for GitOps), rotate on a schedule, prefer volume mounts over environment variables, and audit-log secret access.
Does this checklist cover CIS, SOC 2, and PCI-DSS requirements?
Yes, largely. The checklist is organised so each practice names the frameworks it addresses — CIS Kubernetes Benchmark, SOC 2, PCI-DSS, ISO 27001, HIPAA. Implementing it gives you the technical-control evidence those audits ask for, though organisational controls still live outside the cluster.
What is the difference between kube-bench, Kubescape, and Trivy?
kube-bench executes the CIS benchmark's node-level audit commands, Kubescape evaluates live workloads and RBAC through the API and maps findings to multiple frameworks, and Trivy focuses on image and configuration vulnerabilities. They answer different questions and mature teams run more than one.
Who is responsible for Kubernetes security on EKS, GKE, or AKS?
On managed Kubernetes the provider hardens the control plane and etcd; you own everything you can configure — audit log settings, RBAC, pod security, network policies, secrets, node groups, and workload specs. Roughly 40 of the 50 practices in this checklist remain your responsibility on EKS, GKE, or AKS.
How often should I audit my Kubernetes cluster security?
Scan on triggers as well as calendars: after cluster upgrades, after new namespaces or workloads land, and after RBAC or admission changes, with a monthly baseline scan on top. Scanning manifests in CI catches most regressions before they ever reach the cluster.
How long does it take to implement all 50 Kubernetes security best practices?
Roll it out in three phases: week one for the seven critical practices, weeks two to three for defense-in-depth controls like capabilities, egress policy, external secrets, and admission control, then month one for hardening, backups, runtime detection, and recurring audits. Attempting all 50 in one sprint typically stalls and gets rolled back.