CKS — Security Tools Overview

9 minute read

Why Security Tools Matter for CKS

The CKS exam tests your ability to use real security tools on live clusters. Unlike CKA, which relies almost entirely on kubectl, CKS requires you to run scanners, write detection rules, and apply mandatory access control profiles.

This page provides a high-level overview of each tool. Detailed hands-on usage is covered in dedicated chapters later in the tutorial.

kube-bench — CIS Benchmark Scanning

What it does: Runs automated checks against the CIS Kubernetes Benchmark — a set of security best practices for Kubernetes cluster configuration.

Why it’s on the exam: The Cluster Setup domain (10%) tests your ability to identify and remediate CIS benchmark failures.

How kube-bench Works

kube-bench inspects your cluster components (API server, etcd, kubelet, scheduler, controller-manager) and checks them against CIS-recommended settings. It reports:

  • PASS — Configuration meets the benchmark
  • FAIL — Configuration violates the benchmark (fix required)
  • WARN — Manual review recommended
  • INFO — Informational, no action needed

Key Commands

# Run all checks on master node
kube-bench run --targets=master

# Run all checks on worker node
kube-bench run --targets=node

# Run specific check section (e.g., API server)
kube-bench run --targets=master --check=1.2

# Run a single specific check
kube-bench run --targets=master --check=1.2.6

# Output as JSON
kube-bench run --targets=master --json

Example Output

[INFO] 1 Control Plane Security Configuration
[INFO] 1.1 Control Plane Node Configuration Files
[PASS] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive
[PASS] 1.1.2 Ensure that the API server pod specification file ownership is set to root:root
[FAIL] 1.1.3 Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive
[PASS] 1.1.4 Ensure that the controller manager pod specification file ownership is set to root:root

Exam Relevance

Task What You Do
Run kube-bench Execute against master/worker targets
Read output Identify FAIL items
Remediate Fix the specific configuration (file permissions, API server flags)
Verify Re-run kube-bench to confirm PASS

Trivy — Image Vulnerability Scanning

What it does: Scans container images for known vulnerabilities (CVEs) by checking image layers against vulnerability databases.

Why it’s on the exam: The Supply Chain Security domain (20%) tests your ability to identify vulnerable images and enforce image security policies.

How Trivy Works

Trivy pulls the image (or reads from local cache), extracts the OS packages and application dependencies, and matches them against CVE databases. It reports vulnerabilities by severity: CRITICAL, HIGH, MEDIUM, LOW.

Key Commands

# Scan an image for vulnerabilities
trivy image nginx:1.27

# Scan and filter by severity
trivy image --severity CRITICAL,HIGH nginx:1.27

# Scan and fail if CRITICAL vulnerabilities found (exit code 1)
trivy image --exit-code 1 --severity CRITICAL nginx:1.27

# Scan a local image (not pulling from registry)
trivy image --input /path/to/image.tar

# Output as JSON
trivy image --format json nginx:1.27

# Output as table (default)
trivy image --format table nginx:1.27

Example Output

nginx:1.27 (debian 12.5)
Total: 42 (CRITICAL: 2, HIGH: 8, MEDIUM: 20, LOW: 12)

┌──────────────┬────────────────┬──────────┬───────────────┬──────────────────────┐
│   Library    │ Vulnerability  │ Severity │    Version    │   Fixed Version      │
├──────────────┼────────────────┼──────────┼───────────────┼──────────────────────┤
│ libssl3      │ CVE-2024-XXXX  │ CRITICAL │ 3.0.11        │ 3.0.13               │
│ libcurl4     │ CVE-2024-YYYY  │ HIGH     │ 7.88.1        │ 7.88.1-10+deb12u5    │
└──────────────┴────────────────┴──────────┴───────────────┴──────────────────────┘

Exam Relevance

Task What You Do
Scan images Identify images with CRITICAL/HIGH CVEs
Filter results Use --severity to focus on actionable vulnerabilities
Recommend fixes Suggest updated image tags with patched versions
Integrate with policies Combine with ImagePolicyWebhook to block vulnerable images

Falco — Runtime Threat Detection

What it does: Monitors container and host activity in real time by intercepting Linux syscalls. It detects anomalous behavior based on configurable rules.

Why it’s on the exam: The Monitoring, Logging & Runtime Security domain (20%) heavily tests Falco rule writing and configuration.

How Falco Works

Falco operates at the kernel level:

  1. Syscall capture — Falco hooks into the kernel to capture system calls (file access, network connections, process execution)
  2. Rule matching — Each syscall event is evaluated against a set of rules
  3. Alert generation — When a rule matches, Falco generates an alert (stdout, file, syslog, HTTP)

Key Files

/etc/falco/falco.yaml              # Main configuration
/etc/falco/falco_rules.yaml        # Default rules (DO NOT edit)
/etc/falco/falco_rules.local.yaml  # Custom rules (edit THIS file)

Falco Rule Structure

- rule: Terminal shell in container
  desc: A shell was spawned in a container
  condition: >
    spawned_process and container and
    proc.name in (bash, sh, zsh)
  output: >
    Shell spawned in container
    (user=%user.name container=%container.name
    shell=%proc.name parent=%proc.pname)
  priority: WARNING
  tags: [container, shell, mitre_execution]

Key Commands

# Start Falco
systemctl start falco

# Check Falco status
systemctl status falco

# View Falco logs
journalctl -u falco

# Run Falco in foreground (for testing)
falco -r /etc/falco/falco_rules.local.yaml

# Validate rules without running
falco --validate /etc/falco/falco_rules.local.yaml

What Falco Detects

Detection Example
Shell spawned in container kubectl exec -it pod -- /bin/bash
Sensitive file read Container reads /etc/shadow or /etc/passwd
Unexpected outbound connection Container connects to an IP outside the cluster
Binary modified at runtime New executable written inside a running container
Privilege escalation Process gains capabilities or runs as root
Cryptomining activity Known mining process names detected

AppArmor — Mandatory Access Control

What it does: Enforces per-program security profiles that restrict what files, network resources, and capabilities a program can access. AppArmor is a Linux Security Module (LSM).

Why it’s on the exam: The System Hardening domain (15%) tests your ability to create, load, and apply AppArmor profiles to containers.

How AppArmor Works with Kubernetes

  1. Write a profile — Define what the container can access (files, network, capabilities)
  2. Load the profile — Parse and load it into the kernel using apparmor_parser
  3. Apply to Pod — Reference the profile in the Pod’s annotation or security context
  4. Enforce — The kernel blocks any access that violates the profile

Key Commands

# Check AppArmor status
aa-status

# Load a profile
apparmor_parser -q /etc/apparmor.d/my-profile

# Reload a profile (after editing)
apparmor_parser -r /etc/apparmor.d/my-profile

# Remove a profile
apparmor_parser -R /etc/apparmor.d/my-profile

# List loaded profiles
aa-status | grep my-profile

Example AppArmor Profile

#include <tunables/global>

