# ComplianceAsCode/content: SCAP, Ansible and Bash hardening content from one YAML source

> ComplianceAsCode/content is a build system and content library that turns per-rule YAML into SCAP data streams, Ansible playbooks, Bash fix scripts and CEL YAML for Kubernetes. It suits engineers who must produce auditable hardening content for RHEL, Fedora, Ubuntu, Debian or SLES, and it is a poor fit for anyone wanting a finished scanner.

**ComplianceAsCode/content** — Security automation content in SCAP, Bash, Ansible, and other formats

- Repository: https://github.com/ComplianceAsCode/content
- Website: https://complianceascode.readthedocs.io/en/latest/
- Stars: 2,809 · Forks: 832
- Language: Shell
- License: NOASSERTION
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/complianceascode-content

## The problem ComplianceAsCode/content solves: writing hardening rules once

Most hardening projects end up with the same rule written three or four times. A shell script for the legacy fleet, an Ansible task for the configuration management run, an OVAL check for the auditor, and a separate document for whoever has to explain why the rule exists. Every edit has to be repeated, and the copies drift.

ComplianceAsCode/content attacks that duplication at the source. Rules live as YAML files, and the build system emits the same rule in SCAP (XCCDF, OVAL and SCAP source data streams), Ansible playbooks, Bash fix scripts and, for container platforms, CEL content as YAML for the compliance-operator. Security identifiers such as CCE, NIST ID and STIG are declared once in the YAML and carried into every output format.

The audience is narrow and technical. Distribution maintainers who package scap-security-guide, platform engineers who need a profile for a specific benchmark, and contributors adding rules for a new product. The README is explicit that the project produces content, not a scanner. You still need something that reads a data stream or runs a playbook.

## How the YAML rule format feeds the build system

The input format is OpenControl-inspired YAML. A rule declares a title, a description, a rationale, a severity and an identifiers block. The description can embed Jinja-style expressions, so a value such as MaxKeepAliveRequests is referenced through a variable rather than hard-coded in prose.

The README gives this fragment as the canonical example:

```yaml
title: 'Configure The Number of Allowed Simultaneous Requests'

severity: medium

identifiers:
    cce: "80551-5"
```

Around that YAML sit the artefacts the build system pulls together: OVAL checks, Ansible task snippets and Bash fixes. Templating is applied at each step, which is how one rule ends up as several formats without the author writing each one. The build is driven by CMake, which is why the repository root carries CMakeLists.txt and a cmake/ directory alongside the Python package under ssg/.

Platform awareness is part of the model rather than an afterthought. The README states that platform checks decide whether a rule should be evaluated at all, with separate partition checks given as the example: sensible on bare metal, against recommended practice inside a container. The same content can therefore target bare-metal machines, virtual machines, qcow2 images, containers and container images without the author maintaining separate rule sets.

## Installing ComplianceAsCode content with yum, apt or a release ZIP

The README calls the distribution package manager the preferred installation route. On Red Hat Enterprise Linux and Fedora the package is scap-security-guide:

```bash
yum install scap-security-guide
```

Debian is split by the kind of guide you want, which matters because the package names are not interchangeable:

```bash
apt install ssg-debian  # for Debian guides
apt install ssg-debderived  # for Debian-based distributions (e.g. Ubuntu) guides
apt install ssg-nondebian  # for other distributions guides (RHEL, Fedora, etc.)
apt install ssg-applications  # for application-oriented guides (Firefox, JBoss, etc.)
```

If your distribution does not package it, or the packaged version is too old, the README points at pre-built ZIP archives on the release page. Each ZIP is an archive of ready-made SCAP source data streams, which the README recommends for general use because a data stream contains everything needed to evaluate a machine and bring it into compliance. The most recent release listed is v0.1.82, published on 2026-09-01.

Building from source is the remaining option. The README directs you to the Developer Guide for the build procedure and to make install for installation, and suggests opening an issue on your distribution's bug tracker to register interest. The repository also ships a scap-security-guide.spec file, so an RPM can be produced from the tree. One caveat worth knowing before you start: the version reported by the Python package is derived heuristically from git tags, and pyproject.toml explains that the project tags commits on temporary stabilization branches rather than on master, so a plain git describe does not work here.

## Where ComplianceAsCode/content is the wrong tool

This repository does not scan anything. There is no agent, no scheduler, no dashboard and no report renderer in the tree. If your requirement is a tool that runs a check and hands you a pass or fail list, you are looking at half the pipeline; the consuming scanner is a separate product. The README's Usage section assumes the content has been installed system-wide into a standard location before anything can consume it.

Bash fixes are the second boundary. The README states that Bash fix files are meant to be run on machines to bring them into compliance, but that other formats are recommended, with Bash understood as the only option in some deployment scenarios. Treat a generated Bash script as a fallback, not the default path.

There is also a packaging lag to plan for. The README explicitly anticipates the case where the version in your distribution is too old, and the remedy it offers is to build the content yourself. That means a Python toolchain, CMake and the dependencies listed in requirements.txt, which include lxml, ruamel.yaml, pandas, openpyxl and pcre2. A team that cannot build software will be stuck on whatever version their distribution shipped.

Finally, the licence is not stated in a form you can act on from the repository metadata alone, which reports NOASSERTION. The LICENSE file exists in the tree and is referenced by pyproject.toml, so read it directly rather than assuming terms.

## How ComplianceAsCode differs from a scanner such as OpenSCAP

The nearest thing to a peer is OpenSCAP, and the split is clean. OpenSCAP is the evaluation engine: it consumes an SCAP source data stream and produces results. ComplianceAsCode/content is what produces that data stream. The README recommends SCAP source data streams for general use precisely because they bundle the checks and the remediation into one document that an engine can consume.

That division explains the release artefacts. The ZIP archives on the release page are not tools; they are content. The Ansible playbooks published on Ansible Galaxy are the same rules expressed as tasks that can run in check mode to evaluate or in run mode to remediate. CEL content follows the same pattern for Kubernetes and OpenShift, generating YAML that the compliance-operator evaluates natively, without shell access to nodes.

So the comparison is not which is better. If you already run an SCAP engine, this project supplies its input. If you need an engine, this project will not give you one.

## Maintenance, releases and upgrade cost

The repository is not archived, and the last push was on 2026-09-24. Releases arrive on a roughly quarterly cadence: v0.1.80 on 2026-03-06, v0.1.81 on 2026-06-01 and v0.1.82 on 2026-09-01. Nightly builds are produced by a GitHub Actions workflow, and the README links a nightly ZIP, so there is a channel between releases for anyone who needs a recent rule.

The upgrade cost sits in the content, not the code. Benchmarks are revised, rules are added, identifiers change. If you consume the distribution package, upgrades arrive with the rest of your system packages and you inherit whatever profile changes came with them, which can move a machine from compliant to non-compliant without any action on your part. If you build from source, you own the build environment and the dependency set in requirements.txt, and you will notice that the file mixes runtime needs with tooling such as mypy and cmakelint.

On licensing, pyproject.toml points the license field at the LICENSE file rather than naming an SPDX identifier, and the repository metadata reports NOASSERTION. That is not a conclusion about the terms; it is a reason to read the file before redistributing content in a product.

## Conclusion

Adopt ComplianceAsCode/content if you need to author or maintain security policy content once and emit it as SCAP, Ansible or Bash, and you are willing to build it yourself when the packaged version lags. Skip it if you want a scanner with a user interface; this repository ships content, not the tool that consumes it. Before committing, read the LICENSE file, since the repository metadata reports NOASSERTION, and confirm which product directory under products/ matches your target platform.

## FAQ

### What is ComplianceAsCode/content used for?

It produces security policy content for platforms such as Red Hat Enterprise Linux, Fedora, Ubuntu, Debian and SLES, and for products such as Firefox. The build system turns YAML rule files into SCAP data streams, Ansible playbooks, Bash fix scripts and CEL content for Kubernetes and OpenShift.

### How do I install ComplianceAsCode/content?

The README calls the distribution package manager the preferred route: yum install scap-security-guide on RHEL and Fedora, or the ssg-debian, ssg-debderived, ssg-nondebian and ssg-applications packages on Debian. Pre-built ZIP archives of SCAP source data streams are on the release page, and building from source is documented in the Developer Guide.

### Does ComplianceAsCode/content scan machines by itself?

No. The repository produces content, not an evaluation engine. The README recommends SCAP source data streams for general use because they contain the data needed to evaluate and remediate, which implies a separate tool consumes them.

### Which output formats can ComplianceAsCode/content generate?

SCAP content in XCCDF, OVAL and SCAP source data stream formats, Ansible playbooks published on Ansible Galaxy, Bash fix scripts, and CEL content generated as YAML for Kubernetes and OpenShift through the compliance-operator.

## Sources

- [ComplianceAsCode/content on GitHub](https://github.com/ComplianceAsCode/content)
- [Issues](https://github.com/ComplianceAsCode/content/issues)
- [Project website](https://complianceascode.readthedocs.io/en/latest/)
- [README](https://github.com/ComplianceAsCode/content/blob/master/README.md)
- [Releases](https://github.com/ComplianceAsCode/content/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/complianceascode-content
