Cart

    Sorry, we could not find any results for your search querry.

    Using kubeaudit, kube-bench, kube-hunter, and Trivy in Kubernetes

    A security scan checks whether the configuration of your Kubernetes workloads and cluster complies with security guidelines. Kubeaudit, kube-bench, kube-hunter, and Trivy each examine a different area: workload configuration, node configuration, the network attack surface, or a combination of vulnerabilities and configuration issues.

    This guide explains when to use each tool. You perform a workload audit with kubeaudit, check worker nodes against the CIS Kubernetes Benchmark with kube-bench, start a passive kube-hunter scan from a Pod, and scan manifests and an existing cluster with Trivy.

    • Run security scans only on a cluster that you own or have explicit permission to scan. A scan may generate network traffic, and reports may contain internal IP addresses and other sensitive information.
       
    • Shopify archived kubeaudit in October 2024. Aqua Security states that kube-hunter is no longer actively developed. Use these two tools only for existing workflows or as an additional check. For a new workflow, preferably use the actively maintained kube-bench and a broader tool such as Trivy.
       
    • A successful scan does not prove that an environment is secure. Assess every finding in the context of your own configuration and do not apply suggested changes automatically.
     

     

    Which tool should you choose?

     

    kubeaudit

     

    Kubeaudit assesses Kubernetes manifests or existing workloads for common insecure settings. Examples include containers running as root, missing resource limits, a writable root file system, unwanted Linux capabilities, and missing NetworkPolicies.

    Use kubeaudit early in the development process to check YAML files or inventory an existing namespace. Because the project is archived, it does not recognise all newer Kubernetes features and security guidelines.

    kube-bench

     

    Kube-bench compares the configuration of Kubernetes components with the CIS Kubernetes Benchmark. It checks file permissions and kubelet settings, for example. Kube-bench does not scan application code or vulnerabilities in a container image.

    Use kube-bench periodically and after changes to cluster or node configuration. In a managed Kubernetes environment, you do not have access to the control plane. Therefore, the instructions in this guide check only a worker node.

    kube-hunter

     

    Kube-hunter searches for reachable Kubernetes services and known weaknesses from an attacker's perspective. A scan from a Pod shows what a compromised workload can discover from the cluster network.

    Use kube-hunter only as an additional point-in-time check in a controlled environment. The tool is no longer actively developed, and an old result is not a reliable assessment of a modern environment.

    Trivy

     

    Trivy is an actively maintained security scanner for vulnerabilities in container images, configuration issues in Kubernetes manifests, hard-coded secrets, and overly broad RBAC permissions, among other things. According to Aqua Security, the Kubernetes cluster scan is still experimental and may change without backward compatibility.

    Prefer Trivy for new workflows, local checks, and CI/CD pipelines. Trivy has a broader scope than kubeaudit, but it does not fully replace kube-bench: kube-bench remains the targeted choice for a CIS check of Kubernetes components and nodes.


     

    Requirements

     

    For this guide, you need:

    • A Kubernetes cluster that you own or have permission to scan.
    • kubectl, configured for the correct cluster and context.
    • Permissions to create a namespace and Jobs. Kube-bench also requires hostPID and read-only hostPath volumes.
    • A local text editor for the YAML files.
    • For Trivy: internet access from your client to download Trivy, the vulnerability database, checks, and container images. For a cluster scan, your kubeconfig needs at least read permissions for the resources you scan.

    The kubectl commands work the same in Linux, macOS, and Windows PowerShell. Only the commands for opening files differ by operating system.

    Before each scan, check which context is active:

    kubectl config current-context

    Continue only when the displayed context belongs to the intended cluster.


     

    Using kubeaudit

     

    The latest kubeaudit release is version 0.22.2. Use this version only when intentionally running or comparing an existing kubeaudit workflow.

    Step 1

    From the official kubeaudit release page, download the archive for your operating system and processor architecture. For example, use darwin_arm64 for a Mac with Apple Silicon and windows_amd64 for a regular 64-bit Windows client.

    Also download kubeaudit_0.22.2_checksums.txt and calculate the archive's SHA-256 checksum before extracting it.

    Linux:

    sha256sum <archiefbestand>

    macOS:

    shasum -a 256 <archiefbestand>

    Windows PowerShell:

    Get-FileHash -Algorithm SHA256 <archiefbestand>

    Replace <archiefbestand> with the name of the downloaded file. Compare the displayed checksum with the line for the same archive in kubeaudit_0.22.2_checksums.txt. Extract the archive only when the values match exactly.

    Linux and macOS:

    tar -xzf <archiefbestand>
    chmod +x kubeaudit
    ./kubeaudit version

    Windows PowerShell:

    tar -xzf <archiefbestand>
    .\kubeaudit.exe version

    The -a 256 argument for shasum and the -Algorithm SHA256 argument for Get-FileHash select the SHA-256 algorithm.


     

    Step 2

    Check a manifest before applying it to the cluster.

    Linux and macOS:

    ./kubeaudit all --manifest <bestand.yaml> --minseverity error --no-color --exitcode 0

    Windows PowerShell:

    .\kubeaudit.exe all --manifest <bestand.yaml> --minseverity error --no-color --exitcode 0

    Replace <bestand.yaml> with the path to your Kubernetes manifest. The --manifest argument enables manifest mode, --minseverity error shows only errors, --no-color makes the output suitable for a text file, and --exitcode 0 prevents an interactive scan from exiting with code 2 when errors are found. Omit --exitcode 0 in a CI/CD pipeline if security errors must fail the pipeline.


     

    Step 3

    If necessary, check workloads in an existing namespace. Kubeaudit uses your local user's default kubeconfig.

    Linux and macOS:

    ./kubeaudit all --namespace <namespace> --minseverity error --no-color --exitcode 0

    Windows PowerShell:

    .\kubeaudit.exe all --namespace <namespace> --minseverity error --no-color --exitcode 0

    Replace <namespace> with the namespace you want to check. The account in your kubeconfig must be allowed to list resources in that namespace. The all command does not modify resources.


     

    Step 4

    Assess each error for the referenced resource and container. Pay particular attention to securityContext, automatic mounting of ServiceAccount tokens, Linux capabilities, resource limits, and NetworkPolicies. Do not use the autofix function directly on production manifests; apply the suggested change manually and review it in version control.


     

    Using kube-bench

     

    The configuration below uses kube-bench 0.15.6. Check the official releases before reusing this configuration and review the release notes before updating the image tag.

    Kube-bench needs access to processes and configuration files on the worker node. The Job therefore uses hostPID and mounts several node directories as read-only. Grant these permissions only to the version-pinned kube-bench image from the official repository.

    Step 1

    Create a separate namespace and retrieve the names of your worker nodes:

    kubectl create namespace security-audit
    kubectl get nodes

    Choose the node you want to check first. Later, run the scan separately for each worker node because a Job runs on only one node.


     

    Step 2

    On Linux, use nano, or use the same command on macOS, to open kube-bench.yaml:

    nano kube-bench.yaml

    In Windows PowerShell, use Notepad:

    notepad.exe kube-bench.yaml

    Add the following configuration and replace <node-name> with the name of the selected worker node:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: kube-bench
      namespace: security-audit
    spec:
      backoffLimit: 0
      template:
        metadata:
          labels:
            app: kube-bench
        spec:
          automountServiceAccountToken: false
          hostPID: true
          nodeName: <node-name>
          restartPolicy: Never
          containers:
            - name: kube-bench
              image: docker.io/aquasec/kube-bench:v0.15.6
              command: ["kube-bench", "run", "--targets", "node"]
              volumeMounts:
                - name: var-lib-cni
                  mountPath: /var/lib/cni
                  readOnly: true
                - name: var-lib-kubelet
                  mountPath: /var/lib/kubelet
                  readOnly: true
                - name: etc-systemd
                  mountPath: /etc/systemd
                  readOnly: true
                - name: lib-systemd
                  mountPath: /lib/systemd
                  readOnly: true
                - name: etc-kubernetes
                  mountPath: /etc/kubernetes
                  readOnly: true
                - name: usr-bin
                  mountPath: /usr/local/mount-from-host/bin
                  readOnly: true
                - name: etc-cni-netd
                  mountPath: /etc/cni/net.d
                  readOnly: true
                - name: opt-cni-bin
                  mountPath: /opt/cni/bin
                  readOnly: true
          volumes:
            - name: var-lib-cni
              hostPath:
                path: /var/lib/cni
            - name: var-lib-kubelet
              hostPath:
                path: /var/lib/kubelet
            - name: etc-systemd
              hostPath:
                path: /etc/systemd
            - name: lib-systemd
              hostPath:
                path: /lib/systemd
            - name: etc-kubernetes
              hostPath:
                path: /etc/kubernetes
            - name: usr-bin
              hostPath:
                path: /usr/bin
            - name: etc-cni-netd
              hostPath:
                path: /etc/cni/net.d
            - name: opt-cni-bin
              hostPath:
                path: /opt/cni/bin

    The --targets node option limits the scan to checks for a worker node. By default, kube-bench selects an available CIS test set based on the Kubernetes version it detects on the node. There is no one-to-one relationship between every Kubernetes version and a CIS Benchmark version; therefore, also check the supported benchmark versions.


     

    Step 3

    Save the file, close the text editor, and start the Job:

    kubectl apply -f kube-bench.yaml
    kubectl wait --for=condition=complete job/kube-bench --namespace security-audit --timeout=180s
    kubectl logs job/kube-bench --namespace security-audit

    The wait command waits until the Job is complete. The optional --timeout=180s argument stops waiting after 180 seconds. If the timeout expires, use kubectl describe job kube-bench --namespace security-audit to determine why the Job did not start.


     

    Step 4

    The output uses PASS for a successful check, FAIL for a detected deviation, and WARN for a check that requires manual assessment. A FAIL does not automatically mean that the cluster is vulnerable. File paths and implementation details may differ from the assumptions in the CIS test.

    In a managed Kubernetes cluster, the control plane and host configuration are managed by the provider. Do not apply the displayed node remediations yourself to provider-managed nodes. Use findings within your control to improve workloads and contact TransIP when a finding concerns the managed layer.

    To scan another worker node, first delete the Job, replace nodeName in kube-bench.yaml, and apply the file again:

    kubectl delete job kube-bench --namespace security-audit
    kubectl apply -f kube-bench.yaml

     

    Using kube-hunter

     

    The following Job uses kube-hunter 0.6.8 in passive Pod mode. The Job does not receive a ServiceAccount token and drops Linux capabilities. This allows kube-hunter to examine which services are reachable from the Pod network without testing permissions from a mounted ServiceAccount token.

    Do not add the --active option. Active hunting attempts to exploit detected weaknesses and may change the cluster state. Use this option only in an isolated test environment with separate permission and a recovery plan.

     

    Step 1

    On Linux or macOS, open kube-hunter.yaml:

    nano kube-hunter.yaml

    In Windows PowerShell, use Notepad:

    notepad.exe kube-hunter.yaml

    Add the following configuration:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: kube-hunter
      namespace: security-audit
    spec:
      backoffLimit: 0
      activeDeadlineSeconds: 180
      template:
        metadata:
          labels:
            app: kube-hunter
        spec:
          automountServiceAccountToken: false
          restartPolicy: Never
          securityContext:
            seccompProfile:
              type: RuntimeDefault
          containers:
            - name: kube-hunter
              image: docker.io/aquasec/kube-hunter:0.6.8
              command: ["kube-hunter"]
              args: ["--pod"]
              securityContext:
                allowPrivilegeEscalation: false
                capabilities:
                  drop: ["ALL"]

    The --pod option starts discovery from the cluster network. activeDeadlineSeconds terminates the Job if it is still active after 180 seconds. The container uses the fixed image tag 0.6.8 instead of latest so that a future run does not unexpectedly use different code.


     

    Step 2

    Save the file, close the text editor, and start the passive scan:

    kubectl apply -f kube-hunter.yaml
    kubectl wait --for=condition=complete job/kube-hunter --namespace security-audit --timeout=180s
    kubectl logs job/kube-hunter --namespace security-audit

    The output contains detected nodes, reachable services, and potential vulnerabilities. The IDs refer to descriptions in the Aqua Vulnerability Database. Do not share the full output publicly: evidence may contain internal addresses and configuration data.


     

    Step 3

    First check whether a finding still applies to your Kubernetes version. Then use kubectl and the current Kubernetes documentation to confirm whether the detected service or setting is actually reachable when it should not be. Never treat a kube-hunter result as the sole evidence of a vulnerability.


     

    Using Trivy

     

    With Trivy, you first check local manifests and then the resources in the active cluster. The examples use Trivy 0.72 or newer. When using a newer version, always consult the current Trivy documentation, because the Kubernetes cluster scan is still experimental.

    Step 1

    Install Trivy on the client that you use to manage the cluster.

    Ubuntu and Debian

     

    Add the official Trivy repository and install Trivy:

    sudo apt-get install wget gnupg
    wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
    echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
    sudo apt-get update
    sudo apt-get install trivy
     
     

    macOS

     

    Install Trivy with Homebrew:

    brew install trivy
     
     

    Windows

     

    Download trivy_0.72.0_windows-64bit.zip from the official Trivy release page. Open PowerShell in the download folder and extract the file:

    Expand-Archive -Path .	rivy_0.72.0_windows-64bit.zip -DestinationPath .	rivy

    Add the extracted folder to PATH or run trivy.exe directly from that folder.

     
     

    Check the installation:

    trivy --version

    If you use Windows and Trivy is not in PATH, run the following commands from the extracted folder and use trivy.exe instead of trivy.


     

    Step 2

    Open a terminal in the folder containing your Kubernetes manifests and scan all supported configuration files in the current folder:

    trivy config --severity HIGH,CRITICAL .

    Trivy recognises Kubernetes YAML, Helm Charts, and Dockerfiles, among other formats. The --severity option limits the output to HIGH and CRITICAL findings. The period at the end refers to the current folder. Specify a file name or another path instead if you want to scan a single manifest or a different folder.

    During the first scan, Trivy downloads checks and databases. The first run may therefore take longer and requires internet access.


     

    Step 3

    Check the active kubectl context again, and then start a summary cluster scan:

    kubectl config current-context
    trivy k8s --report=summary --disable-node-collector

    By default, Trivy uses the active context from your kubeconfig. The --report=summary option displays a compact overview. With --disable-node-collector, Trivy does not create node-collector Jobs in the cluster. Findings about node configuration are then omitted; use the kube-bench scan in this guide for those checks.

    If you omit --disable-node-collector, Trivy creates node-collector Jobs by default and needs additional cluster permissions to create and delete namespaces and Jobs, among other actions. Use this mode only when you need the additional node check and have assessed the permissions and impact beforehand.

     

    Prefer limiting a detailed scan to one namespace:

    trivy k8s --include-namespaces <namespace> --severity=HIGH,CRITICAL --report=all --disable-node-collector

    Replace <namespace> with the namespace you want to scan. The --include-namespaces option limits the scan to that namespace, --severity shows only HIGH and CRITICAL findings, and --report=all displays details for each resource.


     

    Step 4

    Save a complete report in JSON format if you want to process the results automatically:

    trivy k8s --report=all --format=json --output=trivy-kubernetes-report.json --disable-node-collector

    The --format=json option makes the output machine-readable, and --output writes it to trivy-kubernetes-report.json. The report may contain resource names, vulnerabilities, and other internal information. Store it only in a location with appropriate access permissions.

    To stop a CI/CD pipeline when a local HIGH or CRITICAL finding is detected, use:

    trivy config --severity=HIGH,CRITICAL --exit-code=1 .

    The --exit-code=1 option makes Trivy exit with status code 1 when a matching finding is detected. Review the results manually before adding an exception or blocking a deployment.


     

    Deleting the scan resources

     

    Delete the namespace after securely storing and reviewing the reports. This removes the kube-bench and kube-hunter Jobs and their Pods:

    kubectl delete namespace security-audit

    Store reports only in a location with appropriate access permissions and remove internal IP addresses, tokens, and other sensitive evidence before sharing a report.


     

    You now know which part of Kubernetes kubeaudit, kube-bench, kube-hunter, and Trivy check and how to use each tool within its limitations. Combine periodic CIS checks with Trivy scans of manifests and clusters, controlled network scans, and manual assessment to improve your cluster's security posture.

    Need help?

    Receive personal support from our supporters

    Contact us