In short

Choose a published benchmark for each image you ship: the CIS Benchmark for its distribution, or the DISA STIG if you deliver to the US Department of Defense, as implemented by a pinned SCAP Security Guide (SSG) profile. Scan every build in CI with OpenSCAP, offline and pinned, and fail the build on any rule that fails, errors or comes back unknown unless a deviation register lists it with the control, a reason, a compensating control, an owner, an approver other than the owner and an expiry. Expired entries, and scans of another profile or content version, fail the build too. Fix in the image what you can, register only what you cannot, and check running hosts and nodes for what an image on disk cannot show.

  • Benchmark what the team builds and runs: container base images, golden VM images, Kubernetes node images and the container runtime. Laptops and office IT have their own baselines.
  • CIS Benchmark PDFs are free for non-commercial use under CC BY-NC-SA 4.0; XCCDF and other formats, CIS-CAT Pro and commercial use need CIS SecureSuite. DISA STIGs are public downloads.
  • SSG turns CIS and STIG recommendations into OpenSCAP profiles such as xccdf_org.ssgproject.content_profile_cis_level1_server, and each profile's description names the benchmark version it follows.
  • SSG profiles trail the benchmarks: in 0.1.82 the Ubuntu 24.04 CIS profile follows v1.0.0, while CIS has published v2.0.0. Record the profile and content version you actually test against.
  • oscap xccdf eval exits 2 when any rule fails or is unknown, so the gate, not the exit code, decides which failures are accepted.
  • A deviation is a decision with an owner and an expiry, not a pass. Tailoring a rule out of the profile hides it; a register keeps it visible in every scan.
  • An image on disk has no running processes, kernel settings or mounts: two of the eight Ubuntu failures in our scan came from that, not from the image.

Verify it

  1. Run the scan twice on the same image digest and confirm the same counts of each result.
  2. Remove one entry from the register and confirm CI fails, naming that rule.
  3. Set one entry's expiry to yesterday and confirm CI fails on it.
  4. Run the gate against a scan made with another profile or SSG version and confirm it fails.
  5. Change one result in a copy of the results to error and confirm the gate fails.
  6. Confirm that every notchecked rule has a recorded manual review.
Applies to
  • OpenSCAP 1.4.4 (also 1.3.14)
  • SCAP Security Guide 0.1.82

Container base and application images, golden VM images built with tools such as Packer, Kubernetes node images and the container runtime configuration that a software team builds or operates. Hardening of employee laptops and office IT is out of scope.

Part of
Workflow: Review a design
Learning goals and prerequisitesAbout 45 minutes: 15 to read and 30 for the exercise

What you will learn

  • Choose a benchmark and profile for each kind of image you ship, and know the CIS, DISA and SSG access terms.
  • Scan a container image offline with OpenSCAP and read pass, fail, notapplicable and notchecked results.
  • Keep a deviation register with an owner, an independent approver and an expiry, and fail CI on anything unregistered or expired.
  • Recognize the rules an image scan cannot judge, and check running hosts and nodes for them.

Before you start

Platform and DevOps engineers who build base images, golden VM images or Kubernetes node images, and AppSec engineers who own the exceptions process.

  • Build container images with Docker or BuildKit, or VM images with a tool such as Packer.
  • Know which packages and users your images contain and what they run as.
  • For the project: Python 3.11 or later, and Docker for live scans.

Refresh first: Harden container images from Dockerfile to admission

Go to the guided practice

Which images need a benchmark

A hardening benchmark is a published list of configuration settings for one product, such as an operating system release or a container runtime. The images a software team builds are where its settings are decided once and then copied to every running instance, so they are where to check them. Hardening employees' laptops and office servers is enterprise IT and is not covered here.

Use one benchmark per image family, not one per team. A container image is not a whole host, so many host rules do not apply: there is no bootloader, kernel or SSH daemon to configure. SSG marks such rules for machines only, or for systems with a kernel package, and reports them as notapplicable in a container scan.

Which images need a benchmark
What you shipBenchmarkHow to check it
Container base and application imagesThe CIS Benchmark or DISA STIG for the image's distribution, through an SSG profileOpenSCAP on the exported filesystem in CI, as in the project below, or oscap-podman on Fedora and RHEL
Golden VM images (AMIs, Azure and Google Cloud images)The CIS Benchmark for the distribution, Level 1 or 2, or the STIGOpenSCAP inside the build VM during the image build, then again on a booted instance
Kubernetes node imagesThe node OS benchmark plus the provider's CIS benchmark for EKS, AKS or GKEkube-bench as a Job, Bottlerocket's apiclient report cis, or Container-Optimized OS's CIS scanner
Container runtime on hosts you runCIS Docker Benchmark v1.9.0; the worker node sections of the Kubernetes benchmarkdocker-bench-security as a starting point, kube-bench for nodes

CIS, DISA STIG and SCAP Security Guide: access and versions

CIS Benchmark PDFs are free to download for non-commercial use after registering, under the Creative Commons BY-NC-SA 4.0 license. CIS's FAQ says the additional formats (XCCDF, Word and others) are for CIS SecureSuite members, who also get CIS-CAT Pro and the build kits; CIS sells separate membership categories for consultants and for vendors who integrate the benchmarks into products. The free CIS-CAT Lite assesses only Google Chrome, Windows 10 and 11 and Ubuntu Linux 20.04, so for images you will usually scan with SSG instead. CIS's Level 1 profile is a base recommendation designed not to have an extensive performance impact; Level 2 is defense in depth and can have an adverse effect if applied without due care.

DISA publishes Security Technical Implementation Guides at cyber.mil without a login, as XCCDF 1.1 manual STIGs and, for some products, SCAP benchmarks. Rules carry a vulnerability ID such as V-257777, a rule ID and a STIG ID such as RHEL-09-211010, and a severity of CAT I, II or III. Current releases include the RHEL 9 STIG V2R10, the Canonical Ubuntu 24.04 LTS STIG V1R7, the Container Platform SRG V2R5 and the Kubernetes STIG V2R6; the Docker Enterprise 2.x STIG was sunset in July 2024. DISA's Container Hardening Process Guide notes that host profiles produce false positives in containers and allows marking items not applicable.

The SCAP Security Guide, from the ComplianceAsCode project, implements these benchmarks as OpenSCAP data streams. Each product has a data stream named like ssg-ubuntu2404-ds.xml, and each profile ID starts with xccdf_org.ssgproject.content_profile_. The IDs are stable, but the benchmark version behind them lags, as the table shows for SSG 0.1.82 (1 September 2026).

CIS, DISA STIG and SCAP Security Guide: access and versions
ProductCIS and STIG profilesFollowsLatest published
Ubuntu 24.04cis_level1_server, cis_level2_server, cis_level1_workstation, cis_level2_workstation, stigCIS v1.0.0; STIG V1R5CIS v2.0.0; STIG V1R7
RHEL 9cis_server_l1, cis (Level 2 Server), cis_workstation_l1, cis_workstation_l2, stig, stig_guiCIS v2.0.0; STIG V2R9CIS v3.0.0; STIG V2R10
Debian 13cis_level1_server, cis_level2_server, cis_level1_workstation, cis_level2_workstationCIS v1.0.0CIS v1.1.0
Amazon Linux 2023cis_server_l1, cis (Level 2 Server)CIS v1.0.0CIS v1.0.0

Scan an image offline in CI

OpenSCAP can evaluate a filesystem that is not the running system: oscap-chroot sets OSCAP_PROBE_ROOT to the directory and runs oscap xccdf eval against it. The script below creates a container from the image without starting it, exports its filesystem into a scanner container with no network, and gets the ARF results and HTML report back on stdout, so nothing from the host is mounted. The export contains /.dockerenv, one of the markers SSG uses to recognize a container, and most host-only rules are skipped anyway because the image has no kernel package. Pin the image to scan by digest, so the results name exactly what was scanned.

On Fedora and RHEL, oscap-podman <image> xccdf eval ... does the same with a Podman image; it must run as root and cannot remediate. The scanner here is Fedora 44 with OpenSCAP 1.4.4 and SSG 0.1.82 pinned by version, and the scan of ubuntu:24.04 takes a few seconds. The Debian 13 data stream also references Debian's remote OVAL patch definitions, which a scanner without network skips; check patches with your vulnerability scanner instead.

