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 theXCCDF_FILEenvironment variablestig_tools/generate_batch_pipeline.py:14, an identical Python defaulttemplates/stig-compliance-analysis.yml:38, the CI/CD component'sxccdf_fileinput default.gitlab-ci.yml:195-196and:202-203, tworules:changesblocks in the deployer image build job, keyed to the exact filename.gitlab-ci.yml:518and:654, two test jobXCCDF_FILEoverrides that duplicated the Python default with no effectaws/Dockerfile:42, the STIG Manager deployer'sCOPYsource
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 pathtests/test_remediation_planner.py, whereV6R4is 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_FILENAMEanddefault_xccdf_path()replace the two duplicated Python literalsxccdf_benchmark_fields()extracts title, version, release information, and filename from an already-parsed XCCDF rootread_stig_info_fields()andapply_stig_info_fields()read and overwrite a checklist'sSTIG_INFOSI_DATApairs
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, passpython3 -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, passglab ci lint .gitlab-ci.yml: valid- Manually verified
ckl_parser.xccdf_benchmark_fields()andapply_stig_info_fields()against the bundled XCCDF and checklist template, including a simulatedV6R4toV6R5version bump confirming the derived checklist version changes accordingly - Ran
generate_batch_pipeline.pydirectly 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.
Related
- 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.