Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation

    OpenSCAP Compliance Scanning

    Applies to CentOS Stream 9 & 10 / AlmaLinux 9.x & 10.x / Rocky Linux 9.x & 10.x

    Compliance checks often mean walking through a checklist of hundreds of items, verifying your system configuration one by one. OpenSCAP automates this: it reads a standardized security baseline, scans your system, tells you which items pass and which fail, and can even remediate them for you.

    • What the SCAP standard and its components (XCCDF, OVAL, datastream) are
    • How to install OpenSCAP and find the baseline content for your distribution
    • How to scan a system with CIS, DISA STIG, and other profiles and generate a readable HTML report
    • How to interpret scan results and run automatic remediation safely
    • How to apply a baseline at install time, scan container images, and set up periodic compliance checks
    • A system running EL 9.x or EL 10.x
    • sudo privileges
    • Access to DNF repositories (baseline content packages install from the default repos)
    • Strongly recommended: work on a test machine or VM snapshot first before applying to production

    SCAP (Security Content Automation Protocol) is a set of standards maintained by NIST that describe “security compliance checks” in a machine-readable format, so that different tools can exchange and execute the same baseline. It consists of several components:

    ComponentRole
    XCCDFThe checklist format, describing individual rules, profiles, and how pass/fail is determined
    OVALThe detection logic, defining “how to actually check the system state” (e.g., whether a file’s permissions are 600)
    datastreamThe packaging format (*-ds.xml) that bundles XCCDF, OVAL, and other content into a single file

    OpenSCAP (oscap) is the open-source implementation of SCAP on EL — the command-line tool that performs scans and remediation. The actual baseline content is provided by the SCAP Security Guide (SSG) project, which packages CIS, DISA STIG, and other baselines for each distribution.

    Install the scanner and baseline content
    $ sudo dnf install openscap-scanner scap-security-guide
    • openscap-scanner provides the oscap command.
    • scap-security-guide provides the datastream content for each distribution.

    If you also need to scan container images, install openscap-utils (which provides oscap-podman).

    SSG installs content under a fixed directory:

    List available datastream files
    $ ls /usr/share/xml/scap/ssg/content/

    Each distribution has its own datastream file. Choosing the wrong one leads to mismatched rules, so match yours up first:

    DistributionDatastream file
    RHEL 9ssg-rhel9-ds.xml
    CentOS Stream 9ssg-cs9-ds.xml
    AlmaLinux 9ssg-almalinux9-ds.xml
    Rocky Linux 9ssg-rl9-ds.xml
    RHEL 10ssg-rhel10-ds.xml

    A single datastream contains multiple profiles, each corresponding to a compliance standard. First, see which ones are available:

    View datastream info and the profile list
    $ oscap info /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

    The Profiles: section of the output lists the title and ID of each profile, similar to:

    Profiles:
    Title: CIS Red Hat Enterprise Linux 9 Benchmark for Level 2 - Server
    Id: xccdf_org.ssgproject.content_profile_cis
    Title: DISA STIG for Red Hat Enterprise Linux 9
    Id: xccdf_org.ssgproject.content_profile_stig
    Title: PCI-DSS v4 Control Baseline for Red Hat Enterprise Linux 9
    Id: xccdf_org.ssgproject.content_profile_pci-dss

    That xccdf_org.ssgproject.content_profile_... is the profile ID you will use in later commands.

    Common profiles:

    StandardDescription
    CISCIS Benchmark, with Level 1/Level 2 and Server/Workstation variants
    DISA STIGThe U.S. Department of Defense Security Technical Implementation Guide, the strictest
    PCI-DSSPayment Card Industry Data Security Standard
    HIPAAU.S. healthcare information protection
    ANSSI-BP-028The French national cybersecurity agency baseline, with minimal/intermediary/enhanced/high levels
    CUSPA general-purpose baseline introduced in EL 10, positioned as a moderate, universal starting point (take the exact name and profile ID from oscap info, not from second-hand articles)

    Once you have your datastream and profile ID, run an evaluation scan:

    Scan the system and generate a report
    $ sudo oscap xccdf eval \
    --profile xccdf_org.ssgproject.content_profile_cis \
    --results scan-results.xml \
    --report report.html \
    /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

    Parameter notes:

    • --profile: the profile ID to apply.
    • --results: saves the machine-readable XML results (needed later to generate remediation scripts).
    • --report: generates a human-readable HTML report.

    When the scan finishes, open report.html in a browser to see each rule’s pass status, severity, and remediation advice.

    Each rule in the report has a result status:

    StatusMeaning
    passPassed, compliant with the baseline
    failFailed, needs remediation
    notapplicableNot applicable (e.g., the rule targets software that is not installed)
    notchecked / errorNot checked or the check errored

    Remediate in order of severity: handle high first, then medium, then low. The summary chart at the top of the report lets you quickly see the distribution of failures. Do not chase 100% pass — some rules may conflict with your business needs (for example, disabling a service you actually use); such items need manual evaluation and a documented exception.

    OpenSCAP can automatically bring failing items into compliance, in two ways.

    Apply remediation in the same pass as the scan:

    Scan and remediate immediately (high risk)
    $ sudo oscap xccdf eval \
    --profile xccdf_org.ssgproject.content_profile_cis \
    --remediate \
    --results scan-results.xml \
    --report report.html \
    /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

    This is the fastest but least controllable approach; only recommended for throwaway test environments.

    After remediation, scan again and compare whether the fail count dropped to confirm the changes took effect.

    If you use Kickstart for automated installs, you can bring the system into compliance during installation and skip remediation afterward. Anaconda provides the org_fedora_oscap addon:

    OSCAP addon snippet in Kickstart
    %addon org_fedora_oscap
    content-type = scap-security-guide
    profile = xccdf_org.ssgproject.content_profile_cis
    %end

    The installer applies the specified profile during provisioning, so a new machine is already hardened on first boot. This is a common practice for keeping baselines consistent across large-scale deployments.

    Compliance is not only about the host — container images need checking too. After installing openscap-utils, use oscap-podman to scan an image directly (without starting a container):

    Scan a container image
    $ sudo oscap-podman registry.access.redhat.com/ubi9/ubi:latest \
    xccdf eval \
    --profile xccdf_org.ssgproject.content_profile_cis \
    --report container-report.html \
    /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

    Put this step in your CI pipeline to block non-compliant builds before an image is published.

    Compliance is not a one-time thing — configuration drifts over time. Use a systemd timer to scan periodically and archive the reports so you can continuously track system state.

    1. Write a scan script that archives reports by date:

      /usr/local/sbin/compliance-scan.sh
      $ sudo tee /usr/local/sbin/compliance-scan.sh <<'EOF'
      #!/bin/bash
      set -euo pipefail
      DS=/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
      PROFILE=xccdf_org.ssgproject.content_profile_cis
      OUT=/var/log/compliance
      DATE=$(date +%Y%m%d)
      mkdir -p "$OUT"
      oscap xccdf eval --profile "$PROFILE" \
      --results "$OUT/results-$DATE.xml" \
      --report "$OUT/report-$DATE.html" \
      "$DS" || true
      EOF
      $ sudo chmod +x /usr/local/sbin/compliance-scan.sh

      The trailing || true prevents the non-zero exit code from rule failures from marking the timer as failed.

    2. Create the service and timer units to run it weekly. See Timers for the exact syntax.

    If /usr/share/xml/scap/ssg/content/ is empty or missing, the baseline content package is not installed:

    Terminal window
    $ sudo dnf install scap-security-guide

    Note that it and openscap-scanner are two different packages — installing the scanner does not install the content.

    The profile ID is that xccdf_org.ssgproject.content_profile_... string, not the human-readable title. Use oscap info <datastream> to view the full list and copy the Id: value.

    A full scan runs through hundreds of OVAL checks and can take several minutes on slow disks or resource-constrained machines, which is normal. If you only want to validate a few rules, use --rule <rule_id> to run just the specified rules, which is much faster.

    This is exactly why “test on a snapshot first” is emphasized repeatedly. If a production system is already broken: rolling back from a VM snapshot or backup is the most reliable fix. So before running --remediate, always confirm you have a restore point to roll back to.