profile my-container-profile flags=(attach_disconnected) {
  #include <abstractions/base>

  # Allow read access to specific paths
  /usr/bin/nginx mr,
  /var/log/nginx/** rw,
  /etc/nginx/** r,

  # Deny write to sensitive paths
  deny /etc/shadow rw,
  deny /etc/passwd w,
  deny /proc/** w,
}

Applying to a Pod (Kubernetes 1.30+)

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    appArmorProfile:
      type: Localhost
      localhostProfile: my-container-profile
  containers:
  - name: app
    image: nginx:1.27

Exam Relevance

Task What You Do
Create profile Write an AppArmor profile restricting file access
Load profile Use apparmor_parser to load on the correct node
Apply to Pod Reference the profile in the Pod spec
Verify enforcement Test that restricted actions are blocked

Common trap: Forgetting to load the AppArmor profile (apparmor_parser) before creating the Pod. The Pod will fail to schedule if the profile isn’t loaded on the node.

Seccomp — Syscall Filtering

What it does: Restricts which Linux syscalls a container can make. Seccomp profiles define an allowlist or denylist of syscalls.

Why it’s on the exam: The System Hardening domain (15%) tests your ability to apply Seccomp profiles to Pods.

How Seccomp Works

Every process makes syscalls (system calls) to interact with the kernel — opening files, creating sockets, forking processes. Seccomp filters these calls:

  • Allow — The syscall proceeds normally
  • Block (EPERM) — The syscall is denied with a permission error
  • Kill — The process is terminated
  • Log — The syscall is allowed but logged

Seccomp Profile Types

Type Description
RuntimeDefault Uses the container runtime’s default Seccomp profile (recommended)
Localhost Uses a custom profile file from the node
Unconfined No Seccomp restrictions (least secure)

Applying Seccomp to a Pod

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: nginx:1.27

Custom Seccomp Profile

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["read", "write", "open", "close", "stat",
                "fstat", "mmap", "mprotect", "brk", "exit_group"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

Custom profiles are stored at: /var/lib/kubelet/seccomp/profiles/

# Reference a custom profile
securityContext:
  seccompProfile:
    type: Localhost
    localhostProfile: profiles/my-custom-profile.json

OPA Gatekeeper / Kyverno — Policy Enforcement

What they do: Enforce custom policies on Kubernetes resources via admission controllers. They evaluate resource creation/modification requests against policy rules and can reject non-compliant resources.

Why they’re on the exam: The Minimize Microservice Vulnerabilities domain (20%) tests policy enforcement via admission controllers.

OPA Gatekeeper

Gatekeeper uses ConstraintTemplates (define the policy logic in Rego) and Constraints (apply the policy to specific resources).

# ConstraintTemplate — defines the policy
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels
        violation[{"msg": msg}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Missing labels: %v", [missing])
        }
# Constraint — applies the policy
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: require-team-label
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  parameters:
    labels: ["team"]

Kyverno

Kyverno uses native Kubernetes YAML for policies (no Rego required):

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-team-label
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "The label 'team' is required."
      pattern:
        metadata:
          labels:
            team: "?*"

Gatekeeper vs Kyverno

Feature OPA Gatekeeper Kyverno
Policy language Rego (custom language) Native Kubernetes YAML
Learning curve Steeper (must learn Rego) Easier (pure YAML)
Flexibility Very high (Rego is powerful) High (covers most use cases)
CKS exam coverage Primary focus May appear as alternative

Tools-to-Exam-Domain Mapping

Tool Exam Domain Weight
kube-bench Cluster Setup 10%
kubectl (RBAC, SA hardening) Cluster Hardening 15%
AppArmor System Hardening 15%
Seccomp System Hardening 15%
OPA Gatekeeper / Kyverno Minimize Microservice Vulnerabilities 20%
Trivy Supply Chain Security 20%
Falco Monitoring, Logging & Runtime Security 20%

Key Commands Reference

Tool Most-Used Command Purpose
kube-bench kube-bench run --targets=master Scan control plane against CIS benchmark
Trivy trivy image --severity CRITICAL,HIGH <image> Scan image for high-severity CVEs
Falco falco -r /etc/falco/falco_rules.local.yaml Run Falco with custom rules
AppArmor apparmor_parser -q /etc/apparmor.d/<profile> Load an AppArmor profile
Seccomp Applied via Pod securityContext.seccompProfile Restrict syscalls in Pod spec
Gatekeeper kubectl apply -f constraint-template.yaml Deploy policy template
Kyverno kubectl apply -f cluster-policy.yaml Deploy cluster policy
aa-status aa-status List loaded AppArmor profiles
crictl crictl ps List running containers

Practice Questions

Q1: What tool would you use to check if your cluster API server configuration follows CIS best practices?

Show Answer

kube-bench. Run it with:

kube-bench run --targets=master

This checks the API server, controller-manager, scheduler, and etcd configurations against the CIS Kubernetes Benchmark.


Q2: You need to find all container images in namespace production that have CRITICAL vulnerabilities. What command would you use?

Show Answer

First, list all images in the namespace:

kubectl get pods -n production -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u

Then scan each image with Trivy:

trivy image --severity CRITICAL <image-name>

To fail on CRITICAL findings (useful in scripts):

trivy image --exit-code 1 --severity CRITICAL <image-name>

Q3: Where should you place custom Falco rules, and why?

Show Answer

Custom rules go in /etc/falco/falco_rules.local.yaml.

You should never edit /etc/falco/falco_rules.yaml (the default rules file) because:

  1. It gets overwritten during Falco upgrades
  2. Your custom rules would be lost
  3. The local file takes precedence and can override default rules

Q4: What is the difference between Seccomp profile types RuntimeDefault and Localhost?

Show Answer
  • RuntimeDefault — Uses the container runtime’s built-in default Seccomp profile. This blocks a standard set of dangerous syscalls and is the recommended baseline for most workloads.
  • Localhost — Uses a custom Seccomp profile file stored on the node at /var/lib/kubelet/seccomp/. Use this when you need a tighter or more specific syscall filter than the runtime default.

Q5: Name the two components required to define a policy in OPA Gatekeeper.

Show Answer
  1. ConstraintTemplate — Defines the policy logic using the Rego language. It specifies what the policy checks.
  2. Constraint — Applies the ConstraintTemplate to specific Kubernetes resources (e.g., Pods in a namespace). It provides parameters and match rules.

Both must exist for a policy to have effect. The ConstraintTemplate defines the “what” and the Constraint defines the “where.”


Next: Assess your readiness with Prerequisites & Study Plan →

Updated: