Skip to content

NIST Controls Assessment SKILL (plus rule to variable mapping)#14824

Open
ggbecker wants to merge 4 commits into
ComplianceAsCode:masterfrom
ggbecker:nist-group-enhancements-assess-skill
Open

NIST Controls Assessment SKILL (plus rule to variable mapping)#14824
ggbecker wants to merge 4 commits into
ComplianceAsCode:masterfrom
ggbecker:nist-group-enhancements-assess-skill

Conversation

@ggbecker

@ggbecker ggbecker commented Jun 24, 2026

Copy link
Copy Markdown
Member

Description:

  • Add assess-nist-control Claude Code skill: OSCAL enrichment, CIS reverse lookup, automatability classification, rule selection, variable resolution, and YAML write-back for pending NIST 800-53 Rev 5 controls — base control and enhancements as a single unit.
  • Add resolve-rule-variables sub-skill: looks up XCCDF variable dependencies from build/<product>/rule_variable_mapping.json, reads .var files, and collects var_name=key selections interactively. Called by assess-nist-control; also usable standalone.
  • Add build-scripts/extract_rule_variable_mapping.py and CMake wiring to generate rule_variable_mapping.json at build time, mapping each rule ID to the XCCDF external variables it depends on.

Rationale:

  • Completing the NIST 800-53 backlog for RHEL products is a sustained effort with ~1,150 pending controls across 20 families. Manual assessment requires juggling the OSCAL catalog, the CIS mapping data, grep across thousands of rule files, and YAML edits — error-prone and slow. These skills encode that workflow so authors can work through controls in a focused session without context-switching between tools.
  • Extracting variable resolution into its own sub-skill (resolve-rule-variables) keeps the concern isolated: the key-vs-value distinction, .var file lookup, deduplication across rules sharing a variable, and the planned future migration to a per-product variables file are all handled in one place.

Review Hints:

  • Build the RHEL 9 product and run the skill /assess-nist-control ia-5 --product rhel9, this will trigger an assessment of the control which also contains the variable selections invocation.

@ggbecker ggbecker changed the title Nist group enhancements assess skill NIST Controls Assessment SKILL (plus rule to variable mapping) Jun 24, 2026
@ggbecker ggbecker force-pushed the nist-group-enhancements-assess-skill branch from f39837a to 4512f84 Compare June 24, 2026 14:03
ggbecker added 2 commits June 24, 2026 17:41
Adds extract_rule_variable_mapping.py which scans per-rule OVAL XML
files in build/<product>/checks/oval/ and checks_from_templates/oval/
to produce build/<product>/rule_variable_mapping.json — a mapping of
each rule ID to the XCCDF external variables it depends on.

The script is wired into the CMake build via ssg_extract_rule_variable_mapping()
and runs as part of every product build after OVAL compilation.

Adds test_profile_variables.py which validates that every profile selects
all variables required by the rules it includes, warning when a rule's
variable dependency would silently fall back to the .var file default.
@ggbecker ggbecker force-pushed the nist-group-enhancements-assess-skill branch from 4512f84 to 8d058bb Compare June 24, 2026 15:59
@ggbecker ggbecker added this to the 0.1.82 milestone Jun 29, 2026
@Mab879 Mab879 self-assigned this Jul 7, 2026

# Process regular OVAL checks
if checks_dir.exists():
# print(f"Processing OVAL checks in {checks_dir}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this


# Process template-generated OVAL checks
if templates_dir.exists():
# print(f"Processing template OVAL checks in {templates_dir}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this

# Convert sets to sorted lists for JSON serialization
result = {rule_id: sorted(list(var_ids)) for rule_id, var_ids in all_mappings.items()}

# print(f"Found {len(result)} rules with variable dependencies")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this

with open(output_file, 'w', encoding='utf-8') as f:
json.dump(mapping, f, indent=2, sort_keys=True)

# print(f"Rule-variable mapping written to {output_file}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this


# print(f"Rule-variable mapping written to {output_file}")

return 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script always returns 0, do want to do this for now, then later we can enforce this?

"""
# Find all variable references via var_ref attributes
var_refs = set()
var_ref_pattern = r'var_ref="([^"]+)"'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review this finding from the Automated review

File: build-scripts/extract_rule_variable_mapping.py:125
Severity: Low-to-medium — affects a small number of rules but the gap is real.
The extract_variables_from_oval_content function only captures variable references via the var_ref="..." attribute pattern (line 125: r'var_ref="([^"]+)"'). However, OVAL XML also uses a child element pattern: <ind:var_ref>variable_id</ind:var_ref> inside <ind:variable_object> elements.
This element pattern appears in ~5,592 built OVAL files across all products. Most of those reference local variables (which would be correctly filtered out), but at least 3 external variables (sshd_required, var_network_filtering_service, var_timesync_service) are referenced exclusively via this element pattern. This means rules that depend on these variables will be missing them from the mapping.
The practical impact is limited — sshd_required defaults to "unset" and most profiles don't explicitly set it — but it's a correctness gap. Adding a second regex to capture <ind:var_ref> element text content would close it:
var_ref_element_pattern = r'<(?:ind:)?var_ref>([^<]+)</(?:ind:)?var_ref>'
The existing internal-variable filtering logic would correctly handle the additional captures.

…pping

- Remove four leftover commented-out debug print statements
- Add <ind:var_ref> element text pattern to capture variable references
  that use child element syntax instead of var_ref="..." attribute syntax;
  affects at least sshd_required, var_network_filtering_service, and
  var_timesync_service which are referenced exclusively this way
- Document the intentional always-zero exit code so build failures in
  individual OVAL files (logged as warnings) don't break the overall build
@Mab879

Mab879 commented Jul 8, 2026

Copy link
Copy Markdown
Member

That rpm-build CI fail looks valid.

Thread an error count from process_oval_file through
build_rule_variable_mapping to main(), and return 1 if any OVAL files
could not be read. Validated against a full build of all 38 products —
zero errors reported.
@ggbecker ggbecker force-pushed the nist-group-enhancements-assess-skill branch from e126d80 to 0218538 Compare July 9, 2026 12:22
@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown

@ggbecker: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/4.20-images 0218538 link true /test 4.20-images
ci/prow/e2e-aws-openshift-platform-compliance 0218538 link true /test e2e-aws-openshift-platform-compliance
ci/prow/e2e-aws-openshift-node-compliance 0218538 link true /test e2e-aws-openshift-node-compliance

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants