# benchmarking-kubernetes-with-kube-bench

Installs and runs the kube-bench tool against a Kubernetes cluster as a Job, DaemonSet, or standalone binary, selecting the correct benchmark version and targets (control plane, etcd, kubelet, worker nodes) and emitting JSON or JUnit output for pipelines. Use when setting kube-bench up for the first time, choosing which benchmark version and node targets to run, wiring it into CI, or troubleshooting skipped or misdetected checks. Keywords: kube-bench, DaemonSet, --benchmark, --targets, JSON output, JUnit, CI integration. Do not use for interpreting the findings or producing an audit report - use performing-kubernetes-cis-benchmark-with-kube-bench.

- **Kind:** skill
- **Source:** https://github.com/mukul975/Anthropic-Cybersecurity-Skills
- **Page:** https://forefy.com/skills/38e9ccb6-b47c-4af4-a36a-2fe2f2d58ee1
- **API (JSON + files):** https://forefy.com/api/asr/38e9ccb6-b47c-4af4-a36a-2fe2f2d58ee1

---

## LICENSE

```

```

## SKILL.md

---
name: benchmarking-kubernetes-with-kube-bench
description: >-
  Installs and runs the kube-bench tool against a Kubernetes cluster as a Job, DaemonSet, or
  standalone binary, selecting the correct benchmark version and targets (control plane, etcd,
  kubelet, worker nodes) and emitting JSON or JUnit output for pipelines. Use when setting
  kube-bench up for the first time, choosing which benchmark version and node targets to run,
  wiring it into CI, or troubleshooting skipped or misdetected checks. Keywords: kube-bench,
  DaemonSet, --benchmark, --targets, JSON output, JUnit, CI integration. Do not use for
  interpreting the findings or producing an audit report - use
  performing-kubernetes-cis-benchmark-with-kube-bench.
domain: cybersecurity
subdomain: container-security
tags:
- kubernetes
- kube-bench
- cis-benchmark
- container-security
- hardening
- compliance
- cluster-security
version: '1.0'
author: mahipal
license: Apache-2.0
nist_csf:
- PR.PS-01
mitre_attack:
- T1610
---
# Benchmarking Kubernetes with kube-bench

## Overview

kube-bench (by Aqua Security) is an open-source tool that checks whether a Kubernetes cluster is deployed securely by running the checks documented in the **CIS Kubernetes Benchmark**. It inspects the control-plane components (API server, controller manager, scheduler, etcd), the kubelet and worker-node configuration, and cluster-wide policy settings, then reports each check as PASS, FAIL, WARN, or INFO with a remediation recommendation drawn directly from the CIS guidance. Tests are configuration-driven YAML files, so kube-bench tracks new Kubernetes versions and benchmark revisions and supports managed distributions (EKS, GKE, AKS, ACK, OpenShift, RKE, k3s).

Hardening a cluster against the CIS Benchmark directly reduces the attack surface for **T1610 (Deploy Container)**, where an adversary deploys a container to execute code or evade defenses — for example by abusing privileged containers, host namespaces, anonymous API access, or insecure kubelet settings that an unhardened cluster leaves exposed.

kube-bench can run as a standalone binary on a node, inside a container, or — most commonly — as a Kubernetes Job whose pod has the host filesystem mounted so it can read the relevant config files. Output is available as human-readable text, JSON, JUnit, or AWS Security Finding Format (ASFF) and can be pushed to a PostgreSQL database for trend tracking.

## When to Use

- When establishing a security baseline for a new Kubernetes cluster against the CIS Kubernetes Benchmark.
- When performing periodic compliance audits of control-plane and node hardening.
- When validating remediation after applying hardening changes (re-run to confirm checks now PASS).
- When integrating cluster compliance scanning into CI/CD or a continuous monitoring pipeline.
- When preparing evidence for SOC 2, PCI DSS, or internal hardening compliance.

## Prerequisites

- Access to the cluster: either SSH access to a control-plane/worker node (binary mode) or `kubectl` with permission to create Jobs (in-cluster mode).
- Knowledge of the cluster's Kubernetes version (kube-bench auto-detects, or specify with `--version` / `--benchmark`).
- Install kube-bench (Aqua Security official methods):

```bash
# Binary release (Linux)
KB_VERSION=0.10.7
curl -L -o kube-bench.tgz \
  "https://github.com/aquasecurity/kube-bench/releases/download/v${KB_VERSION}/kube-bench_${KB_VERSION}_linux_amd64.tar.gz"
tar -xzf kube-bench.tgz
sudo mv kube-bench /usr/local/bin/
sudo cp -R cfg /etc/kube-bench/cfg

# Via Go install
go install github.com/aquasecurity/kube-bench@latest

# Run as a one-off container directly on a node (mounts host config)
docker run --rm --pid=host \
  -v /etc:/etc:ro -v /var:/var:ro \
  -t docker.io/aquasec/kube-bench:latest run --targets node

# Verify
kube-bench version
```

## Objectives

- Run kube-bench against the appropriate benchmark for the cluster's Kubernetes version.
- Scan control-plane (master), node, etcd, control-plane policies, and managed-service targets.
- Produce machine-readable JSON/JUnit output for pipelines and dashboards.
- Triage FAIL and WARN results and apply CIS remediation guidance.
- Re-run to validate that remediations now PASS.

## MITRE ATT&CK Mapping

| Technique ID | Name | Tactic | Relevance |
|--------------|------|--------|-----------|
| T1610 | Deploy Container | Execution / Defense Evasion | CIS Benchmark hardening enforced by kube-bench restricts privileged/host-namespace deployments, anonymous API access, and insecure kubelet settings that adversaries abuse when deploying malicious containers. |

## Workflow

### 1. Run the default scan (auto-detect)

Run all applicable targets, letting kube-bench detect the Kubernetes version and benchmark:

```bash
sudo kube-bench
```

### 2. Run as a Kubernetes Job (in-cluster)

Apply the provided Job manifest from the kube-bench repo and read the results from the pod logs:

```bash
# General-purpose job
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml

# Wait, then retrieve results
kubectl get pods -l app=kube-bench
kubectl logs -l app=kube-bench

# Platform-specific jobs are available, e.g. EKS:
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job-eks.yaml
```

### 3. Target specific components

Use `run --targets` to scope the scan to particular component groups:

```bash
# Control-plane (API server, scheduler, controller manager)
sudo kube-bench run --targets master

# Worker node (kubelet, proxy)
sudo kube-bench run --targets node

# etcd datastore
sudo kube-bench run --targets etcd

# Cluster-wide policies (RBAC, pod security, network policy)
sudo kube-bench run --targets policies

# Combine multiple targets
sudo kube-bench run --targets master,node,etcd,policies
```

### 4. Pin a specific benchmark or Kubernetes version

When auto-detection is wrong or you must audit against a specific revision, pin the benchmark explicitly:

```bash
# Pin to a specific CIS benchmark revision
sudo kube-bench run --benchmark cis-1.8

# Or map by Kubernetes version
sudo kube-bench --version 1.27

# Managed/distribution-specific benchmarks
sudo kube-bench run --benchmark eks-1.5.0
sudo kube-bench run --benchmark gke-1.6.0
sudo kube-bench run --benchmark rke2-cis-1.7
```

### 5. Run or skip individual checks

Focus on or exclude specific check IDs during remediation cycles:

```bash
# Run only specific checks
sudo kube-bench run --targets master --check 1.2.1,1.2.2

# Skip noisy/known-accepted checks
sudo kube-bench run --targets node --skip 4.2.6
```

### 6. Produce machine-readable output

Emit JSON or JUnit for ingestion into pipelines, SIEM, or dashboards, and write to a file:

```bash
# JSON to a file
sudo kube-bench run --targets master,node --json --outputfile kube-bench-report.json

# JUnit (for CI test reporting)
sudo kube-bench --junit --outputfile kube-bench-junit.xml

# AWS Security Finding Format (for Security Hub)
sudo kube-bench run --targets node --asff
```

### 7. Triage and remediate FAIL/WARN findings

Each failing check prints a remediation. Apply the CIS-recommended fix on the node/manifest, for example tightening API server flags in the static pod manifest:

```bash
# Example remediation for a common control-plane FAIL:
# CIS 1.2.x — ensure anonymous-auth is disabled on the API server.
# Edit the static pod manifest and set the flag:
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
#   - --anonymous-auth=false
# The kubelet restarts the static pod automatically.

# Example node remediation — kubelet config file permissions (CIS 4.1.x):
sudo chmod 600 /etc/kubernetes/kubelet/kubelet-config.json
sudo chown root:root /etc/kubernetes/kubelet/kubelet-config.json
```

### 8. Re-validate after remediation

Re-run the relevant target and confirm the previously failing checks now PASS, then track the score over time:

```bash
sudo kube-bench run --targets master --check 1.2.1 --json --outputfile recheck.json

# Optional: persist results to PostgreSQL for trend tracking
sudo kube-bench run --targets master,node --pgsql
```

## Tools and Resources

| Tool / Resource | Purpose | Link |
|------------------|---------|------|
| kube-bench | CIS Kubernetes Benchmark checker | https://github.com/aquasecurity/kube-bench |
| kube-bench docs | Running / platforms / flags | https://aquasecurity.github.io/kube-bench/ |
| CIS Kubernetes Benchmark | Source hardening standard | https://www.cisecurity.org/benchmark/kubernetes |
| Trivy Operator | Continuous in-cluster compliance + vuln scanning | https://github.com/aquasecurity/trivy-operator |
| kube-hunter | Complementary penetration-testing tool | https://github.com/aquasecurity/kube-hunter |

## Validation Criteria

- [ ] kube-bench installed (`kube-bench version`) or running as a Job.
- [ ] Scan run against the correct benchmark for the cluster's Kubernetes version.
- [ ] master, node, etcd, and policies targets each scanned.
- [ ] JSON/JUnit output produced for pipeline/dashboard ingestion.
- [ ] FAIL and WARN findings triaged and prioritized.
- [ ] CIS remediation applied to control-plane manifests and node configs.
- [ ] Re-run confirms previously failing checks now PASS.
- [ ] Results tracked over time (file archive or PostgreSQL).

## references

```

```

## references/api-reference.md

# kube-bench — Command and Flag Reference

## Core Commands

| Command | Description |
|---------|-------------|
| `kube-bench` | Auto-detect version and run all applicable checks |
| `kube-bench run` | Explicit run command (use with `--targets`/`--benchmark`) |
| `kube-bench version` | Print kube-bench version |

## Key Flags

| Flag | Description | Example |
|------|-------------|---------|
| `--targets` | Component groups to test | `--targets master,node,etcd,policies,controlplane,managedservices` |
| `--benchmark` | Pin a specific benchmark revision | `--benchmark cis-1.8` |
| `--version` | Map by Kubernetes version | `--version 1.27` |
| `--check` | Run only specific check IDs (comma list) | `--check 1.2.1,1.2.2` |
| `--skip` | Skip specific check IDs | `--skip 4.2.6` |
| `--json` | Output results as JSON | `--json` |
| `--junit` | Output results as JUnit XML | `--junit` |
| `--asff` | AWS Security Finding Format (Security Hub) | `--asff` |
| `--pgsql` | Write results to PostgreSQL | `--pgsql` |
| `--outputfile` | Write output to a file | `--outputfile report.json` |
| `--config-dir` | Path to config/cfg directory | `--config-dir /etc/kube-bench/cfg` |
| `--config` | Path to alternate config.yaml | `--config ./config.yaml` |
| `--include-test-output` | Include raw command output in results | `--include-test-output` |

## Targets

| Target | Scope |
|--------|-------|
| `master` | Control-plane: API server, scheduler, controller manager |
| `etcd` | etcd datastore configuration |
| `controlplane` | Authentication/authorization and logging policies |
| `node` | kubelet and kube-proxy on worker nodes |
| `policies` | RBAC, service accounts, pod security, network policy |
| `managedservices` | Managed-service-specific controls (EKS/GKE/etc.) |

## Benchmark Profiles (examples)

| Benchmark | Platform |
|-----------|----------|
| `cis-1.8`, `cis-1.9` | Upstream Kubernetes (CIS) |
| `eks-1.5.0` | Amazon EKS |
| `gke-1.6.0` | Google GKE |
| `aks-1.7` | Azure AKS |
| `rke2-cis-1.7`, `k3s-cis-1.7` | Rancher RKE2 / k3s |
| `ocp-4.x` | OpenShift |

## In-Cluster Job Manifests

| File | Use |
|------|-----|
| `job.yaml` | Generic in-cluster run |
| `job-master.yaml` | Control-plane node checks |
| `job-node.yaml` | Worker node checks |
| `job-eks.yaml`, `job-gke.yaml`, `job-aks.yaml` | Managed-platform variants |

```bash
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs -l app=kube-bench
```

## Result States

| State | Meaning |
|-------|---------|
| `PASS` | Check satisfied |
| `FAIL` | Check failed — remediation required |
| `WARN` | Manual verification needed |
| `INFO` | Informational only |

## External References

- Running: https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md
- Platforms: https://github.com/aquasecurity/kube-bench/blob/main/docs/platforms.md
- Output formats: https://github.com/aquasecurity/kube-bench/blob/main/docs/output.md

## references/standards.md

# Standards and References — Benchmarking Kubernetes with kube-bench

## NIST CSF 2.0

| ID | Name | Rationale |
|----|------|-----------|
| PR.PS-01 | Configuration management practices are established and applied | kube-bench audits Kubernetes control-plane, node, and policy configuration against the CIS Benchmark, enforcing secure configuration management. |

## MITRE ATT&CK

| Technique ID | Name | Tactic | Rationale |
|--------------|------|--------|-----------|
| T1610 | Deploy Container | Execution / Defense Evasion | CIS hardening verified by kube-bench restricts privileged/host-namespace container deployment, anonymous API access, and insecure kubelet settings adversaries abuse to deploy containers. |

## Supporting Frameworks and Standards

- **CIS Kubernetes Benchmark** — the authoritative source standard kube-bench implements (control-plane, etcd, node, policy controls).
- **CIS Benchmarks for EKS / GKE / AKS / OpenShift** — managed-distribution variants kube-bench supports via dedicated benchmark profiles.
- **NSA/CISA Kubernetes Hardening Guidance** — complementary hardening recommendations overlapping CIS controls.
- **PCI DSS / SOC 2** — kube-bench JSON/JUnit output supports configuration-compliance evidence.

## Official Resources

- kube-bench: https://github.com/aquasecurity/kube-bench
- kube-bench docs: https://aquasecurity.github.io/kube-bench/
- CIS Kubernetes Benchmark: https://www.cisecurity.org/benchmark/kubernetes
- Running guide: https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md
- Platforms guide: https://github.com/aquasecurity/kube-bench/blob/main/docs/platforms.md

## scripts

```

```

## scripts/agent.py

