Skip to content

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

Open
ggbecker wants to merge 2 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 2 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
@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

@ggbecker: The following test 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/e2e-aws-openshift-node-compliance 8d058bb 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.

@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.

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