Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catalog Metaschema Incorrectly Restricts Guidance Children #2118

Open
brian-ruf opened this issue Mar 3, 2025 · 3 comments
Open

Catalog Metaschema Incorrectly Restricts Guidance Children #2118

brian-ruf opened this issue Mar 3, 2025 · 3 comments
Labels

Comments

@brian-ruf
Copy link
Contributor

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

@xee5ch
Copy link
Contributor

xee5ch commented Mar 3, 2025

Best of luck on this, I tried to argue in #2112 to support more effective use of namespacing or relax these rules, and not much of either approach was accepted. Hopefully, you can achieve a different outcome in this request.

@iMichaela
Copy link
Contributor

@brian-ruf - thank you resurfacing this issue. I raised it long ago in a separate context and got a heavy push back from the technical director of that time. Let's discuss with you and @xee5ch (if interested) the best solution and propose it.
More constraints is, generally speaking, not the direction we should go. Removing constraints, yes.
Issues and PRs are not ignored, but not rushed either since a proper consideration and review from NIST and external-to-NIST working groups is supported and expected. We want to adopt a robust solution that meets the community-at-large needs. Fixing for CSA but not considering EUCS or CIS or CRI or ISO or DORA or others' needs is not something we should aim for.

@xee5ch
Copy link
Contributor

xee5ch commented Mar 4, 2025

Let's discuss with you and @xee5ch (if interested) the best solution and propose it. More constraints is, generally speaking, not the direction we should go. Removing constraints, yes.

OK, so where is this principle written down? How will complex data validation be supported without constraints? It seems this perspective is a change from the current status quo given the models you maintain in code, so answers to these questions seem really important.

Issues and PRs are not ignored, but not rushed either since a proper consideration and review from NIST and external-to-NIST working groups is supported and expected. We want to adopt a robust solution that meets the community-at-large needs.

Where are these working groups? Where is the community-at-large that is not contributing to these repositories, mailing lists, or other avenues for feeedback?

Fixing for CSA but not considering EUCS or CIS or CRI or ISO or DORA or others' needs is not something we should aim for.

This approach is actually why I presented #2115 for #2112 to allow precision for general or specific use-cases with opt-in based on namespaces. How do we move that forward and use that to address this issue (#2118), #2112, and the intersection of other scenarios you allude to here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Needs Triage
Development

No branches or pull requests

3 participants