```python
#!/usr/bin/env python3
"""kube-bench helper.

Runs kube-bench with JSON output, parses the CIS Kubernetes Benchmark
results, summarises PASS/FAIL/WARN/INFO totals per section, lists failing
checks with their remediation, and optionally exits non-zero when failures
exist (for CI/CD compliance gating).

Requires the `kube-bench` binary on PATH (or run inside the aquasec/kube-bench
container). See https://github.com/aquasecurity/kube-bench
"""

import argparse
import json
import shutil
import subprocess
import sys
from collections import Counter
from datetime import datetime, timezone


def ensure_kube_bench() -> str:
    """Return the kube-bench path or exit with install guidance."""
    path = shutil.which("kube-bench")
    if not path:
        print("[!] kube-bench not found on PATH. Install: "
              "https://github.com/aquasecurity/kube-bench/releases",
              file=sys.stderr)
        sys.exit(2)
    return path


def run_kube_bench(binary: str, targets: str, benchmark: str, timeout: int) -> dict:
    """Execute kube-bench with JSON output and return the parsed report."""
    cmd = [binary, "run", "--targets", targets, "--json"]
    if benchmark:
        cmd += ["--benchmark", benchmark]
    print(f"[*] running: {' '.join(cmd)}")
    try:
        proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
    except subprocess.TimeoutExpired:
        print(f"[!] kube-bench timed out after {timeout}s", file=sys.stderr)
        sys.exit(3)
    # kube-bench may exit non-zero when checks fail; results are still on stdout.
    if not proc.stdout.strip():
        print(f"[!] kube-bench produced no output (rc={proc.returncode}): "
              f"{proc.stderr.strip()}", file=sys.stderr)
        sys.exit(proc.returncode or 4)
    try:
        return json.loads(proc.stdout)
    except json.JSONDecodeError:
        print("[!] Could not parse kube-bench JSON output.", file=sys.stderr)
        print(proc.stderr.strip(), file=sys.stderr)
        sys.exit(4)


def iter_checks(report: dict):
    """Yield (section_id, section_text, check) tuples across all controls."""
    # kube-bench JSON: top-level "Controls" -> "tests" -> "results".
    controls = report.get("Controls")
    if controls is None and isinstance(report, list):
        controls = report
    for control in controls or []:
        for section in control.get("tests", []) or []:
            sid = section.get("section", "")
            stext = section.get("desc", "")
            for check in section.get("results", []) or []:
                yield sid, stext, check


def summarise(report: dict):
    """Return overall Counter, per-section Counters, and failing checks."""
    overall = Counter()
    per_section = {}
    failures = []
    for sid, stext, check in iter_checks(report):
        state = (check.get("status") or "").upper()
        overall[state] += 1
        per_section.setdefault(sid, [stext, Counter()])
        per_section[sid][1][state] += 1
        if state in ("FAIL", "WARN"):
            failures.append({
                "section": sid,
                "id": check.get("test_number"),
                "desc": check.get("test_desc"),
                "status": state,
                "remediation": (check.get("remediation") or "").strip(),
            })
    return overall, per_section, failures


def main() -> None:
    parser = argparse.ArgumentParser(description="kube-bench CIS compliance helper")
    parser.add_argument("--targets", default="master,node",
                        help="Comma list: master,node,etcd,policies,controlplane")
    parser.add_argument("--benchmark", default="", help="Pin benchmark, e.g. cis-1.8")
    parser.add_argument("--timeout", type=int, default=300, help="Run timeout (s)")
    parser.add_argument("--show-remediation", action="store_true",
                        help="Print remediation text for each failing check")
    parser.add_argument("--fail-on-warn", action="store_true",
                        help="Treat WARN as gating in addition to FAIL")
    parser.add_argument("--gate", action="store_true",
                        help="Exit non-zero when failing checks exist")
    parser.add_argument("--output", help="Write JSON summary to file")
    args = parser.parse_args()

    binary = ensure_kube_bench()
    report = run_kube_bench(binary, args.targets, args.benchmark, args.timeout)
    overall, per_section, failures = summarise(report)

    print(f"\n=== kube-bench summary {datetime.now(timezone.utc).isoformat()} ===")
    for state in ("PASS", "FAIL", "WARN", "INFO"):
        print(f"  {state:<5}: {overall.get(state, 0)}")

    print("\n--- Per section ---")
    for sid in sorted(per_section):
        text, counts = per_section[sid]
        print(f"  [{sid}] {text}: "
              f"PASS={counts.get('PASS',0)} FAIL={counts.get('FAIL',0)} "
              f"WARN={counts.get('WARN',0)}")

    print(f"\n--- Findings requiring action ({len(failures)}) ---")
    for f in failures:
        print(f"  {f['status']} {f['id']}: {f['desc']}")
        if args.show_remediation and f["remediation"]:
            print(f"      -> {f['remediation']}")

    if args.output:
        with open(args.output, "w", encoding="utf-8") as fh:
            json.dump({"overall": dict(overall), "failures": failures}, fh, indent=2)
        print(f"[+] Summary written to {args.output}")

    if args.gate:
        blocking = overall.get("FAIL", 0)
        if args.fail_on_warn:
            blocking += overall.get("WARN", 0)
        if blocking > 0:
            print(f"[!] GATE FAILED: {blocking} non-compliant checks", file=sys.stderr)
            sys.exit(1)
    print("[+] Done.")


if __name__ == "__main__":
    main()
```

