Skip to content

CMP-4283: Enable all XCCDF groups when TP extends a profile#1199

Open
yuumasato wants to merge 4 commits into
ComplianceAsCode:masterfrom
yuumasato:enable-all-xccdf-groups-when-TP-extends
Open

CMP-4283: Enable all XCCDF groups when TP extends a profile#1199
yuumasato wants to merge 4 commits into
ComplianceAsCode:masterfrom
yuumasato:enable-all-xccdf-groups-when-TP-extends

Conversation

@yuumasato
Copy link
Copy Markdown
Member

@yuumasato yuumasato commented Apr 30, 2026

Keep track of all XCCDF Groups in the ProfileBundle and always enable them when a TailoredProfile extends a Profile.

This ensures that any rule that is enabled has its parent Group enabled as well, ensuring that OpenSCAP can get to the rule that was enbled.

If a TailoredProfile enables a rule that is not part of an XCCDF group enabled by the extended profile, the rule won't be enabled at all by OpenSCAP. This is because data stream traversal will stop at the disabled group.

Issue discovered when testing ComplianceAsCode/content#14665

  • Add tests for a TP with extends and rules out of the extended profile's enabled groups.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Apr 30, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: yuumasato

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@yuumasato
Copy link
Copy Markdown
Member Author

The ProfileBundle ends up looking like this:

apiVersion: compliance.openshift.io/v1alpha1
kind: ProfileBundle
metadata:
  annotations:
    compliance.openshift.io/xccdf-groups: xccdf_org.ssgproject.content_group_openshift,xccdf_org.ssgproject.content_group_integrity,xccdf_org.ssgproject.content_group_crypto,xccdf_org.ssgproject.content_group_accounts,xccdf_org.ssgproject.content_group_api-server,xccdf_org.ssgproject.content_group_authentication,xccdf_org.ssgproject.content_group_confinement,xccdf_org.ssgproject.content_group_controller,xccdf_org.ssgproject.content_group_etcd,xccdf_org.ssgproject.content_group_general,xccdf_org.ssgproject.content_group_high-availability,xccdf_org.ssgproject.content_group_kubelet,xccdf_org.ssgproject.content_group_logging,xccdf_org.ssgproject.content_group_master,xccdf_org.ssgproject.content_group_networking,xccdf_org.ssgproject.content_group_openshift-api-server,xccdf_org.ssgproject.content_group_rbac,xccdf_org.ssgproject.content_group_registry,xccdf_org.ssgproject.content_group_risk-assessment,xccdf_org.ssgproject.content_group_scc,xccdf_org.ssgproject.content_group_scheduler,xccdf_org.ssgproject.content_group_secrets,xccdf_org.ssgproject.content_group_worker
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"compliance.openshift.io/v1alpha1","kind":"ProfileBundle","metadata":{"annotations":{},"name":"upstream-ocp4","namespace":"openshift-compliance"},"spec":{"contentFile":"ssg-ocp4-ds.xml","contentImage":"openscap-ocp4-ds:latest"}}
  creationTimestamp: "2026-04-30T23:40:49Z"
  finalizers:
  - profilebundle.finalizers.compliance.openshift.io
  generation: 1
  name: upstream-ocp4
  namespace: openshift-compliance
  resourceVersion: "104608"
  uid: a502564d-d947-4187-a72a-d030d8223c12
spec:
  contentFile: ssg-ocp4-ds.xml
  contentImage: openscap-ocp4-ds:latest
status:
  conditions:
  - lastTransitionTime: "2026-04-30T23:41:04Z"
    message: Profile bundle successfully parsed
    reason: Valid
    status: "True"
    type: Ready
  dataStreamStatus: VALID

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

🤖 To deploy this PR, run the following command:

make catalog-deploy CATALOG_IMG=ghcr.io/complianceascode/compliance-operator-catalog:1199-564c3e0416ca3abcc61729bde6ec3f429a20d6a7

Copy link
Copy Markdown

@sebrandon1 sebrandon1 left a comment

Choose a reason for hiding this comment

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

Just some comments.

Comment thread pkg/xccdf/tailoring.go
Comment thread pkg/profileparser/profileparser.go Outdated
pb.SetAnnotations(annotations)

// Update the ProfileBundle with the new annotation
if err := pcfg.Client.Update(context.TODO(), pb); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should this be Patch to avoid updating the entire object?

@yuumasato yuumasato changed the title Enable all XCCDF groups when TP extends a profile CMP-4283: Enable all XCCDF groups when TP extends a profile May 21, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Collaborator

@yuumasato: This pull request references CMP-4283 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Keep track of all XCCDF Groups in the ProfileBundle and always enable them when a TailoredProfile extends a Profile.

This ensures that any rule that is enabled has its parent Group enabled as well, ensuring that OpenSCAP can get to the rule that was enbled.

If a TailoredProfile enables a rule that is not part of an XCCDF group enabled by the extended profile, the rule won't be enabled at all by OpenSCAP. This is because data stream traversal will stop at the disabled group.

Issue discovered when testing ComplianceAsCode/content#14665

  • Add tests for a TP with extends and rules out of the extended profile's enabled groups.

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 openshift-eng/jira-lifecycle-plugin repository.

@yuumasato yuumasato force-pushed the enable-all-xccdf-groups-when-TP-extends branch from 564c3e0 to 165141d Compare May 27, 2026 22:33
// Extract all XCCDF Group IDs from the datastream and store in ProfileBundle annotation
if err := extractAndStoreXCCDFGroups(contentDom, pb, pcfg); err != nil {
log.Error(err, "Failed to extract XCCDF groups")
// Don't fail the whole parse if group extraction fails
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we surface this error in case the user needs to use those rules, and fail the bundle as an error state? or if we do not want to fail entire profilebundle we could in TailoredProfileToXML, if the annotation is missing AND the TP extends a profile, enable groups based on a query of the live datastream or a sentinel "enable all groups" wildcard.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We could have have the ProfileBundle in error state.

Another alternative is to have the tailoring controller extract the groups at creation time, rather than Profile Bundle creation.
That would avoid us having the annotation in PB.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think I prefer the current approach, with an annotation in the ProfileBundle.

Copy link
Copy Markdown

@Vincent056 Vincent056 left a comment

Choose a reason for hiding this comment

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

I think the PR looks good, do you think you could add a unit test to test the parser and also e2e tests for a TP with extends and rules out of the extended profile's enabled groups?

@yuumasato yuumasato force-pushed the enable-all-xccdf-groups-when-TP-extends branch from 165141d to 9f3feac Compare May 29, 2026 16:16
@github-actions
Copy link
Copy Markdown

🤖 To deploy this PR, run the following command:

make catalog-deploy CATALOG_IMG=ghcr.io/complianceascode/compliance-operator-catalog:1199-9f3feacef992691f8a4f601123ddcebb7282613e

@Anna-Koudelkova
Copy link
Copy Markdown
Collaborator

Verification failed with the compliance operator deployed using the image from the PR on OCP 4.22:

Verification steps:

  1. Deploy compliance operator from the PR
$ make catalog-deploy CATALOG_IMG=ghcr.io/complianceascode/compliance-operator-catalog:1199-9f3feacef992691f8a4f601123ddcebb7282613e

$ oc get csv
NAME                             DISPLAY               VERSION     RELEASE   REPLACES   PHASE
compliance-operator.v1.8.0-dev   Compliance Operator   1.8.0-dev                        Succeeded
  1. Checkout the PR CMP-4248 added compliance checks content#14665 and build its content to a profile bundle:
$ oc get pb
NAME              CONTENTIMAGE                                 CONTENTFILE         CELCONTENTFILE   STATUS
ocp4              ghcr.io/complianceascode/k8scontent:latest   ssg-ocp4-ds.xml                      VALID
rhcos4            ghcr.io/complianceascode/k8scontent:latest   ssg-rhcos4-ds.xml                    VALID
upstream-ocp4     openscap-ocp4-ds:latest                      ssg-ocp4-ds.xml                      VALID
upstream-rhcos4   openscap-ocp4-ds:latest                      ssg-rhcos4-ds.xml                    VALID
  1. Create a Tailored profile using this yaml file:
apiVersion: compliance.openshift.io/v1alpha1
kind: TailoredProfile
metadata:
  annotations:
    compliance.openshift.io/product-type: Node
  name: test-profile-extension-rules
  namespace: openshift-compliance
spec:
  extends: upstream-rhcos4-moderate
  description: Testing custom package removal and configuration rules
  title: Test Custom Rules
  enableRules:
    - name: upstream-rhcos4-chronyd-specify-remote-server
      rationale: "Test chronyd remote server configuration"
    - name: upstream-rhcos4-kerberos-disable-no-keytab
      rationale: "Test rule only in default.profile"
      
$ oc get tp
NAME                           STATE
test-profile-extension-rules   READY
  1. Create a ssb with said tp and wait for the suite to reach the DONE phase
$ oc compliance bind -N test tailoredprofile/test-profile-extension-rules
Creating ScanSettingBinding test

$ oc get suite -w
NAME   PHASE     RESULT
test   RUNNING   NOT-AVAILABLE
test   RUNNING   NOT-AVAILABLE
test   RUNNING   NOT-AVAILABLE
test   AGGREGATING   NOT-AVAILABLE
test   DONE          NON-COMPLIANT
  1. Check the ccrs. Upstream rhcos4-moderate as well as both rules should have ccrs created.
$ oc get ccr | head -10
NAME                                                                                                             STATUS   SEVERITY
test-profile-extension-rules-master-accounts-no-uid-except-zero                                                  PASS     high
test-profile-extension-rules-master-audit-rules-dac-modification-chmod                                           FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-chown                                           FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fchmod                                          FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fchmodat                                        FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fchown                                          FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fchownat                                        FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fremovexattr                                    FAIL     medium
test-profile-extension-rules-master-audit-rules-dac-modification-fsetxattr                                       FAIL     medium

$ oc get ccr | grep chronyd-specify-remote-server
test-profile-extension-rules-master-chronyd-specify-remote-server                                                PASS     medium
test-profile-extension-rules-worker-chronyd-specify-remote-server                                                PASS     medium

$ oc get ccr | grep kerberos-disable-no-keytab

--> There is no ccr for rule upstream-rhcos4-kerberos-disable-no-keytab. The rule object itself exists on the cluster:

$ oc get rules |grep upstream-rhcos4-kerberos-disable-no-keytab
upstream-rhcos4-kerberos-disable-no-keytab                                                   90m

@yuumasato yuumasato force-pushed the enable-all-xccdf-groups-when-TP-extends branch from 9f3feac to 31da5ee Compare June 2, 2026 10:44
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

🤖 To deploy this PR, run the following command:

make catalog-deploy CATALOG_IMG=ghcr.io/complianceascode/compliance-operator-catalog:1199-31da5ee27679fefb692d2e44b7e8bb620ae30efe

@Anna-Koudelkova
Copy link
Copy Markdown
Collaborator

Anna-Koudelkova commented Jun 2, 2026

Pre-merge verification PASS on OCP 4.22 + CO installed from this PR. ✔️

Premerge verification steps:

  1. Install CO from this image ghcr.io/complianceascode/compliance-operator-catalog:1199-31da5ee27679fefb692d2e44b7e8bb620ae30efe
  2. Create a tailored profile:
apiVersion: compliance.openshift.io/v1alpha1
kind: TailoredProfile
metadata:
  annotations:
    compliance.openshift.io/product-type: Node
  name: test-profile-extension-rules
  namespace: openshift-compliance
spec:
  extends: rhcos4-moderate
  description: Testing custom package removal and configuration rules
  title: Test Custom Rules
  enableRules:
    - name: rhcos4-chronyd-specify-remote-server
      rationale: "Test chronyd remote server configuration"
    - name: rhcos4-ssh-client-rekey-limit
      rationale: "Test rule only in default.profile"
  1. Create ssb with the tailored profile and default scansetting
  2. Wait for the suite to reach DONE phase and check the ccr has been generated for both rules
$ oc get ccr | grep ssh-client-rekey-limit
test-profile-extension-rules-master-ssh-client-rekey-limit                                                       FAIL     medium
test-profile-extension-rules-worker-ssh-client-rekey-limit                                                       FAIL     medium

$ oc get ccr | grep chronyd-specify-remote-server 
test-profile-extension-rules-master-chronyd-specify-remote-server                                                PASS     medium
test-profile-extension-rules-worker-chronyd-specify-remote-server                                                PASS     medium

Bonus step: Both profilebundles have metadata annotations:

$ oc get pb ocp4 -ojsonpath='{.metadata.annotations}'
{"compliance.openshift.io/xccdf-groups":"xccdf_org.ssgproject.content_group_openshift,xccdf_org.ssgproject.content_group_integrity,xccdf_org.ssgproject.content_group_crypto,xccdf_org.ssgproject.content_group_accounts,xccdf_org.ssgproject.content_group_api-server,xccdf_org.ssgproject.content_group_authentication,xccdf_org.ssgproject.content_group_confinement,xccdf_org.ssgproject.content_group_controller,xccdf_org.ssgproject.content_group_etcd,xccdf_org.ssgproject.content_group_general,xccdf_org.ssgproject.content_group_high-availability,xccdf_org.ssgproject.content_group_kubelet,xccdf_org.ssgproject.content_group_logging,xccdf_org.ssgproject.content_group_master,xccdf_org.ssgproject.content_group_networking,xccdf_org.ssgproject.content_group_openshift-api-server,xccdf_org.ssgproject.content_group_rbac,xccdf_org.ssgproject.content_group_registry,xccdf_org.ssgproject.content_group_risk-assessment,xccdf_org.ssgproject.content_group_scc,xccdf_org.ssgproject.content_group_scheduler,xccdf_org.ssgproject.content_group_secrets,xccdf_org.ssgproject.content_group_worker"}

$ oc get pb rhcos4 -ojsonpath='{.metadata.annotations}'
{"compliance.openshift.io/xccdf-groups":"xccdf_org.ssgproject.content_group_system,xccdf_org.ssgproject.content_group_software,xccdf_org.ssgproject.content_group_integrity,xccdf_org.ssgproject.content_group_software-integrity,xccdf_org.ssgproject.content_group_rpm_verification,xccdf_org.ssgproject.content_group_aide,xccdf_org.ssgproject.content_group_fips,xccdf_org.ssgproject.content_group_crypto,xccdf_org.ssgproject.content_group_certified-vendor,xccdf_org.ssgproject.content_group_endpoint_security_software,xccdf_org.ssgproject.content_group_mcafee_security_software,xccdf_org.ssgproject.content_group_mcafee_hbss_software,xccdf_org.ssgproject.content_group_disk_partitioning,...
[shortened}

@yuumasato
Copy link
Copy Markdown
Member Author

@Vincent056 unit and e2e tests were added.

yuumasato added 4 commits June 3, 2026 14:45
Keep track of all XCCDF Groups in the ProfileBundle and always enable
them when a TailoredProfile extends a Profile.

This ensures that any rule that is enabled has its parent Group enabled
as well, ensuring that OpenSCAP can get to the rule that was enbled.
@yuumasato yuumasato force-pushed the enable-all-xccdf-groups-when-TP-extends branch from 31da5ee to e3757b9 Compare June 3, 2026 12:46
@yuumasato
Copy link
Copy Markdown
Member Author

Also rebased to pick up on #1215

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

🤖 To deploy this PR, run the following command:

make catalog-deploy CATALOG_IMG=ghcr.io/complianceascode/compliance-operator-catalog:1199-e3757b954fdcb56d35eac046684455e4e86c6af9

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Jun 3, 2026

@yuumasato: 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/e2e-aws-parallel-arm 31da5ee link true /test e2e-aws-parallel-arm
ci/prow/e2e-aws-serial-arm 31da5ee link true /test e2e-aws-serial-arm
ci/prow/e2e-aws-serial 31da5ee link true /test e2e-aws-serial
ci/prow/e2e-aws-parallel 31da5ee link true /test e2e-aws-parallel
ci/prow/e2e-rosa e3757b9 link true /test e2e-rosa

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants