kubectl Security Commands Cheatsheet
Quick reference for all security-related kubectl commands you will need during the CKS exam. Commands are organized by category for rapid lookup.
Alias Reminder
Always set up your alias first: alias k=kubectl
All examples below use k instead of kubectl.
RBAC Investigation
Checking Permissions
bash
# Check if a user/SA can perform an action
k auth can-i create deployments --as=system:serviceaccount:dev:mysa -n dev
# Check all permissions for a ServiceAccount
k auth can-i --list --as=system:serviceaccount:dev:mysa -n dev
# Check permissions for a user
k auth can-i --list --as=john -n production
# Check if current user can do something
k auth can-i delete pods -n kube-systemViewing RBAC Resources
bash
# List all roles and clusterroles
k get roles -A
k get clusterroles
# List all bindings
k get rolebindings -A
k get clusterrolebindings
# Describe a specific role (see verbs and resources)
k describe role <role-name> -n <namespace>
k describe clusterrole <clusterrole-name>
# Describe a binding (see subjects and roleRef)
k describe rolebinding <binding-name> -n <namespace>
k describe clusterrolebinding <binding-name>Finding Dangerous RBAC
bash
# Find all ClusterRoleBindings to cluster-admin
k get clusterrolebindings -o json | jq -r '
.items[] | select(.roleRef.name=="cluster-admin") |
.metadata.name'
# Find roles with wildcard permissions
k get clusterroles -o json | jq -r '
.items[] | select(.rules[]?.resources[]? == "*") |
.metadata.name'
# Find roles with secrets access
k get clusterroles -o json | jq -r '
.items[] | select(.rules[]?.resources[]? == "secrets") |
.metadata.name'
# Find roles that can exec into pods
k get clusterroles -o json | jq -r '
.items[] | select(.rules[]?.resources[]? == "pods/exec") |
.metadata.name'Creating RBAC Resources
bash
# Create a role (imperative)
k create role pod-reader \
--verb=get,list,watch \
--resource=pods \
-n dev
# Create a clusterrole
k create clusterrole secret-reader \
--verb=get,list \
--resource=secrets
# Create a rolebinding
k create rolebinding pod-reader-binding \
--role=pod-reader \
--serviceaccount=dev:mysa \
-n dev
# Create a clusterrolebinding
k create clusterrolebinding secret-reader-binding \
--clusterrole=secret-reader \
--serviceaccount=dev:mysa
# Bind to a user
k create rolebinding admin-binding \
--clusterrole=admin \
--user=john \
-n devServiceAccount Commands
bash
# Create a ServiceAccount
k create serviceaccount mysa -n dev
# Create a time-bound token (1 hour)
k create token mysa -n dev --duration=1h
# Patch SA to disable automount
k patch sa default -n dev \
-p '{"automountServiceAccountToken": false}'
# Set SA on a deployment
k set serviceaccount deployment/myapp mysa -n dev
# Check which SA a pod uses
k get pod <pod> -n <ns> -o jsonpath='{.spec.serviceAccountName}'
# Check if token is mounted
k get pod <pod> -n <ns> -o jsonpath='{.spec.volumes[?(@.name=="kube-api-access-*")]}'Secret Management
bash
# Create a secret
k create secret generic db-creds \
--from-literal=username=admin \
--from-literal=password='S3cur3!' \
-n finance
# Create TLS secret
k create secret tls my-tls \
--cert=tls.crt \
--key=tls.key \
-n web
# View secret (base64 encoded)
k get secret db-creds -n finance -o yaml
# Decode a secret value
k get secret db-creds -n finance \
-o jsonpath='{.data.password}' | base64 -d
# List all secrets in all namespaces
k get secrets -A
# Check if secrets are encrypted at rest
# (must SSH to control plane)
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep encryption-provider-configNetwork Policy Commands
bash
# List network policies
k get networkpolicies -A
k get netpol -A # short form
# Describe a network policy
k describe netpol <name> -n <namespace>
# Create a default deny ingress (imperative is not supported -- use YAML)
cat <<EOF | k apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: NAMESPACE
spec:
podSelector: {}
policyTypes:
- Ingress
EOF
# Test network connectivity between pods
k exec <pod> -n <ns> -- wget -qO- --timeout=2 http://<target-ip>:<port>
k exec <pod> -n <ns> -- nc -zv <target-ip> <port> -w 2
k exec <pod> -n <ns> -- curl -s --connect-timeout 2 http://<target-ip>:<port>
# Check which policies affect a pod
k get netpol -n <ns> -o json | jq -r '
.items[] | select(.spec.podSelector.matchLabels | to_entries |
all(.key as $k | .value as $v | true)) | .metadata.name'Pod Security Investigation
bash
# Check pod security context
k get pod <pod> -n <ns> -o jsonpath='{.spec.securityContext}'
k get pod <pod> -n <ns> -o jsonpath='{.spec.containers[0].securityContext}'
# Check if pod is running as root
k get pod <pod> -n <ns> -o jsonpath='{.spec.containers[0].securityContext.runAsUser}'
# Check capabilities
k get pod <pod> -n <ns> -o jsonpath='{.spec.containers[0].securityContext.capabilities}'
# Find all privileged pods
k get pods -A -o json | jq -r '
.items[] |
select(.spec.containers[].securityContext.privileged == true) |
"\(.metadata.namespace)/\(.metadata.name)"'
# Find pods without readOnlyRootFilesystem
k get pods -A -o json | jq -r '
.items[] |
.metadata.namespace as $ns | .metadata.name as $pod |
.spec.containers[] |
select(.securityContext.readOnlyRootFilesystem != true) |
"\($ns)/\($pod)/\(.name)"'
# Find pods running as root (UID 0)
k get pods -A -o json | jq -r '
.items[] |
select(.spec.containers[].securityContext.runAsUser == 0 or
.spec.securityContext.runAsUser == 0) |
"\(.metadata.namespace)/\(.metadata.name)"'
# Check Pod Security Admission labels on a namespace
k get ns <namespace> --show-labels | grep pod-security
k get ns <namespace> -o jsonpath='{.metadata.labels}' | jq .Pod Security Admission Labels
bash
# Apply Pod Security Standard labels
k label ns <namespace> \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/warn-version=latest \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/audit-version=latest
# Dry-run to check which pods would be rejected
k label --dry-run=server --overwrite ns <namespace> \
pod-security.kubernetes.io/enforce=restrictedCertificate Commands
bash
# Check certificate expiration (kubeadm clusters)
sudo kubeadm certs check-expiration
# Renew all certificates
sudo kubeadm certs renew all
# Renew a specific certificate
sudo kubeadm certs renew apiserver
# Inspect a certificate with openssl
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text
# Check certificate expiry date
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -enddate
# Check certificate SANs
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | \
grep -A1 "Subject Alternative Name"
# Check certificate issuer
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -issuer
# Verify certificate against CA
openssl verify -CAfile /etc/kubernetes/pki/ca.crt \
/etc/kubernetes/pki/apiserver.crt
# Check etcd certificates
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -enddateImage and Container Investigation
bash
# Check what image a pod is using
k get pod <pod> -n <ns> -o jsonpath='{.spec.containers[*].image}'
# Check all images in a namespace
k get pods -n <ns> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
# Check all images cluster-wide
k get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
# Update an image
k set image deployment/<name> <container>=<new-image> -n <ns>
# Check container runtime on a node
k get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'Audit and Logging
bash
# Check if audit logging is enabled
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep audit
# View audit logs
tail -f /var/log/kubernetes/audit/audit.log | jq .
# Filter audit logs for secrets access
cat /var/log/kubernetes/audit/audit.log | \
jq 'select(.objectRef.resource == "secrets")'
# Filter for specific user
cat /var/log/kubernetes/audit/audit.log | \
jq 'select(.user.username == "john")'
# Filter for specific verb
cat /var/log/kubernetes/audit/audit.log | \
jq 'select(.verb == "delete")'
# Count events by user
cat /var/log/kubernetes/audit/audit.log | \
jq -r '.user.username' | sort | uniq -c | sort -rnQuick Debugging
bash
# Check pod events
k describe pod <pod> -n <ns> | tail -20
# Check pod logs
k logs <pod> -n <ns>
k logs <pod> -n <ns> -c <container> # specific container
k logs <pod> -n <ns> --previous # previous instance
# Check node conditions
k describe node <node> | grep -A5 Conditions
# Check API server status (on control plane)
crictl ps | grep kube-apiserver
crictl logs <container-id> 2>&1 | tail -20
# Check static pod manifests
ls /etc/kubernetes/manifests/
# Dry-run to validate YAML
k apply -f manifest.yaml --dry-run=server
k apply -f manifest.yaml --dry-run=client
# Generate YAML without applying
k run test --image=nginx $do > pod.yaml
k create deployment test --image=nginx $do > deploy.yamlQuick Reference Table
| Task | Command |
|---|---|
| Switch context | k config use-context <name> |
| Current context | k config current-context |
| Check permission | k auth can-i <verb> <resource> --as=<user> -n <ns> |
| Create SA | k create sa <name> -n <ns> |
| Create SA token | k create token <sa> -n <ns> --duration=1h |
| Create role | k create role <name> --verb=get --resource=pods -n <ns> |
| Create binding | k create rolebinding <name> --role=<role> --sa=<ns>:<sa> -n <ns> |
| Create secret | k create secret generic <name> --from-literal=key=val -n <ns> |
| Decode secret | k get secret <name> -n <ns> -o jsonpath='{.data.key}' | base64 -d |
| Get pod image | k get pod <pod> -n <ns> -o jsonpath='{.spec.containers[0].image}' |
| Update image | k set image deploy/<name> <container>=<image> -n <ns> |
| Dry-run YAML | k run <name> --image=<img> --dry-run=client -o yaml |
| Force delete | k delete pod <name> -n <ns> --force --grace-period=0 |
| Label namespace | k label ns <ns> key=value |