Secure your clusters with RBAC, network policies, and security best practices.
Learn defense-in-depth strategies for production Kubernetes environments.
👤 Role-Based Access Control (RBAC)
Control who can access what resources in your Kubernetes cluster using fine-grained permissions.
Subjects
Users, Groups, or ServiceAccounts that need access
Roles/ClusterRoles
Define what actions can be performed on which resources
Bindings
Link subjects to roles, granting the defined permissions
Control traffic flow at the IP address or port level using Kubernetes NetworkPolicies.
⚠️ Important: Network policies require a CNI plugin that supports them (Calico, Cilium, Weave Net). They won't work with basic networking like kubenet.
Default Deny All Traffic
YAML
# Deny all ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {} # Apply to all pods in namespace
policyTypes:
- Ingress
---
# Deny all egress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress: [] # No allowed egress rules
Allow Specific Traffic
YAML
# Allow frontend to backend communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-netpol
namespace: production
spec:
podSelector:
matchLabels:
app: backend
tier: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
# Allow from frontend pods
- podSelector:
matchLabels:
app: frontend
# Allow from specific namespace
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
# Allow from specific IP ranges
- ipBlock:
cidr: 10.0.0.0/8
except:
- 10.0.1.0/24
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8443
egress:
# Allow DNS
- to:
- namespaceSelector:
matchLabels:
name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# Allow to database
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
# Falco rules for runtime security
- rule: Terminal shell in container
desc: A shell was used as the entrypoint/exec
condition: >
spawned_process and container
and shell_procs and proc.name in (shell_binaries)
and not container.image.repository in (allowed_images)
output: >
Shell opened in container (user=%user.name container_id=%container.id
container_name=%container.name image=%container.image.repository:%container.image.tag
shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
priority: WARNING
tags: [container, shell]
- rule: Write below etc
desc: an attempt to write to any file below /etc
condition: >
write and etc_dir and not shadowutils_binaries
and not (container and proc.name in (known_binaries))
output: >
File below /etc opened for writing (user=%user.name command=%proc.cmdline
file=%fd.name container_id=%container.id image=%container.image.repository)
priority: ERROR
tags: [filesystem, mitre_persistence]
- rule: Outbound Connection to C2 Servers
desc: Detect outbound connection to command & control servers
condition: >
outbound and not (fd.sip in (allowed_outbound_ips))
and fd.sport >= 30000
output: >
Outbound connection to unknown server (command=%proc.cmdline
connection=%fd.name container_id=%container.id)
priority: WARNING
tags: [network]
Kubernetes Manifest Scanning
Bash
# Scan Kubernetes manifests with Kubesec
kubesec scan deployment.yaml
# Scan with Polaris
polaris audit --audit-path ./manifests/
# Scan with Checkov
checkov -f deployment.yaml --framework kubernetes
# Scan with KubeLinter
kube-linter lint manifests/
Security Scanning Tools:
Trivy: Comprehensive vulnerability scanner
Falco: Runtime security monitoring
KubeLinter: Static analysis of Kubernetes YAML
Kubesec: Security risk analysis for manifests
Polaris: Best practices validation
OPA Gatekeeper: Policy enforcement
📝 Audit Logging
Track and monitor all API server activities for security and compliance.
Audit Policy Configuration
YAML
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Don't log requests to these paths
- level: None
nonResourceURLs:
- /healthz*
- /metrics
- /swagger*
# Log metadata for all requests in RequestReceived stage
- level: Metadata
omitStages:
- RequestReceived
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
resources: ["pods", "pods/status"]
namespaces: ["production", "staging"]
# Log secret and configmap access
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
# Log full request/response for sensitive operations
- level: RequestResponse
verbs: ["delete", "deletecollection"]
# Log authentication failures
- level: Metadata
users: ["system:anonymous"]
verbs: ["get", "list", "watch"]
# Log everything from specific users
- level: RequestResponse
users: ["admin@example.com"]
# Detailed logging for RBAC changes
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
# Default level for everything else
- level: Metadata