fix: single-source the tracked XCCDF path and version

Summary

Part of #3 (M2: Initial capability release), whose exit criteria include "The tracked STIG release's path and version are single-sourced in the repository." See the plan epic at &1.

The Extensible Configuration Checklist Description Format (XCCDF) filename and the Security Technical Implementation Guide (STIG) release it encodes required hand-edits in five places for every new benchmark. This merge request collapses those to one Python constant and two matching glob patterns, and fixes the exported checklist file (CKL) reporting a stale version regardless of which XCCDF actually ran.

Hand-edit points found

Before this change, the filename U_ASD_STIG_V6R4_Manual-xccdf.xml (or the V6R4 string it encodes) had to be edited in the following locations for every new STIG release:

  • stig_tools/stig_ai_analyzer.py:34, a Python default for the XCCDF_FILE environment variable
  • stig_tools/generate_batch_pipeline.py:14, an identical Python default
  • templates/stig-compliance-analysis.yml:38, the CI/CD component's xccdf_file input default
  • .gitlab-ci.yml:195-196 and :202-203, two rules:changes blocks in the deployer image build job, keyed to the exact filename
  • .gitlab-ci.yml:518 and :654, two test job XCCDF_FILE overrides that duplicated the Python default with no effect
  • aws/Dockerfile:42, the STIG Manager deployer's COPY source

Two further occurrences were found and intentionally left out of scope:

  • .gitlab/duo/flows/stig.yaml, a Duo Flow definition never wired into any pipeline (unmodified since the initial commit); editing it would maintain a dead code path
  • tests/test_remediation_planner.py, where V6R4 is an expected output of the generic version-parsing logic under test, not a reference to the deployed XCCDF

Descriptive V6R4 mentions in README.md, docs/FEATURES.md, docs/INPUTS.md, STIGMAN_DEPLOYMENT.md, and two SVG diagrams were also left unchanged, since they describe the current default rather than a point that breaks on a version bump.

Approach

stig_tools/ckl_parser.py gains a shared default and three functions for reading the benchmark identity out of an XCCDF file and writing it into a checklist's STIG_INFO block:

  • DEFAULT_XCCDF_FILENAME and default_xccdf_path() replace the two duplicated Python literals
  • xccdf_benchmark_fields() extracts title, version, release information, and filename from an already-parsed XCCDF root
  • read_stig_info_fields() and apply_stig_info_fields() read and overwrite a checklist's STIG_INFO SI_DATA pairs

stig_tools/stig_ai_analyzer.py and stig_tools/generate_batch_pipeline.py both import ckl_parser.default_xccdf_path() instead of repeating the filename. Since YAML and Dockerfile syntax cannot dereference a Python constant, .gitlab-ci.yml's two rules:changes blocks now match stig_tools/U_ASD_STIG_*-xccdf.xml and stig_tools/sample_ASD_STIG_*_full.ckl, and aws/Dockerfile copies the same glob before renaming it to the stable asd-xccdf.xml name the uploader already expects. The two redundant .gitlab-ci.yml test overrides, which duplicated the Python default with no effect, are removed.

The CI/CD component's xccdf_file input default was already the only literal on the YAML side (jobs dereference $[[ inputs.xccdf_file ]]), so templates/stig-compliance-analysis.yml is unchanged.

Checklist version defect

The exported checklist's STIG_INFO block (title, version, release information) was copied verbatim from the .ckl template and never refreshed, so it always reported V6R4 even when a different XCCDF had been analyzed. stig_ai_analyzer.py now captures the benchmark fields from the parsed XCCDF and applies them to the output checklist before writing it. aggregate_results.py, which never receives the XCCDF file itself in parallel batch mode, carries the same fields forward from the first batch checklist it reads instead of adding new job-variable plumbing.

Local testing

  • python3 -m unittest discover -s tests -p "test_ai_*.py" -v: 46 tests, pass
  • python3 -m unittest discover -s tests -p "test_remediat*.py" -v: 64 tests, pass (includes 11 new tests pinning the STIG_INFO benchmark-stamping behavior added during review)
  • python3 -m unittest discover -s tests -p "test_rate_*.py" -v: 9 tests, pass
  • glab ci lint .gitlab-ci.yml: valid
  • Manually verified ckl_parser.xccdf_benchmark_fields() and apply_stig_info_fields() against the bundled XCCDF and checklist template, including a simulated V6R4 to V6R5 version bump confirming the derived checklist version changes accordingly
  • Ran generate_batch_pipeline.py directly with the new shared default and confirmed it still resolves the bundled XCCDF and generates a correct batch pipeline

The aws/Dockerfile wildcard COPY was build-tested with podman: a single matching XCCDF builds successfully and the image carries exactly /opt/stigman/fixtures/asd-xccdf.xml; two matching files fail the build at the mv step and zero matches fail at COPY. Over-match and under-match both fail closed, and CI's own build_deployer_image job passes on this branch.

  • Epic: &1
  • Milestone tracker: #3 (M2: Initial capability release). Chosen over #4 (M3) because #3's checklist item "The tracked STIG release's path and version are single-sourced in the repository" is a verbatim match for this fix; #4's checklist (evaluation corpus, heartbeat pipeline, architecture decision record) is unrelated.
Edited by Andrew Dunn

Merge request reports

Loading
Loading