Table of Contents
Kubernetes has become the backbone of modern infrastructure, powering everything from startup MVPs to the world’s largest financial platforms. But with great orchestration power comes an enormous attack surface. In 2026, Kubernetes security is no longer optional โ it is a core competency that every platform team must master.
This guide covers every layer of the Kubernetes security stack: from pod-level hardening and RBAC to supply chain integrity and runtime threat detection. Whether you are hardening your first production cluster or auditing a fleet of thousands, this is the reference you will return to again and again.
1. Why Kubernetes Security Matters in 2026
The 2025 Kubernetes Security Report from Red Hat found that 67% of organizations had delayed or slowed application deployment due to security concerns, and 45% experienced a security incident in their container or Kubernetes environments. The attack surface of a Kubernetes cluster is vast โ and growing.
The Kubernetes Attack Surface
A Kubernetes cluster exposes multiple layers that adversaries can target:
- API Server: The central control plane component. Misconfigured authentication or authorization lets attackers manipulate workloads, exfiltrate secrets, or pivot to underlying nodes.
- etcd: The backing datastore for all cluster state. Unencrypted etcd access means full cluster compromise โ every Secret, ConfigMap, and RBAC policy is stored here in plaintext by default.
- Kubelet: The node agent. An exposed kubelet API (port 10250) without authentication allows remote code execution on every pod running on that node.
- Container Runtime: containerd and CRI-O vulnerabilities can lead to container escape. CVE-2024-21626 (Leaky Vessels) demonstrated how a runc flaw could break container isolation entirely.
- Network Layer: By default, every pod can talk to every other pod in the cluster. Without network policies, a compromised pod in a dev namespace can reach production databases.
- Supply Chain: Container images pulled from public registries may contain malware, backdoors, or known CVEs. Without image verification, you are running untrusted code in production.
The Shared Responsibility Model
When running Kubernetes on a managed service like EKS, GKE, or AKS, the cloud provider secures the control plane โ but everything above that is your responsibility. This includes:
- Pod security configuration and admission control
- RBAC policies and service account permissions
- Network segmentation and network policies
- Secrets management and encryption
- Image scanning, signing, and provenance verification
- Runtime monitoring and incident response
- Workload identity and IAM integration
Defense in Depth
Kubernetes security follows the principle of defense in depth: no single control is sufficient. You need overlapping layers of protection so that when one fails โ and it will โ the next layer catches the threat. This guide walks through each layer systematically, from admission control to runtime detection.
2. Pod Security Standards and Admission Control
Pod Security Standards (PSS) replaced the deprecated PodSecurityPolicy in Kubernetes 1.25 and are now the built-in mechanism for enforcing pod-level security. They define three progressive profiles that control what a pod is allowed to do.
For a deeper dive into production-grade PSS configurations, see our guide on Kubernetes Pod Security Standards for Production.
The Three Profiles
- Privileged: Unrestricted. No security restrictions applied. Use only for system-level workloads like CNI plugins, log collectors, and storage drivers that genuinely require host access.
- Baseline: Prevents known privilege escalations. Blocks hostNetwork, hostPID, hostIPC, privileged containers, and most host path mounts. This is the minimum you should enforce on any namespace running application workloads.
- Restricted: Hardened profile following current pod hardening best practices. Requires running as non-root, drops ALL capabilities, enforces a read-only root filesystem, and mandates seccomp profiles. This is the target for all production workloads.
Pod Security Admission Controller
The built-in Pod Security Admission (PSA) controller enforces PSS at the namespace level using labels. It operates in three modes:
- enforce: Rejects pods that violate the policy.
- audit: Logs violations but allows the pod. Useful for rollout.
- warn: Sends a warning to the user but allows the pod.
# Namespace with Restricted PSS enforcement
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/audit-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
---
# Pod that complies with Restricted profile
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: production
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: gcr.io/my-project/app:v1.2.3@sha256:abc123...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1000
runAsGroup: 1000
capabilities:
drop:
- ALL
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
OPA Gatekeeper
Open Policy Agent (OPA) Gatekeeper extends Kubernetes admission control with custom policies written in Rego. Unlike PSA, Gatekeeper can enforce arbitrary constraints โ requiring specific labels, blocking certain image registries, mandating resource limits, or enforcing naming conventions.
Gatekeeper uses ConstraintTemplates (defining the policy logic) and Constraints (applying the template to specific resources). It supports dry-run mode for safe rollout and provides audit functionality to find existing violations.
Kyverno
Kyverno is a Kubernetes-native policy engine that uses YAML-based policies instead of Rego. For teams already fluent in Kubernetes manifests, Kyverno has a gentler learning curve. It can validate, mutate, and generate resources, making it useful for both security enforcement and operational automation.
warn mode across all namespaces first. This shows you what would fail without blocking deployments. Once your workloads comply, switch to enforce. Layer Gatekeeper or Kyverno on top for custom policies that PSA cannot express.
3. RBAC Deep Dive
Role-Based Access Control (RBAC) is the authorization backbone of Kubernetes. Every API request โ whether from a human operator, a CI pipeline, or a running pod’s service account โ is evaluated against RBAC rules. Misconfigured RBAC is one of the most common root causes of Kubernetes security incidents.
Roles vs ClusterRoles
A Role grants permissions within a single namespace. A ClusterRole grants permissions cluster-wide. Use Roles for application teams that should only operate within their namespace. Use ClusterRoles sparingly โ only for platform-level operations like node management, CRD administration, or cluster-scoped resources.
RoleBindings and ClusterRoleBindings
Bindings connect subjects (users, groups, service accounts) to roles. A RoleBinding can reference either a Role or a ClusterRole, but limits the scope to a single namespace. A ClusterRoleBinding grants permissions across all namespaces.
# Role: Allows reading pods and logs in the 'backend' namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: backend
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list"]
---
# RoleBinding: Grants pod-reader to the backend-devs group
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-devs-pod-reader
namespace: backend
subjects:
- kind: Group
name: backend-devs
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
# ServiceAccount with minimal permissions for a specific workload
apiVersion: v1
kind: ServiceAccount
metadata:
name: order-processor
namespace: backend
automountServiceAccountToken: false
Least Privilege Principles
Follow these rules to keep RBAC tight:
- Never use cluster-admin for applications. The cluster-admin ClusterRole has full access to everything. It should be bound only to break-glass emergency accounts, never to service accounts or CI pipelines.
- Scope to the narrowest verb set. If a service only reads ConfigMaps, grant
getandlistโ not*(all verbs). - Avoid wildcards. Wildcards on resources (
*) or API groups (*) grant far more than intended and grow in scope as new CRDs are installed. - Use resourceNames where possible. You can limit a Role to specific named resources, such as a single ConfigMap or Secret.
- Disable automountServiceAccountToken. Most pods do not need to talk to the Kubernetes API. Set
automountServiceAccountToken: falseat the ServiceAccount or Pod level.
Service Account Hardening
Every namespace gets a default service account, and by default, its token is mounted into every pod. This is dangerous โ a compromised pod immediately has API access. Harden service accounts by:
- Setting
automountServiceAccountToken: falseon the default service account in every namespace. - Creating dedicated service accounts for each workload with only the permissions it needs.
- Using short-lived projected service account tokens (bound tokens) instead of long-lived secrets.
- Integrating with cloud IAM via workload identity (GKE Workload Identity, EKS IRSA, AKS Workload Identity) to eliminate static credentials entirely.
Audit Logging
Enable Kubernetes audit logging to record every API request. This is essential for forensics, compliance, and detecting unauthorized access patterns. Configure the audit policy to log at the RequestResponse level for sensitive resources (secrets, RBAC, pods/exec) and at Metadata level for everything else. Ship audit logs to a centralized SIEM โ do not store them only on the control plane nodes.
4. Network Policies
By default, Kubernetes allows unrestricted network communication between all pods in a cluster. This means a compromised pod in a development namespace can reach every service in production. Network policies are the firewall rules of Kubernetes โ they define which pods can communicate with each other and with external endpoints.
Default Deny: The Essential First Step
The single most impactful network security control is a default-deny policy in every namespace. This blocks all ingress and egress traffic unless explicitly allowed. Start here, then add allow rules for legitimate traffic flows.
# Default deny all ingress and egress in a namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Allow ingress from the ingress controller to web frontends
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-to-web
namespace: production
spec:
podSelector:
matchLabels:
app: web-frontend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- protocol: TCP
port: 8080
---
# Allow egress to the database and DNS only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-egress-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web-frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Namespace Isolation
Use namespace selectors to isolate entire environments. A production namespace should only accept traffic from its own pods and from approved ingress namespaces. Development and staging namespaces should never reach production databases directly.
Calico and Cilium: Advanced Network Policy
The built-in Kubernetes NetworkPolicy API covers basic L3/L4 filtering, but advanced CNI plugins provide much more:
- Calico: Supports GlobalNetworkPolicies (cluster-wide rules), DNS-based egress policies (allow traffic only to specific FQDNs), application layer policies (L7), and integration with enterprise firewalls.
- Cilium: Uses eBPF for high-performance, identity-aware network security. Supports L7 policies (HTTP path/method filtering), DNS-aware policies, transparent encryption (WireGuard), and comprehensive network observability via Hubble.
Egress Controls
Egress is often neglected but is critical for preventing data exfiltration. A compromised pod that can reach the internet can exfiltrate secrets, download malware, or establish reverse shells. Implement strict egress rules:
- Block direct internet access from application pods.
- Route external traffic through an egress gateway or proxy.
- Use DNS-based policies (Calico or Cilium) to allow only specific external domains.
- Log all egress connections for audit and anomaly detection.
5. Secrets Management
Kubernetes Secrets are the default mechanism for storing sensitive data โ API keys, database passwords, TLS certificates, and tokens. However, they have significant limitations that make them insufficient for production security without additional tooling.
For a comprehensive treatment of this topic, see our dedicated guide: Kubernetes Secrets Management: A Security-First Guide.
Built-in Secrets Limitations
- Base64 is not encryption. Kubernetes Secrets are stored as base64-encoded strings by default. Anyone with etcd access or
get secretsRBAC permission can read them in plaintext. - etcd encryption at rest is available but must be explicitly configured with an EncryptionConfiguration. Many clusters skip this step.
- No audit trail. Native Secrets do not track who accessed them or when, making compliance and incident response difficult.
- Git workflow problems. You cannot safely commit Secret manifests to Git, breaking GitOps workflows unless you add a layer of encryption.
External Secrets Operator
The External Secrets Operator (ESO) synchronizes secrets from external providers into Kubernetes Secrets. This keeps your source of truth in a dedicated secrets management system while your workloads consume standard Kubernetes Secret objects.
# SecretStore pointing to AWS Secrets Manager
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-manager
namespace: production
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
---
# ExternalSecret that syncs a database password
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: db-credentials
creationPolicy: Owner
template:
type: Opaque
data:
DB_HOST: "{{ .host }}"
DB_USERNAME: "{{ .username }}"
DB_PASSWORD: "{{ .password }}"
data:
- secretKey: host
remoteRef:
key: production/database
property: host
- secretKey: username
remoteRef:
key: production/database
property: username
- secretKey: password
remoteRef:
key: production/database
property: password
HashiCorp Vault Integration
HashiCorp Vault provides dynamic secrets, automatic rotation, fine-grained access policies, and comprehensive audit logging. There are two primary integration patterns with Kubernetes:
- Vault Agent Injector: A mutating webhook that injects a Vault sidecar into pods. The sidecar authenticates to Vault using the pod’s Kubernetes service account, retrieves secrets, and writes them to a shared volume. No application changes required.
- Vault CSI Provider: Mounts secrets as files using the Container Storage Interface. Secrets appear as files in the pod’s filesystem, are refreshed automatically, and support rotation without pod restarts.
Sealed Secrets and SOPS
For GitOps workflows where secrets must live in Git:
- Sealed Secrets (Bitnami): Encrypts secrets using a cluster-side controller’s public key. The encrypted SealedSecret resource is safe to commit to Git. Only the controller running in the cluster can decrypt it.
- SOPS (Mozilla): Encrypts specific values within YAML files using AWS KMS, GCP KMS, Azure Key Vault, or age/PGP keys. Integrates with Flux and ArgoCD for transparent decryption during deployment.
6. Container Image Security
Container images are the primary delivery mechanism for application code into Kubernetes. A single vulnerable or malicious image can compromise your entire cluster. Image security spans the full lifecycle: building, scanning, signing, storing, and admitting images.
Image Scanning with Trivy and Grype
Trivy (by Aqua Security) is the most widely adopted open-source scanner. It detects vulnerabilities in OS packages, language-specific dependencies (npm, pip, go modules, Maven), IaC misconfigurations, and embedded secrets. Trivy integrates directly into CI pipelines:
# GitHub Actions CI step: Scan image with Trivy
name: Container Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build container image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: table
exit-code: 1
severity: CRITICAL,HIGH
ignore-unfixed: true
- name: Run Trivy for SBOM generation
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: cyclonedx
output: sbom.json
- name: Upload SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
Grype (by Anchore) is another excellent scanner focused purely on vulnerability detection. It is fast, supports the same ecosystem of package types, and produces SARIF output for integration with GitHub Advanced Security.
Admission Controllers for Image Verification
Scanning images in CI is necessary but not sufficient. You also need to enforce that only verified images are admitted into the cluster. Use admission controllers to reject any image that:
- Has not been scanned within the last 24 hours
- Contains critical or high-severity vulnerabilities
- Is not signed by a trusted key
- Was pulled from an unauthorized registry
- Uses a mutable tag like
:latestinstead of a digest
Tools like Kyverno, OPA Gatekeeper, and Sigstore’s policy-controller can enforce these rules at admission time.
Sigstore and Cosign
Sigstore provides keyless signing and verification for container images. Using cosign, you can sign images in CI and verify signatures at admission time. Keyless signing uses OIDC identity (from GitHub Actions, GitLab CI, etc.) and records signatures on a transparency log (Rekor), eliminating the need to manage signing keys.
Base Image Hardening and Distroless Images
Your base image is the foundation of your container’s security posture. Best practices include:
- Distroless images (from Google) contain only your application and its runtime dependencies โ no shell, no package manager, no utilities. This drastically reduces the attack surface. An attacker who gains code execution in a distroless container cannot spawn a shell or download additional tools.
- Chainguard Images provide hardened, FIPS-compliant base images built with apko. They are rebuilt daily, include zero known CVEs, and come with SBOMs and Sigstore signatures out of the box.
- Alpine-based images are a good middle ground โ much smaller than Debian/Ubuntu images, with musl libc and a minimal package set. Just remember to keep them updated.
- Multi-stage builds ensure that build tools, compilers, and test dependencies never appear in your production image.
@sha256:...) rather than tag. Tags are mutable โ someone can push a different image to the same tag. Digests are immutable and guarantee you are running exactly the image you tested and scanned.
7. Supply Chain Security
Software supply chain attacks have surged since the SolarWinds and Codecov incidents demonstrated how devastating they can be. In Kubernetes environments, the supply chain includes container images, Helm charts, Terraform modules, base images, CI/CD pipelines, and every dependency those artifacts pull in.
We cover this topic in depth in our dedicated article: Securing Kubernetes Supply Chains with SBOM & Sigstore.
SBOM Generation
A Software Bill of Materials (SBOM) is an inventory of every component inside your container image โ OS packages, language libraries, transitive dependencies, and their versions. SBOMs are essential for:
- Vulnerability response: When a new CVE drops (like Log4Shell), an SBOM lets you instantly identify which images contain the affected library, across your entire fleet.
- License compliance: Track open-source license obligations across all deployed software.
- Regulatory requirements: Executive Order 14028 and the EU Cyber Resilience Act mandate SBOM generation for software sold to government agencies.
Generate SBOMs in SPDX or CycloneDX format using Trivy, Syft (by Anchore), or docker buildx with the SBOM attestation flag. Attach SBOMs to images as OCI artifacts and store them alongside the image in your registry.
SLSA Framework
Supply-chain Levels for Software Artifacts (SLSA, pronounced “salsa”) is a security framework from Google that provides a checklist of standards and controls to prevent tampering and improve integrity. SLSA defines four levels:
- SLSA Level 1: Documentation of the build process. Automated build with provenance metadata.
- SLSA Level 2: Tamper-resistant provenance generated by a hosted build service. Version control and basic integrity guarantees.
- SLSA Level 3: Hardened build platform with isolation between builds. Provenance is non-falsifiable.
- SLSA Level 4: Two-person review of all changes. Hermetic, reproducible builds.
GitHub Actions natively supports SLSA Level 3 provenance generation via the slsa-github-generator project. This creates a signed provenance attestation that proves which repository, branch, commit, and workflow produced a given artifact.
In-Toto Attestations
In-toto is a framework for securing the entire software supply chain by defining a layout of expected steps (source โ build โ test โ package โ deploy) and verifying that each step was performed by an authorized party. Each step produces a signed attestation (a link) that records inputs, outputs, and who performed the step. Kubernetes admission controllers can verify the full chain of attestations before admitting an image.
Sigstore Policy Enforcement
Sigstore’s policy-controller is a Kubernetes admission controller that verifies Sigstore signatures, attestations, and SBOM data before allowing images to run. You can define policies that require:
- A valid cosign signature from a specific OIDC identity
- A SLSA provenance attestation from a trusted builder
- An SBOM attestation with no critical CVEs
- A specific minimum SLSA level
8. Runtime Security and Monitoring
Prevention is essential, but detection is equally important. No matter how well you harden your cluster, determined attackers will find a way in. Runtime security tools monitor system calls, network connections, file access, and process execution inside containers to detect and respond to threats in real time.
Falco
Falco (CNCF incubating project) is the de facto standard for Kubernetes runtime security. It uses a rules engine to detect suspicious behavior by monitoring Linux system calls via kernel modules or eBPF probes. Out-of-the-box rules detect:
- Shell spawned inside a container
- Sensitive file read (e.g.,
/etc/shadow,/etc/kubernetes/pki) - Unexpected outbound network connection
- Privilege escalation attempts
- Container escape attempts (mount namespace changes, ptrace)
- Crypto mining processes (known miner binary names, stratum protocol connections)
Falco ships alerts to Slack, PagerDuty, Elasticsearch, or any webhook endpoint. Combine with Falcosidekick for rich alerting integrations and response automation.
Tetragon
Cilium Tetragon is a next-generation runtime enforcement tool built on eBPF. Unlike Falco, which primarily detects and alerts, Tetragon can also enforce โ killing processes or blocking network connections in real time at the kernel level, with near-zero overhead.
Tetragon’s TracingPolicy CRD lets you define security policies that monitor specific system calls, file accesses, or network operations. For example, you can create a policy that terminates any process that opens /etc/shadow inside a container, or blocks any outbound connection to a known C2 server IP range.
eBPF-Based Monitoring
eBPF (Extended Berkeley Packet Filter) has revolutionized Kubernetes observability and security. Running sandboxed programs in the Linux kernel, eBPF provides deep visibility without modifying application code or container images. Key eBPF-based tools include:
- Cilium Hubble: Network observability โ service maps, DNS query logs, HTTP request/response visibility, network flow logs.
- Pixie (CNCF): Auto-instrumented application performance monitoring โ captures HTTP, gRPC, SQL, and DNS traffic without sidecars.
- Inspektor Gadget: A collection of eBPF-based debugging and inspection tools for Kubernetes. Trace DNS queries, TCP connections, file access, signal delivery, and more at the pod level.
Kubernetes Audit Logs
Audit logs record every request to the Kubernetes API server. They are essential for forensics, compliance (SOC 2, PCI-DSS, HIPAA), and detecting malicious activity. Key events to monitor include:
- Secrets access (who read which secret, when)
- RBAC changes (new ClusterRoleBindings, permission escalation)
- Pod exec sessions (interactive shell access to running containers)
- Namespace creation and deletion
- ServiceAccount token requests
Anomaly Detection
Static rules catch known threats. For unknown threats, use anomaly detection to baseline normal behavior and alert on deviations. Tools like Kubescape, ARMO, and various SIEM platforms can profile normal network flows, process trees, and API access patterns per workload, then flag unusual activity โ a container that suddenly makes DNS queries to never-before-seen domains, or a service account that starts accessing secrets it has never touched before.
9. GitOps Security Patterns
GitOps โ using Git as the single source of truth for declarative infrastructure โ has become the dominant deployment model for Kubernetes. But GitOps introduces its own security considerations. The Git repository becomes a high-value target, and the GitOps operator (ArgoCD or Flux) has significant cluster permissions.
For in-depth coverage, see our guides on GitOps Security Patterns for Kubernetes and Scaling GitOps Securely: Kubernetes Best Practices.
ArgoCD Security
ArgoCD is the most popular GitOps operator. Harden it by:
- Enabling SSO with OIDC: Integrate with your identity provider (Okta, Azure AD, Dex) for centralized authentication. Disable local admin accounts after initial setup.
- Implementing RBAC policies: ArgoCD has its own RBAC system. Restrict which teams can sync which applications. Use AppProjects to scope permissions by repository, namespace, and cluster.
- Using ApplicationSets carefully: ApplicationSets auto-generate Applications from templates. Ensure the generators cannot be manipulated to create applications in unauthorized namespaces.
- Enabling resource hooks and sync windows: Prevent deployments during maintenance windows and require approval for production syncs.
- Restricting repository access: Use deploy keys with read-only access. Never give ArgoCD write access to your Git repositories.
Flux Security
Flux (CNCF graduated) takes a more decentralized approach with separate controllers for source, kustomize, helm, and notification. Security best practices include:
- Multi-tenancy with service accounts: Each Kustomization can impersonate a specific ServiceAccount, enabling fine-grained RBAC per tenant or team.
- Source verification: Flux supports GPG signature verification on Git commits and OCI artifact verification with cosign.
- Decryption at deploy time: Native SOPS integration decrypts secrets only during reconciliation, keeping encrypted values in Git.
Git Signing
Require GPG or SSH signing on all commits to GitOps repositories. This ensures that every change to your infrastructure can be traced to a verified author. Configure branch protection rules to reject unsigned commits. GitHub, GitLab, and Gitea all support commit signature verification.
Drift Detection
Drift โ when the live cluster state diverges from the desired state in Git โ is a security concern. Someone may have used kubectl to make manual changes that bypass your GitOps pipeline (and therefore bypass code review, policy checks, and audit trails). Both ArgoCD and Flux detect drift automatically. Configure alerts for any drift events and investigate them promptly โ they may indicate unauthorized manual access.
10. Security Checklist for Production Clusters
Use this checklist to audit your Kubernetes cluster security posture. Each item represents a concrete, actionable control.
Cluster Infrastructure
- โ API server is not publicly accessible (private endpoint or IP allowlist)
- โ etcd is encrypted at rest with a KMS provider
- โ etcd access is restricted to the API server only (mutual TLS, firewall rules)
- โ Kubelet authentication is enabled (no anonymous auth)
- โ Kubelet authorization uses Webhook mode (not AlwaysAllow)
- โ Node OS is hardened and auto-patched (Bottlerocket, Flatcar, or hardened Ubuntu)
- โ Control plane components run with minimal permissions
- โ Kubernetes version is within the supported window (N-2)
Identity and Access
- โ RBAC is enabled (should be default on all modern clusters)
- โ No ClusterRoleBindings to cluster-admin for service accounts or user groups
- โ Default service account tokens are not automounted
- โ Each workload has a dedicated service account with minimal permissions
- โ Cloud IAM integration via Workload Identity (GKE, EKS IRSA, AKS)
- โ Human access uses SSO/OIDC, not static kubeconfig tokens
- โ Audit logging is enabled and shipped to a centralized SIEM
Workload Security
- โ Pod Security Standards enforced at Restricted level on all app namespaces
- โ All containers run as non-root with read-only root filesystem
- โ All containers drop ALL capabilities
- โ Resource requests and limits set on all containers
- โ Seccomp profiles applied (RuntimeDefault at minimum)
- โ No privileged containers outside of system namespaces
Network Security
- โ Default-deny NetworkPolicy in every namespace
- โ Ingress restricted to approved sources only
- โ Egress restricted โ no unrestricted internet access from pods
- โ CNI plugin supports and enforces NetworkPolicies
- โ Service mesh or mTLS for inter-service encryption (Istio, Linkerd, Cilium)
Secrets and Data
- โ Secrets encrypted at rest in etcd
- โ External secrets management (Vault, AWS Secrets Manager, etc.)
- โ No plaintext secrets in Git repositories
- โ Secret rotation automated with short TTLs
- โ TLS termination at the ingress controller with valid certificates
Supply Chain
- โ All images scanned for vulnerabilities in CI
- โ Images signed with cosign or Notary
- โ Admission controller rejects unsigned or vulnerable images
- โ Images referenced by digest, not mutable tags
- โ SBOMs generated and attached to all production images
- โ Base images hardened (distroless, Chainguard, or minimal Alpine)
Monitoring and Response
- โ Runtime security monitoring deployed (Falco, Tetragon)
- โ Alerts configured for suspicious behavior (shell in container, privilege escalation)
- โ Kubernetes audit logs monitored and alerted on
- โ Incident response runbook exists for container compromise scenarios
- โ Regular cluster security audits (Kubescape, kube-bench, Polaris)
- โ Drift detection enabled in GitOps operator
Related Guides
Level Up Your Kubernetes Security
Get weekly security guides, vulnerability alerts, and best practices for production Kubernetes clusters.