Skip to content

Catalog Metaschema Incorrectly Restricts Guidance Children #2118

Open
@brian-ruf

Description

@brian-ruf

Describe the bug

In an OSCAL catalog, when attempting to create child/descendent parts to //control/part[@name='guidance'], the OSCAL-CLI tool is incorrectly reporting that only part names of assessment-objective or objective are allowed.

NOTE: This was discovered while attempting to validate the Cloud Security Alliance's Cloud Controls Matrix (CCM) OSCAL Catalog, where they have guidance constructs as follows:

    <control id="A_A-01" class="control">
      <title>Audit and Assurance Policy and Procedures</title>
      <prop name="label" value="A&amp;A-01"/>
      <part id="A_A-01_stm" name="statement">
          <p>Content detail removed for brevity</p>
      </part>

      <part id="A_A-01_imp_gui" name="guidance">
        <part id="A_A-01_imp_gui_csp" name="item">
          <title>CSP implementation guidelines</title>
          <prop name="label" value="CSP"/>
          <p>Content detail removed for brevity</p>
        </part>
        <part id="A_A-01_imp_gui_csc" name="item">
          <title>CSC implementation guidelines</title>
          <prop name="label" value="CSC"/>
          <p>Content detail removed for brevity</p>
        </part>
      </part>
   </control>

Who is the bug affecting

Catalog authors who need to break guidance down into more discrete parts than just the top-level guidance.

What is affected by this bug

Metaschema

How do we replicate this issue

  1. Create an OSCAL catalog with controls that have guidance. (//control/part[@name='guidance'])
  2. Add a child part to guidance with an appropriate name. (NOTE OSCAL documentation is silent on this; however, there is precedence for using part names of either guidance or item).
  3. Run the latest OSCAL-CLI tool (tested with version 2.4.0)
  4. observe the following error(s):
    [ERROR] [/catalog/group[1]/control[1]/part[2]/part[1]/@name] Value 'item' doesn't match one of 'assessment-objective or objective' at path '/catalog/group[1]/control[1]/part[2]/part[1]/@name'

NOTE: The only reason I am not suggesting you test with the CCM is that they also have an invalid control property name that needs to be moved to their own namespace. The bug being reported in this issue is not discovered/reported by the OSCAL-CLI until after the property namespace issued is resolved.

Expected behavior (i.e. solution)

While it is unclear exactly what should be allowed as child/descendent parts to guidance, it should definitely not be assessment-objective or objective.

Other comments

This is the metaschema code responsible:

<allowed-values
target=".//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name">
<enum value="objective" deprecated="1.0.1">**(deprecated)** Use
'assessment-objective' instead.</enum>
<enum value="assessment-objective">The part describes a set of assessment
objectives.</enum>
<remarks>
<p>Objectives can be nested.</p>
</remarks>
</allowed-values>

This requires a two-part fix:

  1. Revise the current constraint to only apply to descendants to objective/assessment-objective parts.
  2. Determine the correct part names for decedents of "guidance" parts, and add a new constraint to properly enforce the correct part name.
  • NOTE: If "item" is the correct name, see my recommendation below.

Part 1

(NOTE the context is //control)

                  <allowed-values
                        target=".//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name">
                        <enum value="objective" deprecated="1.0.1">**(deprecated)** Use
                              'assessment-objective' instead.</enum>
                        <enum value="assessment-objective">The part describes a set of assessment
                              objectives.</enum>
                        <remarks>
                              <p>Objectives can be nested.</p>
                        </remarks>
                  </allowed-values>

The target here should be revised to only enforce this constraint for child parts to assessment objectives:
target="./part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment-objective', 'objective')]//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name"


Part 2

If the correct descendent part name to "guidance" parts is "item", the simplest fix is to revise the the following constraint to include "guidance":

<allowed-values
target="part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='statement']//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name">
<enum value="item">An individual item within a control statement.</enum>
<remarks>
<p>Nested statement parts are "item" parts.</p>
</remarks>
</allowed-values>

                  <allowed-values
                        target="part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='statement']//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name">
                        <enum value="item">An individual item within a control statement.</enum>
                        <remarks>
                              <p>Nested statement parts are "item" parts.</p>
                        </remarks>
                  </allowed-values>

The target here should be revised to enforce this constraint for child parts to both statements and guidance:
target="./part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('statement', 'guidance')]//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name"

Revisions

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Needs Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions