Skip to content

[oscal support] guidance must be a top-level part in Layer 1 OSCAL catalogs #139

@jpower432

Description

@jpower432

based on https://pages.nist.gov/OSCAL/learn/concepts/layer/control/catalog/sp800-53rev5-example/#parts _smt is for statements (link). The _gdn suffix is for guidance (link). Am I wrong? Can they be daisy-chained like this?

@jmeridth I'm glad you brought this up. I missed this earlier -- it's schema valid, but fails on the constraints validation. I looked into this a bit more using some examples from CCC and the oscal-cli for validation and found that you can only nest an item or assessment-objective as a sub-part.

@eddie-knight @zohayb23 I'll open an issue to update Layer 1, but I still think we need some changes here. I would assume we still want the recommendations tied to a specific Assessment Requirement. We could stick with the recommendation custom part and nest it under a statement or maybe something like below?

for _, control := range family.Controls {
			controlId := oscalUtils.NormalizeControl(control.Id, true)
			smtPart := oscal.Part{
				Name:  "statement",
				ID:    fmt.Sprintf("%s_smt", controlId),
				Parts: &[]oscal.Part{},
			}
			gdnPart := oscal.Part{
				Name:  "guidance",
				ID:    fmt.Sprintf("%s_gdn", controlId),
				Parts: &[]oscal.Part{},
			}
			for _, ar := range control.AssessmentRequirements {
				partId := oscalUtils.NormalizeControl(ar.Id, true)
				itemSubSmt := oscal.Part{
					Name:  "item",
					ID:    fmt.Sprintf("%s_smt.%s", controlId, partId),
					Prose: ar.Text,
					Title: ar.Id,
					Links: &[]oscal.Link{
						{
							Href: fmt.Sprintf(controlHREF, c.Metadata.Version, ar.Id),
							Rel:  "canonical",
						},
					},
				}
				*smtPart.Parts = append(*smtPart.Parts, itemSubSmt)
				gdnSubPart := oscal.Part{
					Name:  "assessment-objective",
					ID:    fmt.Sprintf("%s_gdn.%s", controlId, partId),
					Prose: ar.Recommendation,
					Links: &[]oscal.Link{
						{
							Href: fmt.Sprintf("#%s_smt.%s", controlId, partId),
							Rel:  "referenced-statement",
						},
					},
				}

				*gdnPart.Parts = append(*gdnPart.Parts, gdnSubPart)
			}

			newCtl := oscal.Control{
				Class: family.Id,
				ID:    control.Id,
				Links: &[]oscal.Link{
					{
						Href: fmt.Sprintf(controlHREF, c.Metadata.Version, strings.ToLower(control.Id)),
						Rel:  "canonical",
					},
				},
				Title: strings.TrimSpace(control.Title),
				Parts: &[]oscal.Part{smtPart, gdnPart},
			}
			controls = append(controls, newCtl)
		}

Originally posted by @jpower432 in #138 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions