diff --git a/src/content/concepts/processing/profile-resolution.html b/src/content/concepts/processing/profile-resolution.html index 9c56de74..9f8df7cb 100644 --- a/src/content/concepts/processing/profile-resolution.html +++ b/src/content/concepts/processing/profile-resolution.html @@ -2,867 +2,1873 @@ title: OSCAL Profile Resolution description: Transforming a profile into the tailored catalog it represents toc: - enabled: true - headingselectors: "h1, h2, h3, h4, h5" +enabled: true +headingselectors: "h1, h2, h3, h4, h5" --- -

Notice of Draft Status

Please note that this specification is currently a work in progress and is subject to change. If you have any feedback or comments, please create an issue at the NIST OSCAL Github Repository: github.com/usnistgov/OSCAL.

Abstract

This specification provides the minimal requirements for processing an OSCAL Profile to create a new OSCAL Catalog Document. This process of applying a profile to a catalog to create a new catalog is called - Profile Resolution. Not all OSCAL Profiles will be resolved, nor are expected to be; however, the resolution requirements in this document are crucial to understanding the intended functionality of any given OSCAL Profile. - This specification is intended for software developers who intend to develop an OSCAL Profile Resolver, or for OSCAL Profile authors who want a more in-depth understanding of profile resolution. -

Introduction

Purpose

This document defines the normative requirements for an OSCAL Profile Resolver. Profile resolution is core to addressing a fundamental OSCAL requirement: - the representation of baselines separately from the control catalogs on which they depend). The requirements for resolution must therefore be well-defined and deterministic, - enabling tool developers and parties exchanging OSCAL Profiles can work from a common understanding.

No requirements are placed on implementation-level details, instead, requirements are laid out as what the output of resolution must look like given a certain input. - By adhering to these requirements OSCAL producers, OSCAL consumers, and any other members of the OSCAL ecosystem can create and resolve profiles deterministically, - with repeatable results, regardless of the tool used.

Reading This Document

Terminology

Many core OSCAL concepts are defined on the OSCAL Terminology Page. The most important are repeated in this document, but readers should verify their understanding of all core OSCAL terms before reading this document.

Additionally, many terms in the wider domain have overloaded definitions. Unless defined otherwise by OSCAL or explicitly in this document, terms are to be understood as defined in the NIST CSRC Glossary.

Requirement Keywords

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in - BCP 14 - [RFC2119] - [RFC8174]when, and only when, they appear in all capitals, as shown here. -

Use of YAML

OSCAL supports a variety of serialization formats, each of which having it's own benefits and drawbacks. In this document, YAML (YAML Ain't Markup Language) is used to represent the various objects of the - sourceand - target. All examples and in-line references will be represented using - YAML 1.2. -

YAML maps cleanly to JSON, thus allowing easy use of existing JSON/XML transformers where needed. With that in mind, the - OSCAL Complete JSON Referenceis a valuable resource for understanding the YAML-based information structures used in this document. All JSON properties and objects defined in the reference equate to a YAML mapping, list, or dictionary. -

Reading YAML Examples

YAML is a particularly human-readable format. For those unfamiliar with the format, the basics:

The YAML specification is freely available here: - YAML 1.2. -

Additionally, in order to unambiguously express information, this specification uses additional conventions, as described below.

There are some objects whose values must be determined dynamically at processing time. The most common example of this is timestamping output as it is processed. In this case, and any other dynamic-value cases, the expression - ${{ }}is used. -

For example:

{{< highlight xml>}}last-modified: ${{ timestamp }}{{}}

Indicates the - last-modifiedobject should be produced with contents generated appropriately, in this case, the timestamp at the time of processing. -

Some examples may elide content to enhance readability or save space. In these cases, a YAML comment (any line that starts with - #) will be used to explain the elision. -

Finally, although examples are syntactically faithful to OSCAL, they are not necessarily always formally valid in every respect. For example, OSCAL defines allowed property names ( - props) and values, and those rules may not be observed here. Examples are given for purposes of illustrating profile resolution semantics only, and should not be taken as normative for any actual use. -

Document Layout

The specification is broken into the following major sections:

- Please note: As referenced in the Purpose section - [See: Purpose], this specification makes no hard requirements on the specifics of implementation. It is feasible for an implementation to use no intermediate representation, and to directly and iteratively build the output. As long as all processing and output requirements are satisfied, any approach is allowed. With that said, the specification has been laid out to aid in implementation by providing a clear organization as a sequence of distinct operations. -

The Intermediate and Implementation Guidance

The overall intent of this document, in addition to defining strict requirements, is to provide rough guidelines on implementing an OSCAL Profile Resolution Tool. To this end, each phase of resolution will be framed as a series of transformations applied to an internal data structure that is persistent throughout the process. We call this "the intermediate".

Any examples that are labelled as "Intermediate" are pseudo-code, designed to represent how this data structure might look as we apply different operations to it. The example intermediates are often not valid OSCAL, and are not to be taken as guidance, but rather a useful visualization tool for implementers.

The authors believe that applying the steps of resolution in order against this intermediate representation is the simplest way to achieve full compliance with the specification. However, there is no requirement to implement profile resolution in this way. Requirements are given as rules on the output of resolution, and as such, tools can operate any way they would like internally.

Phases of Profile Processing

An OSCAL Profile has three major sections, each which correspond to a phase of profile resolution. In order to complete the profile resolution process, each section must be fully parsed and a catalog output created.

It is strongly RECOMMENDED that implementations execute the following steps in the order that they are provided here (import, merge, modify). While it is possible to achieve compliance with a non-standard approach, the iterative nature of profile resolution lends itself to linear processing.

The three steps are - import; - merge; and - modify. In brief: -

As described in the previous section, when resolved, an OSCAL Profile takes the form of an OSCAL Catalog. The phases described below will produce outputs conforming to the catalog model.

Import Phase

A profile begins by listing a set of catalogs and/or profiles to be imported. Each is represented by a resolvable resource URI and a directive specifying which controls to import from that resource. These resources may be available as static resources, or they may be produced dynamically on request; such as is the case when a profile is imported. Imports are given in sequence after the metadata:

{{< highlight xml>}} - -profile: - uuid: ~ - metadata: ~ - imports: +

Notice of Draft Status

+

Please note that this specification is currently a work in progress and is + subject to change. If you have any feedback or comments, please create an issue at the NIST OSCAL Github Repository: + github.com/usnistgov/OSCAL.

+

Abstract

+

This specification provides the minimal requirements for processing an OSCAL + Profile to create a new OSCAL Catalog Document. This process of applying a profile to a catalog to create a new + catalog is called + Profile Resolution. Not all OSCAL Profiles will be resolved, nor are expected to be; however, the + resolution requirements in this document are crucial to understanding the intended functionality of any given OSCAL + Profile. + This specification is intended for software developers who intend to develop an OSCAL Profile Resolver, or for OSCAL + Profile authors who want a more in-depth understanding of profile resolution. +

+

Introduction

+

Purpose

+

This document defines the normative requirements for an OSCAL Profile Resolver. + Profile resolution is core to addressing a fundamental OSCAL requirement: + the representation of baselines separately from the control catalogs on which they depend). The requirements for + resolution must therefore be well-defined and deterministic, + enabling tool developers and parties exchanging OSCAL Profiles can work from a common understanding.

+

No requirements are placed on implementation-level details, instead, + requirements are laid out as what the output of resolution must look like given a certain input. + By adhering to these requirements OSCAL producers, OSCAL consumers, and any other members of the OSCAL ecosystem can + create and resolve profiles deterministically, + with repeatable results, regardless of the tool used.

+

Reading This Document

+

Terminology

+

Many core OSCAL concepts are defined on the OSCAL Terminology Page. The most important are + repeated in this document, but readers should verify their understanding of all core OSCAL terms before reading this + document.

+

Additionally, many terms in the wider domain have overloaded definitions. Unless + defined otherwise by OSCAL or explicitly in this document, terms are to be understood as defined in the NIST CSRC Glossary.

+ +

Requirement Keywords

+

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", + "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as + described in + BCP 14 + [RFC2119] + [RFC8174]when, and only when, they appear in all capitals, + as shown here. +

+

Use of YAML

+

OSCAL supports a variety of serialization formats, each of which having it's own + benefits and drawbacks. In this document, YAML (YAML Ain't Markup Language) is used to represent the various objects + of the + sourceand + target. All examples and in-line references will be represented using + YAML 1.2. +

+

YAML maps cleanly to JSON, thus allowing easy use of existing JSON/XML + transformers where needed. With that in mind, the + OSCAL Complete JSON + Referenceis a valuable resource for understanding the YAML-based information structures used in this document. + All JSON properties and objects defined in the reference equate to a YAML mapping, list, or dictionary. +

+

Reading YAML Examples

+

YAML is a particularly human-readable format. For those unfamiliar with the + format, the basics:

+ +

The YAML specification is freely available here: + YAML 1.2. +

+

Additionally, in order to unambiguously express information, this specification + uses additional conventions, as described below.

+

There are some objects whose values must be determined dynamically at processing + time. The most common example of this is timestamping output as it is processed. In this case, and any other + dynamic-value cases, the expression + ${{ }}is used. +

+

For example:

{{< highlight xml>}}last-modified: ${{ timestamp }}{{ + }}

Indicates the + last-modifiedobject should be produced with contents generated appropriately, in this case, + the timestamp at the time of processing. +

+

Some examples may elide content to enhance readability or save space. In these + cases, a YAML comment (any line that starts with + #) will be used to explain the elision. +

+

Finally, although examples are syntactically faithful to OSCAL, they are not + necessarily always formally valid in every respect. For example, OSCAL defines allowed property names ( + props) and values, and those rules may not be observed here. Examples are given for + purposes of illustrating profile resolution semantics only, and should not be taken as normative for any actual use. +

+

Document Layout

+

The specification is broken into the following major sections:

+ +

+ Please note: As referenced in the Purpose section + [See: Purpose], this specification makes no hard requirements on the + specifics of implementation. It is feasible for an implementation to use no intermediate representation, and to + directly and iteratively build the output. As long as all processing and output requirements are satisfied, any + approach is allowed. With that said, the specification has been laid out to aid in implementation by providing a + clear organization as a sequence of distinct operations. +

+

The Intermediate and Implementation Guidance

+

The overall intent of this document, in addition to defining strict + requirements, is to provide rough guidelines on implementing an OSCAL Profile Resolution Tool. To this end, each + phase of resolution will be framed as a series of transformations applied to an internal data structure that is + persistent throughout the process. We call this "the intermediate".

+

Any examples that are labelled as "Intermediate" are pseudo-code, designed to + represent how this data structure might look as we apply different operations to it. The example intermediates are + often not valid OSCAL, and are not to be taken as guidance, but rather a useful visualization tool for implementers. +

+

The authors believe that applying the steps of resolution in order against + this intermediate representation is the simplest way to achieve full compliance with the specification. However, + there is no requirement to implement profile resolution in this way. Requirements are given as rules on the output + of resolution, and as such, tools can operate any way they would like internally.

+

Phases of Profile Processing

+

An OSCAL Profile has three major sections, each which correspond to a phase of + profile resolution. In order to complete the profile resolution process, each section must be fully parsed and a + catalog output created.

+

It is strongly RECOMMENDED that implementations execute the following steps in + the order that they are provided here (import, merge, modify). While it is possible to achieve compliance with a + non-standard approach, the iterative nature of profile resolution lends itself to linear processing.

+

The three steps are + import; + merge; and + modify. In brief: +

+ +

As described in the previous section, when resolved, an OSCAL Profile takes + the form of an OSCAL Catalog. The phases described below will produce outputs conforming to the catalog model.

+

Import Phase

+

A profile begins by listing a set of catalogs and/or profiles to be imported. + Each is represented by a resolvable resource URI and a directive specifying which controls to import from that + resource. These resources may be available as static resources, or they may be produced dynamically on request; such + as is the case when a profile is imported. Imports are given in sequence after the metadata:

{{< highlight xml>}} + + profile: + uuid: ~ + metadata: ~ + imports: - href: ${{ catalog URI }} - include-controls: ${{ list of selected controls }} + include-controls: ${{ list of selected controls }} - href: ${{ profile URI }} - include-controls: ${{ list of selected controls }} - {{}}

In an import directive, the reference to the resource to be imported appears on an + include-controls: ${{ list of selected controls }} + {{}}

In an import directive, the reference to the resource to be + imported appears on an hrefchild object. It takes either of two forms, external or internal: -

An external reference appears as an absolute or relative URL:

{{< highlight xml>}} - -profile: - uuid: ~ - metadata: ~ - imports: - - href: >- - https://github.com/usnistgov/oscal-content/tree - /master/nist.gov/SP800-53/rev4/yaml/NIST_SP-800-53_rev4_catalog.yaml +

+

An external reference appears as an absolute or relative URL:

{{< + highlight xml>}} + + profile: + uuid: ~ + metadata: ~ + imports: + - href: >- + https://github.com/usnistgov/oscal-content/tree + /master/nist.gov/SP800-53/rev4/yaml/NIST_SP-800-53_rev4_catalog.yaml include-controls: ${{ list of selected controls }} - - href: "../../NIST_SP-800-53_rev5_catalog.yaml" - include-controls: ${{ list of selected controls }} - {{}}

While an internal reference appears as below (see - [See: Internal References]): -

{{< highlight xml>}} - -profile: - uuid: ~ - metadata: ~ - imports: - - href: #80052rev4 + - href: "../../NIST_SP-800-53_rev5_catalog.yaml" include-controls: ${{ list of selected controls }} - - href: #80052rev5 - include-controls: ${{ list of selected controls }} - {{}}

All import directives will contain either - include-all: ~or - include-controls. These directives indicate which controls from the imported document are explicitly selected - [See: Including Controls]. -

The following section contains requirements for processing the - import child of a source - profile -

Import href Requirements

Import URI Resolution

Tools MUST resolve URIs by following - Section 5 of RFC3986, with the exception of URI Fragments (URIs that start with "#"). URI Fragments MUST instead be resolved as defined in + {{}}

While an internal reference appears as below (see + [See: Internal References]): +

{{< highlight xml>}} + + profile: + uuid: ~ + metadata: ~ + imports: + - href: #80052rev4 + include-controls: ${{ list of selected controls }} + - href: #80052rev5 + include-controls: ${{ list of selected controls }} + {{}}

All import directives will contain either + include-all: ~or + include-controls. These directives indicate which controls from the imported document + are explicitly selected + [See: Including Controls]. +

+

The following section contains requirements for processing the + import child of a source + profile +

+

Import href Requirements

+

Import URI Resolution

+

Tools MUST resolve URIs by following + Section 5 of RFC3986, with the + exception of URI Fragments (URIs that start with "#"). URI Fragments MUST instead be resolved as defined in [See: Internal References]. -

Import Resource Acquisition

Tools MUST acquire resources at the resolved URI by following - Section 5 of RFC3986, with the exception of URI Fragments (URIs that start with "#"). URI Fragments MUST instead be acquired as defined in +

+

Import Resource Acquisition

+

Tools MUST acquire resources at the resolved URI by following + Section 5 of RFC3986, with the + exception of URI Fragments (URIs that start with "#"). URI Fragments MUST instead be acquired as defined in [See: Internal References]. -

For the purposes of resolving URIs using the above specification, the Base URI MUST be considered to be the absolute URI of the containing profile.

In the case that acquiring a resource fails, the tool MUST cease processing and provide an error. In order to ensure profile resolution results in the same catalog regardless of which tool resolves it, all imports must successfully resolve. While this may cause inconvenience if resources are frequently not available, it ensures interoperability.

Note that receiving a cached version of an import, or resolving an import that is otherwise unavailable through some other (but automatic) means still satisfies the above requirement. This specification does not put requirements on the precise function of the import, as long as the correct document is retrieved.

Internal References

URI Fragments in OSCAL represent internal references to other OSCAL objects in the same document. These references follow the pattern of #{{objectID}}. For example, the URI Fragment #param1 is referencing the Parameter with unique ID param1.

In the context of the Import Phase, internal references will only appear as a reference to a profile or catalog that is in the resources section of the source. When tools encounter such a reference, they MUST locate the object in resources with the matching ID value, and resolve the import using the +

+

For the purposes of resolving URIs using the above specification, the + Base URI MUST be considered to be the absolute URI of the containing profile.

+

In the case that acquiring a resource fails, the tool MUST cease + processing and provide an error. In order to ensure profile resolution results in the same catalog regardless + of which tool resolves it, all imports must successfully resolve. While this may cause inconvenience if + resources are frequently not available, it ensures interoperability.

+

Note that receiving a cached version of an import, or resolving an + import that is otherwise unavailable through some other (but automatic) means still satisfies the above + requirement. This specification does not put requirements on the precise function of the import, as long as + the correct document is retrieved.

+

Internal References

+

URI Fragments in OSCAL represent internal references to other OSCAL + objects in the same document. These references follow the pattern of #{{objectID}}. + For example, the URI Fragment #param1 is referencing the Parameter with unique ID + param1.

+

In the context of the Import Phase, internal references will only appear + as a reference to a profile or catalog that is in the resources section of the + source. When tools encounter such a reference, they MUST locate the object in resources with the matching ID value, and resolve the import using the rlink URI and the above resolution requirements. -

If the object fetched cannot be found or is not a valid OSCAL object, the tool MUST cease processing and provide an error.

{{< highlight xml>}} - -profile: - metadata: ~ - imports: - - href: "#nist-sp800-53_catalog" - include-controls: ${{ list of selected controls }} - - # Content Elided - - backmatter: - resources: - - uuid: "nist-sp800-53_catalog" - description: "NIST SP 800-53 rev5 OSCAL format, on Github." - rlinks: +

+

If the object fetched cannot be found or is not a valid OSCAL object, + the tool MUST cease processing and provide an error.

{{< highlight xml>}} + + profile: + metadata: ~ + imports: + - href: "#nist-sp800-53_catalog" + include-controls: ${{ list of selected controls }} + + # Content Elided + + backmatter: + resources: + - uuid: "nist-sp800-53_catalog" + description: "NIST SP 800-53 rev5 OSCAL format, on Github." + rlinks: - rlink: - href: >- - https://github.com/usnistgov/oscal-content/tree - /master/nist.gov/SP800-53/rev4/xml/NIST_SP-800-53_rev5_catalog.xml - {{}}

Resolving Imports of Profiles

If the resource acquired is an OSCAL Profile, the tool MUST apply this specification to resolve it, then continue processing having imported the resulting catalog.

When a profile imports a profile, the subordinate profile SHOULD be resolved first into a catalog using this specification, before it is imported. This presents the possibility of circular imports, when a profile is directed to import itself either directly or indirectly.

A - circular import occurs when a profile imports an already imported profile, which was called at an earlier place in the import hierarchy. For example, if profile A imports profile B, and profile B imports profile A, the second import is circular. (An import at the top can only be circular if a profile tries to import itself.) If A imports B, B imports C and C imports A, C’s import is circular. -

Note that an import can only be circular within the context of processing a particular profile. In the last example, C’s import would not be circular if invoked in the context of resolving B by itself.

If a processor encounters a - circular import as described above (self-imports are inherently circular), the processor MUST cease processing and generate an error. -

A profile identified as - home_profile.yamlimports another one identified as - circular_profile.yaml: -

{{< highlight xml>}} - -profile: - id: "home_profile.yaml" - metadata: ~ - imports: - - href: "circular_profile.yaml" - include-controls: ${{ list of selected controls }} - {{}}

In turn this file invokes - home_profile.xml: -

{{< highlight xml>}} - -profile: - id: "circular_profile.yaml" - metadata: ~ - imports: - - href: "home_profile.yaml" - include-controls: ${{ list of selected controls }} - {{}}

Once detected, this circular import will result in an error and no further processing will take place.

{{< highlight xml>}} - - # Import at href: "circular_profile.yaml" failed. - # Reason: Error during profile import: - # Import at href: "home_profile.yaml" failed. - # Reason: Circular import - {{}}

Multiple imports

Each import directive is processed to produce a set of controls. Note that this occurs even if the same catalog is imported multiple times: each distinct import collects controls into a separate - selection: -

{{< highlight xml>}} - -profile: - uuid: ~ - metadata: ~ - imports: - - href: "#catalog" - include-controls: - - with-ids: - - ac-1 - - ac-2 - - href: "#catalog" - include-controls: - - with-ids: - - ac-3 - - ac-4 - {{}}{{< highlight xml>}} - -intermediate: - inclusions: - - id: ${{uuid of #catalog}} - included-controls: - - ac-1 - - ac-2 - - id: ${{uuid of #catalog}} - included-controls: - - ac-3 - - ac-4 - {{}}

The control inclusions are combined and collapsed in the next phase of processing, - merge(see [See: Merge Phase]) . -

Multiple imports against the same resource are allowed, and would most commonly occur when the profile author is using [See: Mapping Controls] to create very specific output. - Multiple imports may result in outputs with clashing control IDs if mapping or the merge directive is not set correctly.

Mapping Controls

The optional - mapping child of a given - import provides a simple ID remapping for objects included from that specific import. This provides the means for profile authors to proactively avoid clashing IDs of controls and other objects. -

The Mapping section consists of 5 optional subsections, each covering a particular type of object. Each subsection is a list of ID mappings to be applied for objects that are the parent object type.

When encountering a given mapping instruction, processors:

Since mapping is a self contained process inside each import, the rest of this specification will continue to reference IDs with the assumption that mapping has already been applied if it was present. Since mapping is most commonly used to avoid clashing IDs, processors should take care to not handle duplicate IDs until after mapping is complete.

Below is a simple example of mapping. The second - import included controls from a different catalog whose ID values happen to collide. Knowing this, the profile author has remapped those IDs to new values. -

{{< highlight xml>}} - -profile: - uuid: ~ - metadata: ~ - imports: - - href: "#catalog" - include-controls: - - with-ids: - - ac-1 - - ac-2 - - href: "#catalog2" - include-controls: - - with-ids: - - ac-1 - - ac-2 - mapping: - - controls: - - from: ac-1 - to: map-ac-1 - - from: ac-2 - to: map-ac-2 - {{}}

Using the intermediate approach, an internal data structure resembling the following would result from the above profile:

{{< highlight xml>}} - -intermediate: - metadata: ~ - inclusions: - - id: ${{uuid of #catalog}} - included-controls: - - ac-1 - - ac-2 - - id: ${{uuid of #catalog2}} - included-controls: - - map-ac-1 - - map-ac-2 - {{}}

Including Controls

Each import contains directives on which controls from the imported catalog are to be fetched and used for further processing. Throughout the rest of the document we will refer to this as "inclusion". - If a control is included, and the source profile makes no other changes to it, it will be present in the output. Exclusion directives in this section, as well as directives in the following two major sections (merge and modify), - may make changes to an included control or group that could cause it to appear differently, or not at all, in the output. Using the intermediate implementation approach, any control(s) that are included would be extracted from the referenced catalogs, any applicable mappings would be applied, then the controls(s) would be stored.

include-all

When an import provides the - include-all directive, ALL controls and groups in the referenced document (including nested controls) MUST be included. -

{{< highlight xml>}}include-all: ~{{}}

include-controls plus with-id

When an import provides the - include-controls directive, with a - with-id child, all controls in the referenced document whose - id match one of the listed - id values MUST be included. -

{{< highlight xml>}} - -include-controls: - - with-ids: - - id: ac-1 - - id: ac-2 - {{}}

include-controls plus matching

Controls may also be included using match patterns against their IDs. This is useful because related controls (either in a hierarchy, or together in a group) frequently have related IDs as well.

When an import provides the - include-controls directive, with a - matching child, all controls in the referenced document whose - id matches one of the listed - pattern values (Glob matching) MUST be included. -

If a - matching object is provided with no - pattern, it MUST be treated as matching nothing. While not providing a pattern is technically valid, resolution tool implementers should be aware that it is generally undesirable, and warnings or notices to the user may be appropriate. -

{{< highlight xml>}} - -include-controls: - - matching: - - pattern: "ac*" - {{}}

Dealing with Nested Controls and Groups

In OSCAL, controls may contain child controls. For instance, in SP 800-53 many controls are supplemented with control enhancements; in OSCAL these are represented as child controls within parent controls. So parent AC-2 (in a given catalog) has children AC-2(1) through AC-2(13), for example.

By default, inclusion of a control also causes any of that control's ancestors (or parents) to also be included. By default, inclusion of a control DOES NOT cause the inclusion of any descendants (or children) of that control to be included. This applies to both controls and groups.

This default behavior can be modified by the following two optional children of the - include-controls object. -

with-child-controls

Child controls are, for the most part, treated the same as top level controls: they can be explicitly included using the selection directives above. As a shortcut to manually including all of the desired descendant controls of a given control, OSCAL provides the with-child-controls option. with-child-controls appears as a child object under a given inclusion directive, and defines additional behavior that is to be executed alongside the parent inclusion.

A - with-child-controls: yes directive on an - include-controls indicates that - all descendant controls of the included control MUST also be included. -

A - with-child-controls: no directive on an - include-controls indicates that ONLY the matching control is included, any descendant children MUST NOT be included. -

If no - with-child-controls is provided, the processor MUST consider the directive as being equivalent to one having - with-child-controls:no. -

with-parent-controls

Although similar to the above - with-child-controls, the optional - with-parent-controls applies to parents of the included control, and has the opposite default behavior. In order to maintain the structure of the source catalog, profile resolution includes all parents of an included control by default. If a profile author wants to change this structure, they should use an exclude directive that lists all of the undesired parents. As a shortcut for this, - with-parent-controls provides the following functionality: -

A - with-parent-controls: yes directive on an - include-controls indicates that - all parent controls of the included control MUST also be included. -

A - with-parent-controls: no directive on an - include-controls indicates that ONLY the matching control is included, any parent MUST NOT be included. -

If no - with-parent-controls is provided, the processor MUST consider the directive as being equivalent to one having - with-parent-controls:yes. -

exclude-controls

Exclusions work the same way as inclusions, except with the opposite effect - the indicated control(s) do not appear in the target catalog.

Any control designated to be both included and excluded, MUST be excluded. This holds irrespective of the specificity of the selection for inclusion or exclusion. For example, if AC-1 is included by id - ac-1 and excluded by matching - ac.*, it is excluded. -

When - exclude-controls has at least one - with-ids or - matching directive, the processor MUST follow the same rules as defined in the relevant sections above for these directives, but exclude instead of include any controls. All optional features (with-child-controls, etc.) also apply to exclusion directives. -

Redundant Inclusions and Exclusions

A given - import may have any number of inclusion statements and any number of exclusion statements. Their effect is cumulative; any control that is included (or excluded) more than once MUST be considered to be included (or excluded) only once. In other words, a given control being included or excluded more than once has no effect. Exclusion still takes priority over inclusion (see above). -

Note that this requirement only applies to controls included within the context of a single import. Controls with duplicate IDs included under a different - import are not discarded. Also note that this redundancy pruning happens after any relevant mappings have been applied. -

Handling Params

Any - paramthat is not directly under a control is referred to as a - looseparam. -

All loose params from both imported documents and the profile source MUST be included. These params will be kept in the final output if the document contains any references to them, and discarded otherwise. See - [See: Pruning and Ordering]. Since new references can be created during the - modify phase, tools should be careful not to prune params without fully understanding the final state of the output document. -

Handling Groups

Some source catalogs use - group objects to place controls into arbitrary groupings. Tools will need to be aware of these groups when executing the "merge" phase below, as they will duplicated into the output under the "as-is" mode and can be referenced in "custom" mode. The naïve intermediate approach would keep all groups until all other phases are complete, but implementations may find it more performant to look ahead and prune unused groups early. -

Avoiding Implementation Pitfalls

In order to ensure that implementers have as much flexibility as possible, requirements in this section have purposefully been kept minimal. Below are some common issues for implementers to be aware of:

Wrapping up the Import Phase

At this point all requirements for content importing and control inclusion have been covered. If using the intermediate approach, the processor should have an intermediate that contains: a set of included controls and all of their child informational (non-control, non-group) objects, any relevant - group objects and their informational content, and a set of included "loose params" - [See: Handling Params] (zero to many). The general structure of the intermediate would match that of the imported catalogs (i.e. nested controls remain nested, grouped controls remain grouped). -

Merge Phase

Profiles may contain a - mergesection, where directives are given to instruct the processor how to combine the set of included objects collected during the Import Phase. - mergehas two parts: a "combine" directive, and a "structuring" directive. -

It is RECOMMENDED that tools apply the "combine" directive to the intermediate generated by the Import phase first, then apply the "structuring" directive.

The following section contains requirements for processing the - merge child of a source profile. -

The "combine" Directive

- combineis an optional child of - mergethat provides the rules for dealing with objects that have duplicate (or clashing) distinct IDs - [See: Distinct ID of Objects]. -

There are two valid combination methods provided by OSCAL, provided by the - methodchild of - combine: -

Note that "merge: combine" is deprecated, and MUST be considered undefined behavior when encountered.

In order to apply the combination method, IDs of each control explicitly included are compared against one another. As IDs are unique across entire OSCAL documents, different imports or any groupings have no bearing on collision. Processing requirements for each method are described below.

No Combine Directive

If no - merge directive is given in the profile, or if a - merge is given without a - combine, merge conflicts MUST be treated as if - method: keep was given. For example, a profile with no - merge directive: -

{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-all: ~ - {{}}

is the same as

{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-all: ~ - merge: - combine: - method: keep - flat: ~ - {{}}

- method:keep -

When a merge is indicated by - method:keep, or when no merge directive is given, the - keepcombination rule is used. Any control with the same distinctive ID - [See: Distinct ID of Objects]MUST NOT not merged. (They are kept.) -

{{< highlight xml>}} - - merge: - combine: - method: keep - {{}}

Under this directive, colliding controls will result in invalid results, as they will both appear in the results with the same ID. Accordingly, this setting may be useful in ensuring integrity of references to controls as given in the profile: if any included control is called only once, clashing controls will not be produced and validation will succeed.

{{< highlight xml>}} - -profile: - imports: - - href: #catalog1 - include-controls: - - with-ids - id: ac-1 - id: ac-2 - - href: #catalog1 - include-controls: - - with-ids - id: ac-1 - id: ac-2 - merge: - combine: - method: keep - {{}}

In the intermediate (showing control inclusions):

{{< highlight xml>}} - -intermediate: - inclusions: - - explicitly-included-controls: - - ac-1 - - ac-2 - - ac-1 - - ac-2 - {{}}

In this case, downstream errors should be expected: the two - ac-1 controls clash with each other, as do the two - ac-2 controls. -

Processors SHOULD provide a warning under the merge:keep directive when duplicate controls are detected. The processor MAY throw an error and cease processing (short-circuiting a certain future error) when duplicate controls are detected under the merge:keep directive.

- method:use-first -

{{< highlight xml>}} - - merge: - combine: - method: use-first - {{}}

When the - "use-first"combination rule is applied, and controls that share a distinctive ID are found, the first control encountered MUST be kept, the rest MUST be discarded. - "First" MUST be determined by a top-down, depth-first traversal of the source profile's import hierarchy. -

{{< highlight xml>}} - -profile: - imports: - - href: #catalog1 - include-controls: - - with-ids - id: ac-1 - id: ac-3 - - href: #catalog1 - include-controls: - - with-ids - id: ac-1 - id: ac-2 - merge: - combine: - method: use-first - {{}}

In the intermediate(showing control inclusions):

{{< highlight xml>}} - -intermediate: - inclusions: - - explicitly-included-controls: - - ac-1 (From catalog1) - - ac-3 - - ac-2 - {{}}

- method:merge -

Deprecated, unspecified behavior.

The "structuring" Directive

This section describes how a profile may dictate the structure of the target - catalog, apart from its - metadata or - back-matter. Optionally, one of three "structuring" directives can be included as a child of - merge: - flat, - as-isand - custom. When one of these appears, it is the selected structuring directive. If more than one appears, processors MUST generate an error and cease processing. Processing requirements for each are given below: -

No Structuring Directive

If no - merge directive is given in the profile, or if a - merge is given without a structuring directive, structuring the output MUST be treated as if the structuring directive - flat was given. For example, a profile with no - merge directive: -

{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-all: ~ - {{}}

is the same as

{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-all: ~ - merge: - combine: - method: keep - flat: ~ - {{}}

"flat"

Profiles with the "flat" merge directive MUST be resolved as unstructured catalogs, with no grouping or nesting of controls.

Unstructured catalog output MUST be produced by adhering to the following requirements:

An example of flat structuring is provided below

{{< highlight xml>}} - -catalog: - groups: - - groupA - - ac-1 - - ac-2 - - groupB - - bc-1 - {{}}{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-controls: - with-ids: - - ac-1 - - ac-2 - - bc-1 - merge: - combine: - method: keep - flat: ~ - {{}}{{< highlight xml>}} - -intermediate: - controls: - - ac-1 - - ac-2 - - bc-1 - {{}}

- as-is -

An - as-is directive is used to reproduce the structure of the source documents in the target catalog. -

Processors MUST handle the - as-is directive by adhering to the following requirements: -

Example:

{{< highlight xml>}} - -catalog: - groups: - - groupA - - ac-1 - - ac-2 - - groupB - - bc-1 - {{}}{{< highlight xml>}} - -profile: - imports: - - href: #catalogURI - include-controls: - with-ids: - - ac-1 - - ac-2 - - bc-1 - merge: - combine: - method: keep - as-is: ~ - {{}}{{< highlight xml>}} - -intermediate: -#In this approach, the original hierarchy of the controls under the groups is stored, -#but is not shown in this example. - controls: - - ac-1 - - ac-2 - - bc-1 - groups: - - groupA - - groupB - {{}}

- custom -

The - customdirective provides the target catalog with a custom structure. A one-to-one mapping of the desired structure of the target catalog is defined alongside control matching instructions, resulting in a strictly controlled output catalog. -

Creating Custom Groups

A - groupobject given under - custom MUST result in a - group with the exact same content (excluding - insert-controls) in the target catalog. -

If the ID of the group matches the ID of a group that has been included during the import phase, all contents inside the group, including - title, - param, - prop and - part objects MUST be copied into the target, appearing in the same order as in the source. -

Note that groups defined in - custom may vary from fully featured to minimally instantiated. This includes arbitrary nesting of such groups inside of one another. No groups other than those explicitly declared should appear in the output catalog. -

Inserting Controls

The - insert-controls directive may appear anywhere under - custom, whether as a direct child or inside any of the defined groups. Inside insert-controls, - include-controls and - include-all from the Import Phase - [See: Import Phase]are used with the same basic behavior to configure which controls are selected and inserted at the current location. -

In order to provide clarity, controls that match the various conditions of these inclusion directives inside the - custom object will be referred to as "selected" instead of "included". Only directly selected controls will appear in the target catalog. -

When processing the control selection of a custom element, the behavior defined in this section MUST be followed to generate the output.

A - insert-controls with an - include-controls child results in the following behavior: -

An - insert-controls with an - include-all child results in all included controls being selected and inserted. They are given in the same order as they appeared in the input control selection(s). -

- insert-controls can also indicate the order that the selected controls are to be emitted in the result catalog using an - order child. Three values MUST be supported and handled as specified below: -

In the case that a control selection matches none of the included controls, it MUST be ignored. In the case that a control selection matches none of the included controls, a warning SHOULD be provided. If a control that was included by the Import Phase is never selected, no error occurs. That control simply does not appear in the output catalog.

Wrapping up the Merge Phase

After the merge phase, the intermediate should now closely resemble the content and structure of the final output catalog. Controls and groups have been included, remapped, de-duplicated, then placed into their final location within the output's structure. Note: there is still an opportunity for included controls or groups to become referenced; and therefore, not eligible for pruning - [See: Pruning and Ordering]in the next phase. -

Regardless of any merge directives, there also likely remains "loose params" that have been propagated forward; these too must be persisted.

Modify Phase

There are two ways profiles may further modify the results of profile resolution: setting parameters and altering controls. These activities are defined as two child objects inside the third step of profile resolution, the Modify Phase.

The following section contains requirements for processing the - modify child of a source profile. -

Setting Parameters

Modification of parameter settings is indicated using the - set-parameter object under - modify. For this section, a given - set-parameter object will be referred to as the - source. -

Profile Resolution Tools MUST adhere to the following requirements for processing "set-parameter":

Altering controls

A control can be altered by an - alterobject inside "modify". The - control-idchild object under the - alterindicates the control to which the alteration is applied. -

Adding contents to controls

Contents may be added to controls using an add directive inside an alter directive. There are two forms of alteration: with implicit and explicit bindings.

Implicit binding

An - add directive with no - by-id child MUST be considered an implicit binding, and will apply to the control as a whole. -

The contents of an implicitly bound add directive MUST be added to the control contents in the target, either after its - title when - position is - starting, or at the end if its position is - ending, or if no valid position is given. -

When an add directive is implicitly bound, the - position values - before and - after MUST be treated like - starting and - ending, respectively. -

Control contents in catalogs must appear in the order - title, param, prop, link, part, control per the OSCAL model documentation. After processing an implicitly bound add directive, the control contents MUST be sorted to appear in the required order: a new - prop appears after any - prop already in the control, when - position is - ending, or not given, or before any - prop in the control when - position is - starting. -

An addition operating on a control with implicit binding and position - starting -

{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: status - value: ready - {{}}{{< highlight xml>}} - -alter: - control-id: a1 - add: - position: starting - props: - - name: basis - value: enumerated - parts: - - name: caution - prose: \\n\\nPending scheduled testing. - {{}}{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: basis - value: enumerated - - name: status - value: ready - parts: - - name: caution - prose: \\n\\nPending scheduled testing. - {{}}

Position is - startingbut the new - partis added after the existing - prop, because - propobjects must always occur first. -

An addition operating on a control with implicit binding and position - ending -

{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: status - value: ready - {{}}{{< highlight xml>}} - -alter: - control-id: a1 - add: - position: starting - props: - - name: basis - value: enumerated - parts: - - name: caution - prose: \\n\\nPending scheduled testing. - {{}}{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: status - value: ready - - name: basis - value: enumerated - parts: - - name: caution - prose: \\n\\nPending scheduled testing. - {{}}

The - positionis - endingso the new - propappears after the existing - prop. -

Explicit binding

An explicit binding on an addition permits inserting new contents anywhere in a control, not only at the top level. An - add directive with a - by-id child MUST be considered an explicit binding, and applies to only a single object inside the control. When an add directive is explicitly bound, the value of the - by-id child MUST correspond to the value of an - id on an object inside the control, and not the control itself. If - by-id does not correspond to such a value, the - add directive MUST be considered inoperative and ignored. An inoperative add directive MAY result in a warning. -

The object with - id equal to the value of - by-id is considered the - target of the addition. -

When - position has a value of - startingor - ending, the contents of the source MUST be added inside the target, either at the start or end of its contents, respectively. -

When - position has a value of - before or after, the contents of the source MUST be added outside the target, either directly before or after it, respectively. -

An addition operating on a control with explicit binding and position - after -

{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: status - value: ready - parts: - - name: recommendations - id: a1.b - parts: - - name: task1 - id: a1.b1 - prose: Collect recycling for pickup - - name: task2 - id: a1.b2 - prose: Sweep surfaces free of dust - {{}}

Note that the - adddirective identifies the object with - id - a1.b1as its target. + href: >- + https://github.com/usnistgov/oscal-content/tree + /master/nist.gov/SP800-53/rev4/xml/NIST_SP-800-53_rev5_catalog.xml + {{}}

Resolving Imports of Profiles

+

If the resource acquired is an OSCAL Profile, the tool MUST apply this + specification to resolve it, then continue processing having imported the resulting catalog.

+

When a profile imports a profile, the subordinate profile SHOULD be + resolved first into a catalog using this specification, before it is imported. This presents the possibility + of circular imports, when a profile is directed to import itself either directly or indirectly.

+

A + circular import occurs when a profile imports an already imported profile, which was + called at an earlier place in the import hierarchy. For example, if profile A imports profile B, and profile + B imports profile A, the second import is circular. (An import at the top can only be circular if a profile + tries to import itself.) If A imports B, B imports C and C imports A, C’s import is circular. +

+

Note that an import can only be circular within the context of + processing a particular profile. In the last example, C’s import would not be circular if invoked in the + context of resolving B by itself.

+

If a processor encounters a + circular import as described above (self-imports are inherently circular), the processor + MUST cease processing and generate an error. +

+
+

A profile identified as + home_profile.yamlimports another one identified as + circular_profile.yaml:

{{< highlight xml>}} - -alter: - control-id: a1 - add: - position: after - by-id: a1.b1 - props: - - name: basis - value: allocated - parts: - - name: caution - prose: Unavailable on weekends + + profile: + id: "home_profile.yaml" + metadata: ~ + imports: + - href: "circular_profile.yaml" + include-controls: ${{ list of selected controls }} + {{}}

In turn this file invokes + home_profile.xml: +

{{< highlight xml>}} + + profile: + id: "circular_profile.yaml" + metadata: ~ + imports: + - href: "home_profile.yaml" + include-controls: ${{ list of selected controls }} + {{}}

Once detected, this circular import will result in an error and no further processing + will take place.

{{< highlight xml>}} + + # Import at href: "circular_profile.yaml" failed. + # Reason: Error during profile import: + # Import at href: "home_profile.yaml" failed. + # Reason: Circular import + {{}} +
+

Multiple imports

+

Each import directive is processed to produce a set of controls. Note + that this occurs even if the same catalog is imported multiple times: each distinct import collects controls + into a separate + selection: +

{{< highlight xml>}} + + profile: + uuid: ~ + metadata: ~ + imports: + - href: "#catalog" + include-controls: + - with-ids: + - ac-1 + - ac-2 + - href: "#catalog" + include-controls: + - with-ids: + - ac-3 + - ac-4 {{}}{{< highlight xml>}} - -control: - id: a1 - title: Basic precautions - props: - - name: status - value: ready - parts: - - name: recommendations - id: a1.b - parts: - - name: task1 - id: a1.b1 - prose: Collect recycling for pickup - - name: caution - prose: Unavailable on weekends - - name: task2 - id: a1.b2 - prose: Sweep surfaces free of dust - props: - - name: basis - value: allocated - {{}}

The - positionis - afterso both objects inside - addare added after (not inside) the target object. Since the target object is inside another - partin the control, the new additions appear there as well. -

Note that the result in this case will be schema-invalid since a - propmay not occur directly following a - part. A better result can be obtained (a better target may be defined) by using two - adddirectives, to insert the new - propseparately before any - partobjects in the target. -

Modifying controls inside controls -

OSCAL supports controls inside controls in the form of - control objects inside - control objects. Because the semantics of the - add and remove directives target any (object) contents of controls, they can be used to target these child controls for modification as well as other contents. Profile resolution tools MUST be able to correctly handle add directives targetting nested controls. This includes directives that target a child control as well as directives that target a parent control and modify the child.

Removing contents from controls

Contents inside controls can be removed from them in catalog targets. In combination with adding new contents, this feature can be used to edit controls as well as amend them.

A - removedirective inside an - alter directive identifies an object or set of objects inside a control to be removed. It does this using any of five child objects. -

An object inside the control MUST be removed from the output if and only if it meets all of the criteria given by the child objects of the remove directive. When more than one child appears under the remove directive, an object would need to match all of them, otherwise it is not removed.

Final Operations

Backmatter Resolution

- back-matter in the result is produced by combining all objects within - back-matter in all source catalogs, with the - back-matter in the input profile. -

Tools MAY check for pruning conditions - [See: Pruning and Ordering] as resources are added as long as the final result is the same as if the pruning had taken place at the end of all resource addition. -

Placing the keep always prop on a resource in a catalog has the effect of ensuring it will always appear in the output produced by any profile importing that catalog, even if nothing links to the resource. This version of the resource will also be the one copied, unless a later-imported catalog or importing profile offers its own version marked to keep always.

Metadata Resolution

The following requirements MUST be followed with regards to the Metadata section of the output catalog:

Beyond these requirements, tools are free to use any and all of the objects inside metadata to provide additional information downstream.

Because of options in producing metadata and especially the requirement for a timestamp, developers and users should note that two different resolutions of the same profile will not, ordinarily, be identical inside - metadata. -

Pruning and Ordering

The processor SHOULD prune the resulting output catalog by removing unused objects.

Implementers should note that pruning need not take place after all other steps. As long as all above criteria are respected, pruning can happen at any time, and doing so is a likely performance and memory overhead improvement.

Tools MUST reorder the output catalog into canonical order - [See: Order of objects in serialization], except where this specification provides different ordering requirements. -

Items of Note

Distinct ID of Objects

Whenever this specification refers to - "distinctiveness", it is to be interpreted as is defined in this section with regards to the object in question. -

For the objects control, param, and group, distinctiveness MUST be determined by the value of the - "id" child object. -

For the object resource, distinctiveness MUST be determined by the value of the - "uuid" - [See: Backmatter Resolution]. -

Dealing with Multiple Formats

Profile Resolution tools SHOULD be able to handle source profiles, imported catalogs, and imported profiles that are serialized in XML, JSON, or YAML. A different serialization format of any given input MUST NOT result in a differing output catalog.

In order to help bootstrap this format management, the following resources are provided for implementers:

The following sections provide additional requirements and guidance for each format.

Requirements and Guidance for XML Output

The final Catalog output, if using XML, MUST be valid as defined by the XML model documentation for the OSCAL Catalog. See - the complete XML reference for model requirements. -

Requirements and Guidance for JSON Output

The final Catalog output, if using JSON, MUST be valid as defined by the JSON model documentation for the OSCAL Catalog. See the - complete JSON reference for model requirements. -

The JSON format, in general use, does not require the preservation of order of fields. As order matters in OSCAL, care should be taken to adhere to the canonical OSCAL order - [See: Order of objects in serialization] when outputting a catalog in JSON. -

Requirements and Guidance for YAML Output

The final Catalog output, if using YAML, MUST be valid as defined by the JSON model documentation for the OSCAL Catalog. YAML is considered a simple variation on the JSON format. Beyond cosmetic differences there are no differences in the information structure between these formats. Therefore, the - complete JSON reference provides model requirements. -

The YAML format, in general use, does not require the preservation of order of fields. As order matters in OSCAL, care should be taken to adhere to the canonical OSCAL order - [See: Order of objects in serialization]when outputting a catalog in YAML. -

Order of objects in serialization

In OSCAL, order of top level objects (those that are direct children of the root element) is considered important only when the XML format is used. To facilitate this, OSCAL provides the concept of - canonical order. This order is provided by the OSCAL Metaschema files for a given document type (see - an overview of Metaschema. -

When the output format is XML, tools MUST use the OSCAL canonical order as described above. When using the YAML or JSON formats, order conveys no meaning, and is not considered important.

Comments in result documents

In an XML-based profile resolution, XML comments are one straightforward way for a processor to record events or conditions without affecting the output's nominal semantics. To support this, while two processors are obliged to return the same catalog XML for the same profile XML inputs, they are not required to match one another's comments, white space usage, attribute order, or processing instructions, only each other's objects, attributes and data content.

One consequence of this is that processes intended to compare two profile resolutions may have to accommodate differences in comments, considering them as insignificant along with other differences in serialization.

\ No newline at end of file + + intermediate: + inclusions: + - id: ${{uuid of #catalog}} + included-controls: + - ac-1 + - ac-2 + - id: ${{uuid of #catalog}} + included-controls: + - ac-3 + - ac-4 + {{}}

The control inclusions are combined and collapsed + in the next phase of processing, + merge(see [See: Merge Phase]) . +

+

Multiple imports against the same resource are allowed, and would + most commonly occur when the profile author is using [See: Mapping + Controls] to create very specific output. + Multiple imports may result in outputs with clashing control IDs if mapping or the merge directive is + not set correctly.

+

Mapping Controls

+

The optional + mapping child of a given + import provides a simple ID remapping for objects included from that specific + import. This provides the means for profile authors to proactively avoid clashing IDs of controls and + other objects. +

+

The Mapping section consists of 5 optional subsections, each + covering a particular type of object. Each subsection is a list of ID mappings to be applied for objects + that are the parent object type.

+

When encountering a given mapping instruction, processors:

+ +

Since mapping is a self contained process inside each import, the + rest of this specification will continue to reference IDs with the assumption that mapping has already + been applied if it was present. Since mapping is most commonly used to avoid clashing IDs, processors + should take care to not handle duplicate IDs until after mapping is complete.

+

Below is a simple example of mapping. The second + import included controls from a different catalog whose ID values happen to + collide. Knowing this, the profile author has remapped those IDs to new values. +

{{< highlight xml>}} + + profile: + uuid: ~ + metadata: ~ + imports: + - href: "#catalog" + include-controls: + - with-ids: + - ac-1 + - ac-2 + - href: "#catalog2" + include-controls: + - with-ids: + - ac-1 + - ac-2 + mapping: + - controls: + - from: ac-1 + to: map-ac-1 + - from: ac-2 + to: map-ac-2 + {{}}

Using the intermediate approach, an internal + data structure resembling the following would result from the above profile:

{{< highlight xml>}} + + intermediate: + metadata: ~ + inclusions: + - id: ${{uuid of #catalog}} + included-controls: + - ac-1 + - ac-2 + - id: ${{uuid of #catalog2}} + included-controls: + - map-ac-1 + - map-ac-2 + {{}}

Including Controls

+

Each import contains directives on which controls from the + imported catalog are to be fetched and used for further processing. Throughout the rest of the + document we will refer to this as "inclusion". + If a control is included, and the source profile makes no other changes to it, it will be present in + the output. Exclusion directives in this section, as well as directives in the following two major + sections (merge and modify), + may make changes to an included control or group that could cause it to appear differently, or not + at all, in the output. Using the intermediate implementation approach, any control(s) that are + included would be extracted from the referenced catalogs, any applicable mappings would be applied, + then the controls(s) would be stored.

+

include-all

+

When an import provides the + include-all directive, ALL controls and groups in the referenced document + (including nested controls) MUST be included. +

{{< highlight xml>}}include-all: ~{{}}

include-controls plus with-id

+

When an import provides the + include-controls directive, with a + with-id child, all controls in the referenced document whose + id match one of the listed + id values MUST be included. +

{{< highlight xml>}} + + include-controls: + - with-ids: + - id: ac-1 + - id: ac-2 + {{}}

include-controls plus + matching

+

Controls may also be included using match patterns against + their IDs. This is useful because related controls (either in a hierarchy, or together in a + group) frequently have related IDs as well.

+

When an import provides the + include-controls directive, with a + matching child, all controls in the referenced document whose + id matches one of the listed + pattern values (Glob matching) MUST be included. +

+

If a + matching object is provided with no + pattern, it MUST be treated as matching nothing. While not providing a + pattern is technically valid, resolution tool implementers should be aware that it is generally + undesirable, and warnings or notices to the user may be appropriate. +

{{< highlight xml>}} + + include-controls: + - matching: + - pattern: "ac*" + {{}}

Dealing with Nested + Controls and Groups

+

In OSCAL, controls may contain child controls. For + instance, in SP 800-53 many controls are supplemented with control enhancements; in OSCAL + these are represented as child controls within parent controls. So parent AC-2 (in a given + catalog) has children AC-2(1) through AC-2(13), for example.

+

By default, inclusion of a control also causes any of + that control's ancestors (or parents) to also be included. By default, inclusion of a control + DOES NOT cause the inclusion of any descendants (or children) of that control to be included. + This applies to both controls and groups.

+

This default behavior can be modified by the following + two optional children of the + include-controls object. +

+
with-child-controls
+

Child controls are, for the most part, treated the same + as top level controls: they can be explicitly included using the selection directives above. + As a shortcut to manually including all of the desired descendant controls of a given control, + OSCAL provides the with-child-controls option. with-child-controls appears as a child object under a given inclusion + directive, and defines additional behavior that is to be executed alongside the parent + inclusion.

+

A + with-child-controls: yes directive on an + include-controls indicates that + all descendant controls of the included control MUST also be included. +

+

A + with-child-controls: no directive on an + include-controls indicates that ONLY the matching control is + included, any descendant children MUST NOT be included. +

+

If no + with-child-controls is provided, the processor MUST consider the + directive as being equivalent to one having + with-child-controls:no. +

+
with-parent-controls
+

Although similar to the above + with-child-controls, the optional + with-parent-controls applies to parents of the included control, and + has the opposite default behavior. In order to maintain the structure of the source catalog, + profile resolution includes all parents of an included control by default. If a profile author + wants to change this structure, they should use an exclude directive that lists all of the + undesired parents. As a shortcut for this, + with-parent-controls provides the following functionality: +

+

A + with-parent-controls: yes directive on an + include-controls indicates that + all parent controls of the included control MUST also be included. +

+

A + with-parent-controls: no directive on an + include-controls indicates that ONLY the matching control is + included, any parent MUST NOT be included. +

+

If no + with-parent-controls is provided, the processor MUST consider the + directive as being equivalent to one having + with-parent-controls:yes. +

+

exclude-controls

+

Exclusions work the same way as inclusions, except with + the opposite effect - the indicated control(s) do not appear in the target catalog.

+

Any control designated to be both included and excluded, + MUST be excluded. This holds irrespective of the specificity of the selection for inclusion or + exclusion. For example, if AC-1 is included by id + ac-1 and excluded by matching + ac.*, it is excluded. +

+

When + exclude-controls has at least one + with-ids or + matching directive, the processor MUST follow the same rules as + defined in the relevant sections above for these directives, but exclude instead of include + any controls. All optional features (with-child-controls, etc.) also + apply to exclusion directives. +

+

Redundant Inclusions and Exclusions +

+

A given + import may have any number of inclusion statements and any number of + exclusion statements. Their effect is cumulative; any control that is included (or excluded) + more than once MUST be considered to be included (or excluded) only once. In other words, a + given control being included or excluded more than once has no effect. Exclusion still takes + priority over inclusion (see above). +

+

Note that this requirement only applies to controls + included within the context of a single import. Controls with duplicate IDs included under a + different + import are not discarded. Also note that this redundancy pruning + happens after any relevant mappings have been applied. +

+

Handling Params

+

Any + paramthat is not directly under a control is referred to as a + looseparam. +

+

All loose params from both imported documents and the + profile source MUST be included. These params will be kept in the final output if the document + contains any references to them, and discarded otherwise. See + [See: Pruning and Ordering]. Since new references can + be created during the + modify phase, tools should be careful not to prune params without + fully understanding the final state of the output document. +

+

Handling Groups

+

Some source catalogs use + group objects to place controls into arbitrary groupings. Tools will + need to be aware of these groups when executing the "merge" phase below, as they will + duplicated into the output under the "as-is" mode and can be referenced in "custom" mode. The + naïve intermediate approach would keep all groups until all other phases are complete, but + implementations may find it more performant to look ahead and prune unused groups early. +

+

Avoiding Implementation Pitfalls

+

In order to ensure that implementers have as much + flexibility as possible, requirements in this section have purposefully been kept minimal. + Below are some common issues for implementers to be aware of:

+ +

Wrapping up the Import Phase

+

At this point all requirements for content importing and + control inclusion have been covered. If using the intermediate approach, the processor should + have an intermediate that contains: a set of included controls and all of their child + informational (non-control, non-group) objects, any relevant + group objects and their informational content, and a set of included + "loose params" + [See: Handling Params] (zero to many). The general + structure of the intermediate would match that of the imported catalogs (i.e. nested controls + remain nested, grouped controls remain grouped). +

+

Merge Phase

+

Profiles may contain a + mergesection, where directives are given to instruct the processor + how to combine the set of included objects collected during the Import Phase. + mergehas two parts: a "combine" directive, and a "structuring" + directive. +

+

It is RECOMMENDED that tools apply the "combine" + directive to the intermediate generated by the Import phase first, then apply the + "structuring" directive.

+

The following section contains requirements for + processing the + merge child of a source profile. +

+

The "combine" Directive

+

+ combineis an optional child of + mergethat provides the rules for dealing with objects that have + duplicate (or clashing) distinct IDs + [See: Distinct ID of Objects]. +

+

There are two valid combination methods provided by + OSCAL, provided by the + methodchild of + combine: +

+ +

Note that "merge: combine" is deprecated, and MUST be + considered undefined behavior when encountered.

+

In order to apply the combination method, IDs of each + control explicitly included are compared against one another. As IDs are unique across entire + OSCAL documents, different imports or any groupings have no bearing on collision. Processing + requirements for each method are described below.

+

No Combine Directive

+

If no + merge directive is given in the profile, or if a + merge is given without a + combine, merge conflicts MUST be treated as if + method: keep was given. For example, a profile with no + merge directive: +

{{< highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-all: ~ + {{}}

is the same as

{{< highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-all: ~ + merge: + combine: + method: keep + flat: ~ + {{}}

+ method:keep +

+

When a merge is indicated by + method:keep, or when no merge directive is given, the + keepcombination rule is used. Any control with the same distinctive ID + [See: Distinct ID of Objects]MUST NOT not merged. + (They are kept.) +

{{< highlight xml>}} + + merge: + combine: + method: keep + {{}}

Under this directive, colliding + controls will result in invalid results, as they will both appear in the results with + the same ID. Accordingly, this setting may be useful in ensuring integrity of references + to controls as given in the profile: if any included control is called only once, + clashing controls will not be produced and validation will succeed.

{{< highlight + xml>}} + + profile: + imports: + - href: #catalog1 + include-controls: + - with-ids + id: ac-1 + id: ac-2 + - href: #catalog1 + include-controls: + - with-ids + id: ac-1 + id: ac-2 + merge: + combine: + method: keep + {{}}

In the intermediate (showing + control inclusions):

{{< highlight xml>}} + + intermediate: + inclusions: + - explicitly-included-controls: + - ac-1 + - ac-2 + - ac-1 + - ac-2 + {{}}

In this case, downstream + errors should be expected: the two + ac-1 controls clash with each other, as do the two + ac-2 controls. +

+

Processors SHOULD provide a warning under the + merge:keep directive when duplicate controls are detected. The processor MAY throw + an error and cease processing (short-circuiting a certain future error) when + duplicate controls are detected under the merge:keep directive.

+

+ method:use-first +

{{< highlight xml>}} + + merge: + combine: + method: use-first + {{}}

When the + "use-first"combination rule is applied, and controls that share a distinctive ID + are found, the first control encountered MUST be kept, the rest MUST be discarded. + "First" MUST be determined by a top-down, depth-first traversal of the source + profile's import hierarchy. +

+
{{< highlight xml>}} + + profile: + imports: + - href: #catalog1 + include-controls: + - with-ids + id: ac-1 + id: ac-3 + - href: #catalog1 + include-controls: + - with-ids + id: ac-1 + id: ac-2 + merge: + combine: + method: use-first + {{}}

In the intermediate(showing control inclusions):

{{< + highlight xml>}} + + intermediate: + inclusions: + - explicitly-included-controls: + - ac-1 (From catalog1) + - ac-3 + - ac-2 + {{}}
+

+ method:merge +

+

Deprecated, unspecified behavior.

+

The "structuring" + Directive

+

This section describes how a profile may + dictate the structure of the target + catalog, apart from its + metadata or + back-matter. Optionally, one of three "structuring" + directives can be included as a child of + merge: + flat, + as-isand + custom. When one of these appears, it is the selected + structuring directive. If more than one appears, processors MUST generate an error + and cease processing. Processing requirements for each are given below: +

+

No Structuring Directive +

+

If no + merge directive is given in the profile, or if a + merge is given without a structuring directive, + structuring the output MUST be treated as if the structuring directive + flat was given. For example, a profile with no + merge directive: +

{{< highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-all: ~ + {{}}

is the same as

{{< + highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-all: ~ + merge: + combine: + method: keep + flat: ~ + {{}}

"flat" +

+

Profiles with the "flat" merge directive + MUST be resolved as unstructured catalogs, with no grouping or nesting of + controls.

+

Unstructured catalog output MUST be + produced by adhering to the following requirements:

+ +

An example of flat structuring is + provided below

{{< highlight xml>}} + + catalog: + groups: + - groupA + - ac-1 + - ac-2 + - groupB + - bc-1 + {{}}{{< highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-controls: + with-ids: + - ac-1 + - ac-2 + - bc-1 + merge: + combine: + method: keep + flat: ~ + {{}}{{< highlight xml>}} + + intermediate: + controls: + - ac-1 + - ac-2 + - bc-1 + {{}}

+ as-is +

+

An + as-is directive is used to reproduce the + structure of the source documents in the target catalog. +

+

Processors MUST handle the + as-is directive by adhering to the following + requirements: +

+ +

Example:

{{< highlight xml>}} + + catalog: + groups: + - groupA + - ac-1 + - ac-2 + - groupB + - bc-1 + {{}}{{< highlight xml>}} + + profile: + imports: + - href: #catalogURI + include-controls: + with-ids: + - ac-1 + - ac-2 + - bc-1 + merge: + combine: + method: keep + as-is: ~ + {{}}{{< highlight xml>}} + + intermediate: + #In this approach, the original hierarchy of the controls under the + groups is stored, + #but is not shown in this example. + controls: + - ac-1 + - ac-2 + - bc-1 + groups: + - groupA + - groupB + {{}}

+ custom +

+

The + customdirective provides the target + catalog with a custom structure. A one-to-one mapping of the + desired structure of the target catalog is defined alongside + control matching instructions, resulting in a strictly controlled + output catalog. +

+
Creating + Custom Groups
+

A + groupobject given under + custom MUST result in a + group with the exact same content + (excluding + insert-controls) in the target catalog. +

+

If the ID of the group + matches the ID of a group that has been included during the import + phase, all contents inside the group, including + title, + param, + prop and + part objects MUST be copied into the + target, appearing in the same order as in the source. +

+

Note that groups defined in + custom may vary from fully featured to + minimally instantiated. This includes arbitrary nesting of such + groups inside of one another. No groups other than those + explicitly declared should appear in the output catalog. +

+
Inserting + Controls
+

The + insert-controls directive may appear + anywhere under + custom, whether as a direct child or + inside any of the defined groups. Inside insert-controls, + include-controls and + include-all from the Import Phase + [See: Import Phase]are + used with the same basic behavior to configure which controls are + selected and inserted at the current location. +

+

In order to provide clarity, + controls that match the various conditions of these inclusion + directives inside the + custom object will be referred to as + "selected" instead of "included". Only directly selected controls + will appear in the target catalog. +

+

When processing the control + selection of a custom element, the + behavior defined in this section MUST be followed to generate the + output.

+

A + insert-controls with an + include-controls child results in the + following behavior: +

+ +

An + insert-controls with an + include-all child results in all included + controls being selected and inserted. They are given in the same + order as they appeared in the input control selection(s). +

+

+ insert-controls can also indicate the + order that the selected controls are to be emitted in the result + catalog using an + order child. Three values MUST be + supported and handled as specified below: +

+ +

In the case that a control + selection matches none of the included controls, it MUST be + ignored. In the case that a control selection matches none of the + included controls, a warning SHOULD be provided. If a control that + was included by the Import Phase is never selected, no error + occurs. That control simply does not appear in the output catalog. +

+

Wrapping + up the Merge Phase

+

After the merge phase, the + intermediate should now closely resemble the content and structure + of the final output catalog. Controls and groups have been + included, remapped, de-duplicated, then placed into their final + location within the output's structure. Note: there is still an + opportunity for included controls or groups to become referenced; + and therefore, not eligible for pruning + [See: Pruning and + Ordering]in the next phase. +

+

Regardless of any merge + directives, there also likely remains "loose params" that have + been propagated forward; these too must be persisted.

+

Modify + Phase

+

There are two ways profiles + may further modify the results of profile resolution: setting + parameters and altering controls. These activities are defined as + two child objects inside the third step of profile resolution, the + Modify Phase.

+

The following section + contains requirements for processing the + modify child of a source profile. +

+

Setting + Parameters

+

Modification of parameter + settings is indicated using the + set-parameter object under + modify. For this section, a given + set-parameter object will be referred to + as the + source. +

+

Profile Resolution Tools + MUST adhere to the following requirements for processing + "set-parameter":

+ +

Altering + controls

+

A control can be altered by + an + alterobject inside "modify". The + control-idchild object under the + alterindicates the control to which the + alteration is applied. +

+

Adding + contents to controls

+

Contents may be added to + controls using an add directive inside an alter directive. There + are two forms of alteration: with implicit and explicit bindings. +

+
Implicit + binding
+

An + add directive with no + by-id child MUST be considered an + implicit binding, and will apply to the control as a whole. +

+

The contents of an + implicitly bound add directive MUST be added to the control + contents in the target, either after its + title when + position is + starting, or at the end if its position + is + ending, or if no valid position is + given. +

+

When an add directive is + implicitly bound, the + position values + before and + after MUST be treated like + starting and + ending, respectively. +

+

Control contents in catalogs + must appear in the order + title, param, + prop, link, + part, control + per the OSCAL model documentation. After processing an implicitly + bound add directive, the control contents MUST be sorted to appear + in the required order: a new + prop appears after any + prop already in the control, when + position is + ending, or not given, or before any + prop in the control when + position is + starting. +

+
+

An addition operating on a control with implicit binding and + position + starting +

{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: status + value: ready + {{}}{{< highlight xml>}} + + alter: + control-id: a1 + add: + position: starting + props: + - name: basis + value: enumerated + parts: + - name: caution + prose: \\n\\nPending scheduled testing. + {{}}{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: basis + value: enumerated + - name: status + value: ready + parts: + - name: caution + prose: \\n\\nPending scheduled testing. + {{}}

Position is + startingbut the new + partis added after the existing + prop, because + propobjects must always occur + first. +

+
+
+

An addition operating on a control with implicit binding and + position + ending +

{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: status + value: ready + {{}}{{< highlight xml>}} + + alter: + control-id: a1 + add: + position: starting + props: + - name: basis + value: enumerated + parts: + - name: caution + prose: \\n\\nPending scheduled testing. + {{}}{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: status + value: ready + - name: basis + value: enumerated + parts: + - name: caution + prose: \\n\\nPending scheduled testing. + {{}}

The + positionis + endingso the new + propappears after the existing + prop. +

+
+
Explicit + binding
+

An explicit binding on an + addition permits inserting new contents anywhere in a control, not + only at the top level. An + add directive with a + by-id child MUST be considered an + explicit binding, and applies to only a single object inside the + control. When an add directive is explicitly bound, the value of + the + by-id child MUST correspond to the value + of an + id on an object inside the control, and + not the control itself. If + by-id does not correspond to such a + value, the + add directive MUST be considered + inoperative and ignored. An inoperative add directive MAY result + in a warning. +

+

The object with + id equal to the value of + by-id is considered the + target of the addition. +

+

When + position has a value of + startingor + ending, the contents of the source MUST + be added inside the target, either at the start or end of its + contents, respectively. +

+

When + position has a value of + before or after, the contents of the source MUST be + added outside the target, either directly before or after it, + respectively. +

+
+

An addition operating on a control with explicit binding and + position + after +

{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: status + value: ready + parts: + - name: recommendations + id: a1.b + parts: + - name: task1 + id: a1.b1 + prose: Collect recycling for pickup + - name: task2 + id: a1.b2 + prose: Sweep surfaces free of dust + {{}}

Note that the + adddirective identifies the object + with + id + a1.b1as its target. +

{{< highlight xml>}} + + alter: + control-id: a1 + add: + position: after + by-id: a1.b1 + props: + - name: basis + value: allocated + parts: + - name: caution + prose: Unavailable on weekends + {{}}{{< highlight xml>}} + + control: + id: a1 + title: Basic precautions + props: + - name: status + value: ready + parts: + - name: recommendations + id: a1.b + parts: + - name: task1 + id: a1.b1 + prose: Collect recycling for pickup + - name: caution + prose: Unavailable on weekends + - name: task2 + id: a1.b2 + prose: Sweep surfaces free of dust + props: + - name: basis + value: allocated + {{}}

The + positionis + afterso both objects inside + addare added after (not inside) + the target object. Since the target object is inside + another + partin the control, the new + additions appear there as well. +

+

Note that the result in this case will be schema-invalid + since a + propmay not occur directly + following a + part. A better result can be + obtained (a better target may be defined) by using two + adddirectives, to insert the new + propseparately before any + partobjects in the target. +

+
+
Modifying + controls inside controls +
+

OSCAL supports controls + inside controls in the form of + control objects inside + control objects. Because the semantics of + the + add and remove directives target any + (object) contents of controls, they can be used to target these + child controls for modification as well as other contents. Profile + resolution tools MUST be able to correctly handle add directives + targetting nested controls. This includes directives that target a + child control as well as directives that target a parent control + and modify the child. +

+

Removing + contents from controls

+

Contents inside controls can + be removed from them in catalog targets. In combination with + adding new contents, this feature can be used to edit controls as + well as amend them.

+

A + removedirective inside an + alter directive identifies an object or + set of objects inside a control to be removed. It does this using + any of five child objects. +

+

An object inside the + control MUST be removed from the output if and only if it meets + all of the criteria given by the child objects of the remove + directive. When more than one child appears under the remove + directive, an object would need to match all of them, otherwise it + is not removed.

+ +

Final + Operations

+

+ Backmatter Resolution

+

+ back-matter in the result is produced by + combining all objects within + back-matter in all source catalogs, with + the + back-matter in the input profile. +

+ +

Tools MAY check for pruning + conditions + [See: Pruning and + Ordering] as resources are added as long as the final result + is the same as if the pruning had taken place at the end of all + resource addition. +

+

Placing the keep always prop + on a resource in a catalog has the effect of ensuring it will + always appear in the output produced by any profile importing that + catalog, even if nothing links to the resource. This version of + the resource will also be the one copied, unless a later-imported + catalog or importing profile offers its own version marked to keep + always.

+

Metadata + Resolution

+

The following requirements + MUST be followed with regards to the Metadata section of the + output catalog:

+ +

Beyond these requirements, + tools are free to use any and all of the objects inside metadata + to provide additional information downstream.

+

Because of options in + producing metadata and especially the requirement for a timestamp, + developers and users should note that two different resolutions of + the same profile will not, ordinarily, be identical inside + metadata. +

+

Pruning + and Ordering

+

The processor SHOULD prune + the resulting output catalog by removing unused objects.

+ +

Implementers should note + that pruning need not take place after all other steps. As long as + all above criteria are respected, pruning can happen at any time, + and doing so is a likely performance and memory overhead + improvement.

+

Tools MUST reorder the + output catalog into canonical order + [See: Order of objects in + serialization], except where this specification provides + different ordering requirements. +

+

Items of + Note

+

Distinct + ID of Objects

+

Whenever this specification + refers to + "distinctiveness", it is to be interpreted as is defined in this + section with regards to the object in question. +

+

For the objects control, + param, and group, distinctiveness MUST be determined by the value + of the + "id" child object. +

+

For the object resource, + distinctiveness MUST be determined by the value of the + "uuid" + [See: Backmatter + Resolution]. +

+

Dealing + with Multiple Formats

+

Profile Resolution tools + SHOULD be able to handle source profiles, imported catalogs, and + imported profiles that are serialized in XML, JSON, or YAML. A + different serialization format of any given input MUST NOT result + in a differing output catalog.

+

In order to help bootstrap + this format management, the following resources are provided for + implementers:

+ +

The following sections + provide additional requirements and guidance for each format.

+

+ Requirements and Guidance for XML Output

+

The final Catalog output, if + using XML, MUST be valid as defined by the XML model documentation + for the OSCAL Catalog. See + the + complete XML reference for model requirements. +

+

+ Requirements and Guidance for JSON Output

+

The final Catalog output, if + using JSON, MUST be valid as defined by the JSON model + documentation for the OSCAL Catalog. See the + complete + JSON reference for model requirements. +

+

The JSON format, in general + use, does not require the preservation of order of fields. As + order matters in OSCAL, care should be taken to adhere to the + canonical OSCAL order + [See: Order of objects in + serialization] when outputting a catalog in JSON. +

+

+ Requirements and Guidance for YAML Output

+

The final Catalog output, if + using YAML, MUST be valid as defined by the JSON model + documentation for the OSCAL Catalog. YAML is considered a simple + variation on the JSON format. Beyond cosmetic differences there + are no differences in the information structure between these + formats. Therefore, the + complete + JSON reference provides model requirements. +

+

The YAML format, in general + use, does not require the preservation of order of fields. As + order matters in OSCAL, care should be taken to adhere to the + canonical OSCAL order + [See: Order of objects in + serialization]when outputting a catalog in YAML. +

+

Order of + objects in serialization

+

In OSCAL, order of top level + objects (those that are direct children of the root element) is + considered important only when the XML format is used. To + facilitate this, OSCAL provides the concept of + canonical order. This order is provided by the + OSCAL Metaschema files for a given document type (see + an + overview of Metaschema. +

+

When the output format is + XML, tools MUST use the OSCAL canonical order as described above. + When using the YAML or JSON formats, order conveys no meaning, and + is not considered important.

+

Comments + in result documents

+

In an XML-based profile + resolution, XML comments are one straightforward way for a + processor to record events or conditions without affecting the + output's nominal semantics. To support this, while two processors + are obliged to return the same catalog XML for the same profile + XML inputs, they are not required to match one another's comments, + white space usage, attribute order, or processing instructions, + only each other's objects, attributes and data content.

+

One consequence of this is + that processes intended to compare two profile resolutions may + have to accommodate differences in comments, considering them as + insignificant along with other differences in serialization.

\ No newline at end of file