Skip to content

Profile Resolution Incorrect Duplicate Control Handling #271

@brian-ruf

Description

@brian-ruf

Describe the bug

When attempting to apply a profile representing an overlay onto a profile representing a baseline, duplicate controls are created even when the "use-first" merge directive is present and regardless of whether the "as-is" or "flat" directive is used.

There are several issues in play here, including an under-specification for how duplicate groups are handled in the NIST OSCAL profile syntax and profile resolution specification (See issue usnistgov/OSCAL#2231); however, profile-resolution tools should at least check for duplicate controls regardless of their group or origin and handle per the specified merge directive.

Who is the bug affecting

Anyone attempting to perform profile resolution involving control overlays.

How do we replicate this issue

  1. Clone the NIST OSCAL Content repository
  2. Put this profile (below) in the same folder as the 800-53r5 XML catalog and profiles.
  3. Use the OSCAL-CLI to resolve the profile
  4. Change 'as-is' to flat
  5. Re-run the OSCAL-CLI to resolve the profile
  6. In both 3 and 5, observe ID duplication errors in spite of the use-first directive.
<?xml version="1.0" encoding="UTF-8"?>
<profile xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="dbbd571b-fa8d-47e9-a33b-e06e730d252c">
   <metadata>
      <title>High Baseline and Privacy Overlay</title>
      <last-modified>2026-05-12T00:00:00Z</last-modified>
      <version>1.0.0</version>
      <oscal-version>1.2.1</oscal-version>
      <remarks><p>Use this to apply the privacy overlay to the High baseline.</p></remarks>
   </metadata>
   <import href="NIST_SP-800-53_rev5_HIGH-baseline_profile.xml">
      <include-all/>
   </import>
   <import href="NIST_SP-800-53_rev5_PRIVACY-baseline_profile.xml">
      <include-all/>
   </import>
   <merge>
      <combine method="use-first"/>
      <as-is>true</as-is>
   </merge>
</profile>

Expected behavior (i.e. solution)

For step 5, there should be one version of each control and all controls should be at the root with no groups. There should be no duplicates.

For step 3, the expected behavior is ambiguous due to the under-specification of handling for duplicate group IDs; however, I would still expect the control duplication to be caught and handled IAW the merge directive (first-use) and the second instance gets dropped.

Other comments

Until NIST properly addresses collision of group IDs, I would like to suggest ...

Group ID collisions honor the control ID merge directives.

  • "keep" both groups are kept.

    • "as-is" controls stay with their respective parent group, and duplicate controls in the different parents are retained.
  • "use-first", the title, props and other content of the first group is retained and any subsequent group with the same ID is ignored.

    • "as-is" controls stay with their respective parent group based strictly on group ID, which results in controls from the group with the duplicate ID being merged in with the controls from the first group.
    • duplicate control IDs follow the "use-first" directive regardless of whether they are in the same group, a different group, or at the root.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    To Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions