Skip to main content

Kubernetes Security Best Practices Cheat Sheet

This guide is based on the OWASP’s page OWASP Kubernetes Top Ten Vulnerabilities.

It aims to sum up the best practices for security management. For more information / details, you can check the following links:

Insecure Workload Configuration

Don’t run as root

apiVersion: v1
kind: Pod
metadata:
name: root-user
spec:
containers:
...
securityContext:
#root user:
runAsUser: 0
#non-root user:
runAsUser: 5554

Set filesystems as read-only

apiVersion: v1
kind: Pod
metadata:
name: read-only-fs
spec:
containers:

securityContext:
#read-only fs explicitly defined
readOnlyRootFilesystem: true

Disallow privileged containers

apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
...
securityContext:
#priviliged
privileged: true
#non-privileged
privileged: false

Supply Chain Vulnerabilities

Image Integrity

When systems of record do not exist regarding the contents of a container image it is possible that an unexpected container may run in a cluster. Use Software Bill of Materials (SBOM) and image signing.

Image Composition

Use minimal OS package and dependencies. Run a vulnerability scanner on the images.

Overly Permissive Role-Based Access Control (RBAC)

  • Reduce direct cluster access by end users when possible
  • Don’t use Service Account Tokens outside of the cluster
  • Avoid automatically mounting the default service account token
  • Audit RBAC included with installed third-party components
  • Deploy centralized polices to detect and block risky RBAC permissions
  • Utilize RoleBindings to limit scope of permissions to particular namespaces vs. cluster-wide RBAC policies

Policy Enforcement

Reject workload that

  • haven’t been scanned for vulnerabilities
  • use a base image that’s not explicitly allowed
  • don’t include an approved SBOM
  • originated from untrusted registries
  • … and any other policy that apply governance, compliance, and security requirements
# Allowed repos
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
name: allowed-repos
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "sbx"
- "prd"
parameters:
repos:
- "open-policy-agent"
- "ubuntu"

Inadequate Logging

Kubernetes Audit Logs

Records actions taken by the API (anomalous or unwanted API calls, especially any authorization failures)

Kubernetes Events

Kubernetes resource state changes and errors, such as exceeded resource quota or pending pods, as well as any informational messages

Application & Container Logs

Applications running inside of Kubernetes (easiest method for capturing these logs is to ensure the output is written to standard output stdout and standard error stderr streams)

Operating System Logs

Logs from programs such as systemd

Cloud Provider Logs

Check with the provider what logs can be provided

Network Logs

If working with traditional proxy or ingress components such as nginx or apache, use the standard out stdout and standard error stderr pattern

Monitoring

The monitoring must be robust and should not only capture relevant security events, but also be centralized in a way that is queryable, long term, and maintains integrity.

Broken Authentication

  • Avoid using certificates for end user authentication (the API has no way to revoke certificates)
  • Do not code your own authentication system
  • Enforce MFA when possible
  • Don’t use Service Account tokens from outside of the cluster
  • Authenticate users and external services using short-lived tokens

Network Segmentation

The Kubernetes networking is flat by default

Native Controls (Multi-Cluster)

One way to truly enforce network isolation within Kubernetes is to utilize separate clusters when appropriate. This adds complexity when working with tightly coupled microservices but is a viable option when separating different tenants based on risk.

Native Controls (NetworkPolicies)

Network policies are built into Kubernetes itself and behave like firewall rules. They control how pods communicate. Without network policies, any pod can talk to any other pod. Network Policies should be defined as to limit pod communication to only defined assets while denying everything that isn’t explicitly configured.

# network policy prevents backend egress between pods running the “default” namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-backend-egress
namespace: default

spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
tier: backend

Service Mesh

There are a number of different service mesh projects available for different use cases including Istio, Linkerd, and Hashicorp Consul

CNI Plugins

Container Network Interface (CNI) is an open source specification that is used to configure access to networking resources. CNI is a software-defined mechanism for allowing or disallowing network access within Kubernetes and has a wide variety of supported plugins. When choosing a CNI, it is most important to understand the feature-set that you are seeking from a security perspective and the resource overhead and maintenance related to using the plugin.

Secrets Management

  • Encrypt secrets at rest (encrypt etcd, encrypt backup, consider full disk encryption if possible)
  • Address Security Misconfigurations (least privilege for users)
  • Ensure Logging and Auditing is in place

Misconfigured Cluster Components

Examples

--anonymous-auth=false --authorization-mode=Webhook

  • Regular CIS Benchmark scans and audits focused on component misconfigurations
  • Strong culture of Infrastructure-as-Code can also help

Vulnerable Components

  • Set up a vulnerability scanner for all the components of Kubernetes
  • Minimize the use of third party components, if possible