Configurationscan.shShell
#!/bin/sh
# Scan a container image with OpenSCAP and the SCAP Security Guide, with no network.
# Usage: ./scan.sh IMAGE@sha256:DIGEST PRODUCT PROFILE [OUTDIR]
#   ./scan.sh ubuntu:24.04@sha256:534b... ubuntu2404 cis_level1_server results
# Writes OUTDIR/arf.xml (ARF results) and OUTDIR/report.html. Exits non-zero only when the
# scan itself fails; failing rules are for the gate to judge.
set -eu
if [ $# -lt 3 ]; then
  echo "usage: $0 IMAGE@sha256:DIGEST PRODUCT PROFILE [OUTDIR]" >&2
  exit 64
fi
image=$1 product=$2 profile=$3 out=${4:-results}
scanner=${SCANNER_IMAGE:-image-scanner}
case $image in
  *@sha256:*|sha256:*) ;;  # a registry digest, or the ID of a local build
  *) echo "scan.sh: pin the image by digest so the results name exactly what was scanned" >&2
     exit 64 ;;
esac
mkdir -p "$out"
rm -f "$out/arf.xml" "$out/report.html"
container=$(docker create "$image" /bin/true)  # created to export its filesystem, never started
trap 'docker rm "$container" >/dev/null' EXIT
# The image's files go in on stdin and the results come out on stdout: no bind mounts. The
# exported filesystem has /.dockerenv, so SSG skips rules that apply only to machines.
docker export "$container" | docker run --rm -i --network=none "$scanner" sh -c '
  set -eu
  mkdir /target /results
  tar -x -C /target
  status=0
  oscap-chroot /target xccdf eval \
    --profile "xccdf_org.ssgproject.content_profile_$2" \
    --results-arf /results/arf.xml --report /results/report.html \
    "/usr/share/xml/scap/ssg/content/ssg-$1-ds.xml" >&2 || status=$?
  # 0: every rule passed; 2: a rule failed, errored or was unknown; anything else: no scan.
  if [ "$status" -ne 0 ] && [ "$status" -ne 2 ]; then exit "$status"; fi
  tar -c -C /results .' sh "$product" "$profile" | tar -x -C "$out"
test -s "$out/arf.xml"
echo "scan.sh: $image -> $out/arf.xml" >&2

Read the results before you gate on them

Scanning ubuntu:24.04 against the CIS Level 1 Server profile on 11 October 2026 gave 128 pass, 8 fail, 2 notchecked, 270 notapplicable and 240 notselected results. Every failure needs a decision: fix it in the image, or record a deviation. Four were easy to fix in a Dockerfile; two, the root PATH rules, are artifacts of scanning an image on disk, because their check reads the environment of running processes (an OVAL environmentvariable58 test) and an image has none.

The two notchecked results say SSG 0.1.82 has no automated check for these rules on Ubuntu 24.04. They are not passes: check world-writable files and files without a group by hand or with your own test, and record that review.

  • accounts_umask_etc_bashrc and accounts_umask_etc_profile (CIS 5.4.3.3): no umask 027 in /etc/bash.bashrc or /etc/profile. Fix: append umask 027 to both.
  • permissions_local_var_log (6.1.4.1): package logs in /var/log are readable by others. Fix: remove other and group-write access.
  • file_permission_user_init_files (7.2.10): the image's default ubuntu user (UID 1000) has mode 0644 .bashrc, .profile and .bash_logout. Fix: userdel --remove ubuntu; workloads run as their own UID.
  • package_pam_pwquality_installed (5.3.1.3): no password quality module, but no account has a password and no login service runs. Deviation, with non-root workloads and no SSH as the compensating controls.
  • use_pam_wheel_group_for_su (5.2.7): su from util-linux is not restricted to a group. Deviation: workloads run with no-new-privileges, so the setuid su cannot raise privileges.
  • root_path_no_dot and root_path_all_dirs (5.4.2.5): the check reads running processes' PATH, and an image on disk has no processes. Deviation: the image config's PATH has only absolute directories.

Keep a deviation register

NIST SP 800-70 Rev. 5 (May 2026) says any deviation from checklist settings should be reviewed for risk and accompanied by a documented justification with risk acceptance, and that organizations should customize checklists with specific deviations, documented justifications, risk acceptance and compensating controls. A register in the repository, next to the image it describes, makes that reviewable in a pull request. Each entry names the exact SSG rule ID, the benchmark control, why the setting is not applied, the compensating control, an owner, an approver who is not the owner, the approval date and an expiry, and the register as a whole names the benchmark, profile and SSG content version it was reviewed against.

Prefer a register to tailoring. An XCCDF tailoring file, which autotailor generates, can unselect a rule so it never runs, and then the scan reports it as notselected and nobody sees it again. A register keeps the rule in every scan and the decision in front of reviewers until it expires. Approval follows your exceptions process: see /frameworks/risk-exceptions-and-metrics/ for who may accept the risk and what happens at expiry.

Configurationdeviations.yaml (excerpt)YAML
# Deviation register for ubuntu:24.04 scanned against the SCAP Security Guide profile for the
# CIS Ubuntu Linux 24.04 LTS Benchmark v1.0.0, Level 1 - Server (scan-ubuntu2404-cis-l1.xml).
# One entry per failing rule the team accepts for now. The gate fails the build on a failing
# rule without an entry, on an expired entry and on a scan of any other profile or content.
benchmark: xccdf_org.ssgproject.content_benchmark_UBUNTU_24-04
profile: xccdf_org.ssgproject.content_profile_cis_level1_server
content_version: "0.1.82"
deviations:
  - rule: xccdf_org.ssgproject.content_rule_package_pam_pwquality_installed
    control: CIS Ubuntu 24.04 v1.0.0 5.3.1.3
    reason: >-
      The image has no account with a password and no login service, so no password is
      ever set or changed and pam_pwquality would never run.
    compensating_control: >-
      Containers run as UID 10001 with no SSH daemon; the admission policy rejects pods
      that run as root.
    owner: platform-images
    approved_by: appsec-lead
    approved_on: 2026-10-11
    expires: 2027-01-31
  - rule: xccdf_org.ssgproject.content_rule_root_path_no_dot
    control: CIS Ubuntu 24.04 v1.0.0 5.4.2.5
    reason: >-
      False positive of an offline scan: the check reads the environment of running root
      processes (environmentvariable58), and an image filesystem has none.
    compensating_control: >-
      The PATH comes from the image config, /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,
      which has only absolute entries; checked with docker image inspect.
    owner: platform-images
    approved_by: appsec-lead
    approved_on: 2026-10-11
    expires: 2027-01-31

Enforce the register in CI

The gate reads the XCCDF 1.2 TestResult from the ARF report and compares it with the register. It fails the build on a failing, erroring or unknown rule without a valid entry, on an expired entry, on a register entry that is incomplete, self-approved or longer than 180 days, and on a scan of another benchmark, profile or SSG version. It matches entries by exact rule ID: matching by substring would let an entry for accounts_umask waive every umask rule. Rules that no longer fail are reported, so their entries get removed.

On the scan of ubuntu:24.04 with the project's four register entries, the gate fails on the four unregistered rules. The project's example image fixes the other four in one RUN step, and its scan has 132 passes, the 4 registered failures and a passing gate. The project's starter gate made the mistakes that the tests catch: it waived error and unknown, ignored expiry and the scan's profile, and matched by substring.

Fixedgate.pyPython
# gate.py (excerpt): decide the build from the scan and the register
import datetime

XCCDF = "{http://checklists.nist.gov/xccdf/1.2}"
# A rule that errored or came back unknown has not shown compliance either.
FAILING = {"fail", "error", "unknown"}
REVIEW = {"notchecked"}
REQUIRED = ("rule", "control", "reason", "compensating_control", "owner", "approved_by",
            "approved_on", "expires")
MAX_DAYS = 180


def as_date(value):
    if isinstance(value, datetime.date):
        return value
    return datetime.date.fromisoformat(str(value))


def check_register(register):
    """Problems with the register itself, whatever the scan says, and the usable entries."""
    problems, usable = [], {}
    seen = set()
    for i, entry in enumerate(register.get("deviations") or []):
        where = f"deviations[{i}] ({entry.get('rule', '?')})"
        missing = [field for field in REQUIRED if not str(entry.get(field) or "").strip()]
        if missing:
            problems.append(f"{where}: missing {', '.join(missing)}")
            continue
        if entry["rule"] in seen:
            problems.append(f"{where}: duplicate entry")
        seen.add(entry["rule"])
        if entry["approved_by"] == entry["owner"]:
            problems.append(f"{where}: approved by its own owner")
        try:
            approved, expires = as_date(entry["approved_on"]), as_date(entry["expires"])
        except ValueError as error:
            problems.append(f"{where}: {error}")
            continue
        if not 0 < (expires - approved).days <= MAX_DAYS:
            problems.append(f"{where}: expiry must fall within {MAX_DAYS} days of approval")
            continue
        usable[entry["rule"]] = entry
    return problems, usable


def evaluate(scan, register, today):
    """Returns (failures, waived, review, stale): lists of messages."""
    failures, entries = check_register(register)
    for key in ("benchmark", "profile", "content_version"):
        if str(scan[key]) != str(register.get(key)):
            failures.append(f"scan {key} is {scan[key]!r}; the register was reviewed for "
                            f"{register.get(key)!r}")
    if not any(result != "notselected" for result in scan["results"].values()):
        failures.append("the scan evaluated no rules")
    waived, review = [], []
    for rule, result in sorted(scan["results"].items()):
        if result in REVIEW:
            review.append(f"{rule}: {result}, review by hand")
        if result not in FAILING:
            continue
        entry = entries.get(rule)  # the exact rule ID: no prefixes, no substrings
        if entry is None:
            failures.append(f"{rule}: {result}, not in the register")
        elif as_date(entry["expires"]) < today:
            failures.append(f"{rule}: {result}, deviation expired on {entry['expires']}")
        else:
            waived.append(f"{rule}: {result}, deviation {entry['control']} until "
                          f"{entry['expires']} (owner {entry['owner']})")
    stale = [f"{rule}: no longer failing; remove the deviation"
             for rule in entries if scan["results"].get(rule) not in FAILING]
    return failures, waived, review, stale

An image is not the whole host

A scan of an image on disk cannot see services that run, kernel parameters, mounts, audit rules or the environment of running processes. For golden VM images, run OpenSCAP inside the build VM after provisioning, keep the ARF report with the image, and scan an instance booted from it. SSG ships remediation for each profile, such as an Ansible playbook and a Bash script, and oscap xccdf generate fix --fix-type ansible --result-id <id> writes fixes for just the rules that failed in a results file; review generated fixes like any other code before an image build runs them.

For Kubernetes nodes, kube-bench runs the node and control-plane checks as a Job; version 0.16.0 has configurations up to CIS Kubernetes Benchmark 1.12 (Kubernetes 1.32 to 1.34) plus provider benchmarks, and none yet for 2.x. Bottlerocket's default settings are compliant with level 1 of the CIS Bottlerocket Benchmark, and apiclient report cis and apiclient report cis-k8s report on a node; CIS has said it plans to archive the Bottlerocket benchmark unless more community support appears. On GKE, Container-Optimized OS images from milestone 97 comply with CIS Level 1 by default. Managed control planes are the provider's to configure; /domains/runtime/containers/managed-kubernetes-hardening/ covers that split.

Pitfalls

Most benchmark programs fail quietly rather than loudly.

  • Gating on the scanner's exit code alone: exit status 2 covers every failure, accepted or not, so teams either ignore it or switch the scan off.
  • Counting error, unknown or notchecked as passes.
  • Waiving rules by tailoring them out, so they vanish from every later report.
  • Deviations without an expiry, or approved by the person who asked for them.
  • Upgrading SSG without reviewing the new results: new content adds rules and changes what existing rules check.
  • Calling an image compliant because the benchmark's machine-only rules came back notapplicable; they still apply to the host or node that runs it.
  • Copying CIS benchmark text into a commercial product or a customer deliverable: the free PDFs are licensed for non-commercial use only.

Guided practice

Your platform team ships base-ubuntu built on ubuntu:24.04. Its register was reviewed against SSG 0.1.82 and the cis_level1_server profile. Decide what the gate does on each day and change, and why. Today is 2026-10-11 unless stated.

Supplied scenario material
Plain text
Register: package_pam_pwquality_installed (expires 2027-01-31), use_pam_wheel_group_for_su (expires 2026-10-10), root_path_no_dot and root_path_all_dirs (expire 2027-01-31), each approved by appsec-lead and owned by platform-images.
Scan A (SSG 0.1.82, cis_level1_server): fail for the four registered rules; notchecked for file_permissions_unauthorized_world_writable.
Scan B (SSG 0.1.83, cis_level1_server): the same four failures plus one new rule that fails.
Scan C (SSG 0.1.82, cis_level1_server): accounts_umask_etc_bashrc returns error; everything else as in A.
Change D: a pull request adds an entry for accounts_umask owned and approved by platform-images, expiring 2027-12-31.
  1. 1. Gate scan A

    What does the gate report for scan A today?

    Expected result and reasoning

    FAIL: the use_pam_wheel_group_for_su entry expired on 2026-10-10. The other three failures are waived, and the notchecked rule is listed for manual review.

  2. 2. Gate scan B

    What happens when the scanner image moves to SSG 0.1.83?

    Expected result and reasoning

    FAIL before any rule is judged: the scan's content version does not match the register's 0.1.82. Review the new rule and every existing entry against the new content, then update content_version in the same change as the scanner image.

  3. 3. Gate scan C

    accounts_umask_etc_bashrc returns error. Is the image compliant with that rule?

    Expected result and reasoning

    Unknown, so the gate fails: an error is not evidence of compliance. Find out why the check errored, then fix the image or the scan.

  4. 4. Review change D

    What is wrong with the pull request?

    Expected result and reasoning

    Three things: accounts_umask is not a rule ID (exact matching means it waives nothing, and substring matching would waive every umask rule), the owner approved their own entry, and the expiry is more than 180 days after approval. The rule has a two-line fix in the image instead.

Your deliverable: A gate result for scans A to C and review comments for change D, each naming the register field or scan property that decides it.

Paper exercise. The image-benchmark-gate project runs the same checks against a real OpenSCAP scan of ubuntu:24.04.

Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.

No draft saved on this device yet.

Run a local project

Download and unzip a starter with failing tests and a step-by-step README, edit the named exercise file, and run the tests until they pass. The reference solution is a separate download, so you can attempt the repair before you see it.

OpenSCAP 1.4.4 and SSG 0.1.82 in Docker · 45–60 min

Gate an image build on a CIS scan and a deviation register

Repair a CI gate that reads a real OpenSCAP scan of ubuntu:24.04 against the CIS Level 1 Server profile, until unregistered failures, errors, expired deviations and scans of the wrong profile or content version fail the build.

Needs: The offline tests need Python 3.11 or later and nothing else; two register-file tests also need PyYAML, which the scanner image has, and are skipped without it. Live scans need Docker and internet access to build the scanner image and pull the images to scan.

In the extracted folder, run:

Shell
python3 -m unittest -v test_gate.py
docker build -t image-scanner .
sh scan.sh IMAGE@sha256:DIGEST ubuntu2404 cis_level1_server out

12 regression tests · The starter intentionally fails some cases.

Opens in a dev container (VS Code Dev Containers or GitHub Codespaces) with a pinned image.

The fixture is the TestResult of a real scan with OpenSCAP 1.4.4 and SSG 0.1.82, whose Ubuntu profile follows CIS v1.0.0. An image on disk cannot show running services, kernel settings or mounts; scan hosts and nodes as well.

Sources & further reading

The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.

  1. CIS Benchmarks FAQ
  2. CIS: terms and conditions, Terms of Use for Non-Members (CIS Benchmarks free PDF use under CC BY-NC-SA 4.0)
  3. CIS SecureSuite: membership categories
  4. CIS-CAT Assessor coverage guide: CIS-CAT Lite coverage
  5. CIS Ubuntu Linux Benchmarks. Ubuntu Linux 24.04 LTS v2.0.0.
  6. CIS Docker Benchmark. v1.9.0.
  7. CIS: Benchmarks September 2026 update (Bottlerocket archive notice)
  8. DISA: Security Technical Implementation Guides downloads
  9. DISA: Container Hardening Process Guide. Version 1, Release 2 (24 August 2022).
  10. ComplianceAsCode: SCAP Security Guide 0.1.82 release. 0.1.82 (1 September 2026).
  11. ComplianceAsCode: Ubuntu 24.04 CIS Level 1 Server profile. 0.1.82.
  12. ComplianceAsCode developer guide: platforms and the machine CPE. 0.1.82.
  13. OpenSCAP: oscap(8) manual page. 1.4.4.
  14. OpenSCAP user manual: container and offline scanning. 1.3.
  15. NIST SP 800-70 Rev. 5: National Checklist Program for IT Products. Rev. 5 (May 2026).
  16. NIST IR 7275 Rev. 4: XCCDF 1.2 specification. Rev. 4 (March 2012 update).
  17. kube-bench v0.16.0: benchmark versions by platform (cfg/config.yaml)
  18. Bottlerocket: CIS benchmark reports. Bottlerocket 1.65.x.
  19. Google Kubernetes Engine: CIS benchmarks
  20. Container-Optimized OS: CIS compliance
  21. docker-bench-security. v1.6.1.

Reference information

Checked with OpenSCAP 1.4.4, SCAP Security Guide 0.1.82, CIS Ubuntu Linux 24.04 LTS Benchmark v2.0.0, CIS Red Hat Enterprise Linux 9 Benchmark v3.0.0, CIS Docker Benchmark v1.9.0, CIS Kubernetes Benchmark v2.1.0, DISA RHEL 9 STIG V2R10, Canonical Ubuntu 24.04 LTS STIG V1R7, kube-bench 0.16.0 and Docker 29.4.3.

Download this guide as Markdown