Kubernetes Security Best Practices
Kubernetes Security Best Practices
Kubernetes security fails in layers, and it fails in predictable ways: over-permissioned service accounts, flat networks, secrets in plaintext, and images pulled from anywhere. This guide covers the defensive layers in the order attackers exploit them, with concrete YAML for each.
Layer 1: Authentication and Authorization (RBAC)
The default cluster-admin service account is the most common security hole. Grant the least privilege per workload:
# rbac.yaml — a service account that can only read its own namespace
apiVersion: v1
kind: ServiceAccount
metadata:
name: payments-sa
namespace: payments
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: payments-reader
namespace: payments
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: payments-reader-binding
namespace: payments
subjects:
- kind: ServiceAccount
name: payments-sa
namespace: payments
roleRef:
kind: Role
name: payments-reader
apiGroup: rbac.authorization.k8s.io
Rules:
- Never use
cluster-adminfor workloads. It is for cluster operators only. - Use Roles (namespace-scoped) over ClusterRoles unless the workload genuinely needs cluster scope.
- Audit bindings regularly:
kubectl get rolebindings -Aand review who can do what. - Disable the default service account for pods that do not need API access:
spec:
automountServiceAccountToken: false
Layer 2: Network Policies
By default, Kubernetes networks are flat: any pod can talk to any pod. Network policies are the firewall:
# networkpolicy.yaml — payments can only talk to the database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payments-allow-db
namespace: payments
spec:
podSelector:
matchLabels:
app: payments
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
app: api-gateway
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
Rules:
- Default-deny is the only safe default: create a policy that denies all traffic, then add allow rules.
- The CNI must support policies: Calico, Cilium, or Weave. Flannel does not enforce them.
- Block egress to the internet for workloads that do not need it.
Layer 3: Pod Security
Pod Security Standards (replacing PodSecurityPolicies) enforce three levels: privileged, baseline, restricted.
# pod-security.yaml — enforce restricted in the payments namespace
apiVersion: v1
kind: Namespace
metadata:
name: payments
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
A restricted pod must run as non-root, drop all capabilities, and avoid privileged features:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
Layer 4: Secrets Management
Secrets in kind: Secret are base64, not encrypted. Treat them as plaintext:
- Use an external secrets manager: Vault, AWS Secrets Manager, or GCP Secret Manager, synced via the External Secrets Operator or CSI driver.
- Enable encryption at rest for etcd:
--encryption-provider-configwith a KMS provider. - Never commit secrets to git: scan with tools like gitleaks in CI.
- Rotate automatically: external secrets with short TTLs rotate without redeploys.
# ExternalSecret — pull from AWS Secrets Manager
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: payments-db
namespace: payments
spec:
secretStoreRef:
name: aws-secrets
kind: SecretStore
target:
name: payments-db-secret
data:
- secretKey: password
remoteRef:
key: payments/prod/db
property: password
Layer 5: Supply Chain Security
The images you run are the code you deploy. Secure the pipeline:
- Use signed images: cosign sign and verify with policy controllers (Kyverno, OPA Gatekeeper).
- Pin image digests, not tags:
image: myapp@sha256:abc123...prevents tag mutation. - Scan images in CI: Trivy, Grype, or Snyk before they reach the registry.
- Restrict registries: an admission policy that only allows images from your registry.
# Kyverno policy — only allow images from the trusted registry
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-trusted-registry
spec:
validationFailureAction: Enforce
rules:
- name: check-registry
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "Images must come from registry.acme.io"
pattern:
spec:
containers:
- image: "registry.acme.io/*"
Layer 6: Admission Control and Policy
Admission controllers are the last gate before anything runs. Use policy engines to enforce your security rules:
- Kyverno: Kubernetes-native policies, easy to write.
- OPA Gatekeeper: Rego policies, more powerful, steeper learning curve.
- ValidatingAdmissionPolicies: built-in, no extra components.
Enforce: no privileged containers, no hostPath mounts, no latest tags, no cluster-admin bindings.
Layer 7: Runtime Security
Defense in depth at runtime:
- Falco: detects anomalous behavior (shell in a container, unexpected file access).
- Seccomp/AppArmor: restrict syscalls per workload.
- Read-only root filesystems: prevents writes to the container layer.
- Resource limits: a runaway container cannot starve the node.
The Audit Checklist
Run this against every cluster:
- No workload uses cluster-admin
- Default service accounts disabled where unused
- Network policies default-deny in place
- Pod Security restricted enforced
- Secrets externalized, etcd encrypted
- Images signed, digests pinned, scanned in CI
- Admission policies enforce registry and security rules
- Runtime monitoring (Falco) active
- RBAC bindings audited regularly
- kube-bench run against the control plane
Implementation Checklist
- Start with RBAC least privilege
- Add default-deny network policies
- Enforce restricted pod security
- Move secrets to an external manager
- Sign, pin, and scan images
- Add admission policies
- Deploy runtime monitoring
- Run kube-bench and fix findings
MatterAI builds frontier AI infrastructure for engineering teams — from inference-optimized models to autonomous coding agents and agentic code reviews.
Explore what we're building:
- Orbital IDE — Autonomous AI coding agent with background agents and deep codebase memory
- AI Code Reviews — Agentic pre-commit reviews across GitHub, GitLab, and Bitbucket
- Axon Models — Frontier-grade reasoning models at 70% lower inference cost
Share this Guide:
More Guides
Local LLMs in Your IDE: Connecting Ollama to Coding Agents and Autocomplete
Wire local models into VS Code, JetBrains, Cline, Continue, and Aider via the OpenAI-compatible API. Covers model routing, context budgets, tool calling with small models, and when a local model is the right choice for the job.
15 min readBuilding a Self-Hosted AI Stack: Ollama, Open WebUI, and Local RAG
Stand up a fully self-hosted AI stack on a single machine: Ollama for inference, Open WebUI as the chat interface, local embeddings for RAG, and a reverse proxy for secure access. No cloud dependency, no data leaving your network.
17 min readTop 5 Open-Source Coding Models to Run on Your Mac (2026)
The best local coding models for Apple Silicon in 2026, ranked by quality per gigabyte of unified memory. Covers qwen3-coder, devstral, gpt-oss, and more with real pull tags, sizes, and context windows.
14 min readRunning LLMs Locally: GGUF, Quantization, and Memory Planning
Learn the GGUF format, the quantization ladder from Q2 to FP16, and the exact memory math for running models on Apple Silicon and NVIDIA GPUs. Includes Ollama and llama.cpp tuning for KV cache and context.
15 min readOllama vs vLLM vs llama.cpp: Choosing the Right Local LLM Runtime
Compare the three dominant local LLM runtimes on architecture, throughput, hardware, and deployment context. Includes benchmark data, a decision framework, and a migration path from Ollama to vLLM.
16 min readContinue Reading
Local LLMs in Your IDE: Connecting Ollama to Coding Agents and Autocomplete
Wire local models into VS Code, JetBrains, Cline, Continue, and Aider via the OpenAI-compatible API. Covers model routing, context budgets, tool calling with small models, and when a local model is the right choice for the job.
15 min readBuilding a Self-Hosted AI Stack: Ollama, Open WebUI, and Local RAG
Stand up a fully self-hosted AI stack on a single machine: Ollama for inference, Open WebUI as the chat interface, local embeddings for RAG, and a reverse proxy for secure access. No cloud dependency, no data leaving your network.
17 min readTop 5 Open-Source Coding Models to Run on Your Mac (2026)
The best local coding models for Apple Silicon in 2026, ranked by quality per gigabyte of unified memory. Covers qwen3-coder, devstral, gpt-oss, and more with real pull tags, sizes, and context windows.
14 min readShip Faster. Ship Safer.
Join thousands of engineering teams using MatterAI to autonomously build, review, and deploy code with enterprise-grade precision.
