Creating a Control Catalog
This tutorial covers creating a basic OSCAL control catalog.
Before reading this tutorial you should:
- Have some familiarity with the XML, JSON, or YAML formats.
- Read the OSCAL control layer overview.
- Review the OSCAL catalog model overview.
What is an OSCAL Catalog?
A catalog is a collection of security and privacy controls, and related control enhancements.
An OSCAL Control Catalog is a machine-readable representation of a catalog, expressed using the OSCAL Catalog model, which includes contextualizing documentation and metadata.
The OSCAL Catalog model provides machine-readable formats in XML, JSON, and YAML, which support representing an equivalent set of catalog information. Examples in this tutorial are provided for XML, JSON, and YAML to show the equivalent representations.
This tutorial describes the formatting of such a catalog using the OSCAL Catalog model XML format.
For the purpose of this tutorial, an example prose catalog has been created based on a short excerpt from ISO/IEC 27002:2013, Information technology — Security techniques — Code of practice for information security controls. This work is provided here under copyright "fair use" for non-profit, educational purposes only. Copyrights for this work are held by the publisher, the International Organization for Standardization (ISO).
This tutorial illustrates how to create an OSCAL control catalog using the OSCAL XML, JSON, and YAML formats, which each implement the OSCAL catalog model. The OSCAL project provides an XML Schema and documentation, which is useful for validating an XML catalog, and a JSON Schema and documentation, which is useful for validating JSON and YAML catalogs. However, this tutorial is not focusing on the schemas themselves, but rather on the formatting the sample control catalog listed above in OSCAL.
Creating an OSCAL Catalog
The examples below illustrate the top-level structure of the OSCAL control catalog model.
| |
The root of the OSCAL control catalog model is <catalog>.
In the example above, the contents of the <catalog> element is provided as empty data items. These are included to illustrate the content model of an OSCAL catalog, and we will be covering each element's syntax later in this tutorial.
The @id attribute (on line 3) is the document's universally unique identifier (UUID), a unique 128-bit number displayed as a string of hyphenated hexadecimal digits as defined by RFC 4122. OSCAL documents use a version 4 UUID (randomly generated) to uniquely identify the document.
A <catalog> contains:
<metadata>(required) - Provides document metadata for the catalog. This is explored below in the defining the catalog's metadata section of this tutorial.<group>(optional) - Allows for grouping of<control>and other<group>elements. Zero or more<group>elements may be used. This is explored below in the representing groups in a catalog section of this tutorial.<control>(optional) - Defines a given control in the catalog. Zero or more<control>elements may be used, and a<control>can be nested within another<control>element to identify an optional portion of a control that can be managed as a discrete unit (e.g., a control enhancement). This is explored below in the representing control information section of this tutorial.<back-matter>(optional) – Contains references used within the catalog. Use of<back-matter>is not covered in this tutorial.
| |
The root of the OSCAL control catalog model is the catalog property.
In the example above, the contents of the catalog property is provided as empty object properties. These are included to illustrate the content model of an OSCAL catalog, and we will be covering each child property's syntax later in this tutorial.
The id property (on line 3) is the document's universally unique identifier (UUID), a unique 128-bit number displayed as a string of hyphenated hexadecimal digits as defined by RFC 4122. OSCAL documents use a version 4 UUID (randomly generated) to uniquely identify the document.
A catalog contains the following props:
metadata(required) - Provides document metadata for the catalog. This is explored below in the defining the catalog's metadata section of this tutorial.groups(optional) - Allows for grouping ofcontrolsand othergroupsproperties. Contains one or more group objects. This is explored below in the representing groups in a catalog section of this tutorial.controls(optional) - Contains one or more control objects, which can nest other control objects to identify an optional portion of a control that can be managed as a discrete unit (e.g., a control enhancement). This is explored below in the representing control information section of this tutorial.back-matter(optional) – Contains references used within the catalog. Use ofback-matteris not covered in this tutorial.
| |
The root of the OSCAL control catalog model is the catalog item.
In the example above, the contents of the catalog item is provided as keys with empty collections. These are included to illustrate the content model of an OSCAL catalog, and we will be covering their syntax later in this tutorial.
The id key (on line 3) is the document's universally unique identifier (UUID), a unique 128-bit number displayed as a string of hyphenated hexadecimal digits as defined by RFC 4122. OSCAL documents use a version 4 UUID (randomly generated) to uniquely identify the document.
A catalog contains:
metadata(required) - Provides document metadata for the catalog. This is explored below in the defining the catalog's metadata section of this tutorial.groups(optional) - Allows for grouping ofcontrolsand othergroupskeys. Contains one or more group items. This is explored below in the representing groups in a catalog section of this tutorial.controls(optional) - Contains one or more control items, which can nest other control items to identify an optional portion of a control that can be managed as a discrete unit (e.g., a control enhancement). This is explored below in the representing control information section of this tutorial.back-matter(optional) – Contains references used within the catalog. Use ofback-matteris not covered in this tutorial.
We will now discuss each of these data structures in the following sections and identify how they each can be used to represent our catalog.
Defining the Catalog's Metadata
The metadata section of the control catalog contains data about the catalog document. This section has an identical structure which is used consistently across all OSCAL models.
This tutorial focuses only on the mandatory data required in the metadata section. A separate tutorial will focus on the full syntax available in the metadata section.
The metadata section must include:
- the title of the catalog
- the time the catalog was last modified
- the version of OSCAL used
The following additional data items from the sample security catalog also need to be defined in the OSCAL catalog.
Version: 1.0
Published: 02.02.2020
Last Modified: 02.10.2020
All of these data items can be represented as follows:
| |
Breaking this down line-by-line you will notice the following:
- Line 1: The
<metadata>element, which contains the document's metadata. - Line 2: The document's title (i.e.,
Sample Security Catalog) is provided using<title>element. The document's title is a mandatory field for an OSCAL Catalog. - Line 3: The date when the document was published (i.e.,
2020-02-02T11:01:04.736-04:00) is provided using<published>element. This date is provided using the RFC 3339 format with a required timezone. The published date is not a mandatory field for an OSCAL Catalog. - Line 4: The date when the document was last modified (i.e.,
2020-12-18T16:23:23.811-05:00) is provided using<last-modified>element. This date is provided using the RFC 3339 format with a required timezone. The last modified date is a mandatory field for an OSCAL Catalog. - Line 5: The version of the document (i.e.,
1.0) is provided using the<version>element. This can be a numeric version, commit hash, or any other suitable version identifier. The document version is a mandatory field for an OSCAL Catalog. - Line 6: Finally, the OSCAL version is provided using the
<oscal-version>element, which represents the revision of the OSCAL Catalog model for which the catalog was created under. The current OSCAL version is1.0.0-rc1.
| |
Breaking this down line-by-line you will notice the following:
- Line 2: The
metadataproperty, who's value is an object which contains properties representing the document's metadata. - Line 3: The document's title (i.e.,
Sample Security Catalog) is provided usingtitleproperty. The document's title is a mandatory field for an OSCAL catalog. - Line 4: The date when the document was published (i.e.,
2020-02-02T11:01:04.736-04:00) is provided using thepublishedproperty. This date is provided using the RFC 3339 format with a required timezone. The published date is not a mandatory field for an OSCAL Catalog. - Line 5: The date when the document was last modified (i.e.,
2020-12-18T16:23:23.811-05:00) is provided using thelast-modifiedproperty. This date is provided using the RFC 3339 format with a required timezone. The last modified date is a mandatory field for an OSCAL Catalog. - Line 6: The version of the document (i.e.,
1.0) is provided using theversionproperty. This can be a numeric version, commit hash, or any other suitable version identifier. The document version is a mandatory field for an OSCAL Catalog. - Line 7: Finally, the OSCAL version is provided using the
oscal-versionproperty, which represents the revision of the OSCAL Catalog model for which the catalog was created under. The current OSCAL version is1.0.0-rc1.
| |
Breaking this down line-by-line you will notice the following:
- Line 1: The
metadatablock, who's value is a mapping of keys representing the document's metadata. - Line 2: The document's title (i.e.,
Sample Security Catalog) is provided usingtitlekey. The document's title is a mandatory field for an OSCAL Catalog. - Line 3: The date when the document was published (i.e.,
2020-02-02T11:01:04.736-04:00) is provided using thepublishedkey. This date is provided using the RFC 3339 format with a required timezone. The published date is not a mandatory field for an OSCAL Catalog. - Line 4: The date when the document was last modified (i.e.,
2020-12-18T16:23:23.811-05:00) is provided using thelast-modifiedkey. This date is provided using the RFC 3339 format with a required timezone. The last modified date is a mandatory field for an OSCAL Catalog. - Line 5: The version of the document (i.e.,
1.0) is provided using theversionkey. This can be a numeric version, commit hash, or any other suitable version identifier. The document version is a mandatory field for an OSCAL Catalog. - Line 6: Finally, the OSCAL version is provided using the
oscal-versionkey, which represents the revision of the OSCAL Catalog model for which the catalog was created under. The current OSCAL version is1.0.0-rc1.
Representing Groups in a Catalog
An OSCAL catalog allows for the organization of related controls using groups. A catalog group can represent families of controls or other organizational structures, such as sections in a control catalog.
Analyzing the body of the Catalog Sample, we observe that the catalog has multiple sections and sub-sections as follows:
1 Organization of Information Security
1.1 Internal Organization
Objective: [...]
1.1.1 Information security roles and responsibilities
[...]
1.1.2 Segregation of duties
[...]
2 Access Control
2.1 Business Requirements of Access Control
Objective: [...]
2.1.1 Access control policy
[...]
2.1.2 Access to networks and network services
[...]
In the above, controls are organized into two top-level groups: 1 Organization of Information Security and 2 Access Control. Each of these sections have sub-sections that define an Objective, and these sub-sections then define a series of controls.
The first section in the example catalog is represented in an OSCAL catalog as follows:
| |
Breaking this down line-by-line you will notice the following:
Line 1 declares a new group using the
<group>element. The@idattribute defines the group's required unique identifiers1. A group's unique identifier must be unique within the document. An identifier in OSCAL is a string that may not contain spaces or colons.Line 2 provides the group's title using the
<title>element. A title can be simple text or can include html markup.Line 3 defines a property of the group using the
<prop>element. This property element has a@name="label, which defines the name of the property (i.e.label), and textual content1, which defines the property's value. A property with the namelabelprovides the text label that can be prepended to the title when formatting the content for human readability.In OSCAL, properties are commonly used constructs that allow for arbitrary name/value data to be defined. This name/value data helps to describe the containing element. Most major XML elements within OSCAL allow for properties to be defined. Names, like identifiers, are strings that may not contain spaces or colons.
Lines 4 thru 6 declare a new child group of the group defined on line 1, and is nested/indented within the context of the parent group to indicate it is a child. This child group represents the sub-section
1.1 Internal Organization, along with its title (line 5) and label (line 6). Notice that the title and label are declared in the same way as the parent section, using<title>and<prop>elements.Lines 7 thru 10 define the sub-section's objective using a
<part>element and child content. A part requires:a unique identifier specified by the
@idattribute, which identifies the part.a name specified by the
@nameattribute, which identifies the type of the part. The nameobjectiveis used to indicate that the part represents an objective.A sequence of child HTML prose block elements. In this example, the
<p>element is used to represent a paragraph of text. The prose model allows for other structural markup to be included within each block, to indicate emphasis (italics), importance (bold), etc.While not illustrated here, a
<part>element can also include child parts to denote a hierarchy of text. This will be covered in a future tutorial.
| |
Breaking this down line-by-line you will notice the following:
Line 2 declares a new group using a group object in the
groupsarray.Line 3 where the
idproperty defines the group's required unique identifiers1. A group's unique identifier must be unique within the document. An identifier in OSCAL is a string that may not contain spaces or colons.Line 4 provides the group's title using the
titleproperty. A title can be simple text or can include Markdown.Lines 5 thru 8 define an array of properties for the group using the
propertiesproperty.On line 6 the property's name
labelis provided using thenameJSON property. A property with the namelabelprovides the text label that can be prepended to the title when formatting the content for human readability.On line 7 the property's value
1is provided using thevalueJSON property.In OSCAL, properties are commonly used constructs that allow for arbitrary name/value data to be defined. This name/value data helps to describe the containing object. Most major JSON objects within OSCAL allow for properties to be defined. Names, like identifiers, are strings that may not contain spaces or colons.
Lines 9 thru 22 declare a new child group of the group defined on line 1, and is nested/indented within the context of the parent group to indicate it is a child. This child group represents the sub-section
1.1 Internal Organization, along with its title (line 11) and label (lines 12 thru 15). Notice that the title and label are declared in the same way as the parent section, using thetitleandpropertiesJSON properties.Lines 16 thru 20 define the sub-section's objective using the
partsproperty and associated array of objects. In this case we have a single part object. A part requires:a unique identifier specified by the
idproperty (line 17), which identifies the part.a name specified by the
nameproperty (line 18), which identifies the type of the part. The nameobjectiveis used to indicate that the part represents an objective.A string of Markdown prose content (line 19) contained by the
proseproperty. In Markdown double newlines are used to delineate different paragraphs of text. These newlines are escaped in JSON, since all string content needs to be on a single line.The OSCAL prose model allows for other structural markup to be included within Markdown text, to indicate emphasis (italics), importance (bold), etc.
While not illustrated here, a
partcan also include child parts to denote a hierarchy of text. This will be covered in a future tutorial.
| |
Breaking this down line-by-line you will notice the following:
Line 1 declares a list of group items using the
groupskey.Line 2 starts a new group item and the
idkey defines the group's required unique identifiers1. A group's unique identifier must be unique within the document. An identifier in OSCAL is a string that may not contain spaces or colons.Line 3 provides the group's title using the
titlekey. A title can be simple text or can include Markdown.Lines 4 thru 6 define a list of properties for the group using the
propertieskey.Line 5 starts a new property item and the
namekey provides the namelabelfor the property. A property with the namelabelprovides the text label that can be prepended to the title when formatting the content for human readability.On line 6 the key
valueprovides the property's value1.In OSCAL, properties are commonly used constructs that allow for arbitrary name/value data to be defined. This name/value data helps to describe the containing item. Most major YAML items within OSCAL allow for properties to be defined. Names, like identifiers, are strings that may not contain spaces or colons.
Lines 7 thru 19 declare a new child group of the group defined on line 2, and is nested/indented within the context of the parent group to indicate it is a child. This child group represents the sub-section
1.1 Internal Organization, along with its title (line 9) and label (lines 10 thru 12). Notice that the title and label are declared in the same way as the parent section, using thetitleandpropertieskeys.Lines 13 thru 18 define the sub-section's objective using the
partsproperty and associated array of objects. In this case we have a single part object. A part requires:a unique identifier specified by the
idproperty (line 17), which identifies the part.a name specified by the
nameproperty (line 18), which identifies the type of the part. The nameobjectiveis used to indicate that the part represents an objective.A string of Markdown prose content (lines 17 and 18) contained by the
prosekey. In Markdown double newlines are used to delineate different paragraphs of text. Since multiline strings are supported in YAML, YAML markdown is more natural to write, as compared to JSON Markdown where character like\nneed to be escaped.The OSCAL prose model allows for other structural markup to be included within Markdown text, to indicate emphasis (italics), importance (bold), etc.
While not illustrated here, a
partcan also include child parts to denote a hierarchy of text. This will be covered in a future tutorial.
The sections of the original document have numbers, and therefore, we base the identifier values for each group on the heading numbers of the sections and the subsections, with a leading character such as s in front as a way to avoid any potential id conflicts.
Section 2 follows suit, resulting in the following representation of both sections:
| |
| |
| |
Representing Control Information
In the catalog sample, controls are defined following the Objective in each section. Each control in the sample provides a control statement, expressing the control's requirement; an Implementation Guidance section, providing guidelines to consider when implementing the control; and often some additional information titled Other information.
The structure of the first control, 1.1.1 Information security roles is represented below:
1.1.1 Information security roles and responsibilities
Control
All information security responsibilities should be defined and allocated.
Implementation Guidance
Allocation of information security responsibilities should ...
Other information
Many organizations appoint an information security manager ...
Note: The text of the above example has been elided to condense the example.
OSCAL provides the syntax to represent a control and its content in a structured, machine-readable form. The first control from the Sample Security Catalog has three parts:
- The control statement, labeled as
Control. - A set of implementation guidance, labeled as
Implementation Guidance. - A set of supplemental information, labeled as
Other Information.
The following sub-sections will illustrate how to define these parts in OSCAL.
Defining a Control and the Control Statement
IN OSCAL, the minimum data needed to define a control is as follows:
| |
A control is represented using the <control> element as shown on line 1. Like most major elements in OSCAL, a control is required to have an identifier provided using the @id attribute.
Another required piece of information for a control is the control's title provided by the <title> element (line 2).
While optional in the OSCAL model, the need often exists to provide a section or control label that is used to identify the control within its source document. Using the <prop> element, an OSCAL property with the name label is used to provide the section number label value. This is illustrated on line 3.
Finally, a control must have a set of control statements. Shown on lines 4 thru 6, a <part> element with the name statement provides the required statement text using HTML markup. This uses the same part structure we reviewed earlier in this tutorial for defining text within a group. This part is also assigning the identifier s1.1.1_stm using the @id attribute. This identifier can be used to reference the specific statement in the OSCAL catalog.
| |
A control is represented as a JSON object with the array value of the controls property as shown on line 2. Like most major JSON objects in OSCAL, a control is required to have an identifier provided using the id property (line 3).
Another required piece of information for a control is the control's title provided by the title property (line 4).
While optional in the OSCAL model, the need often exists to provide a section or control label that is used to identify the control within its source document. The properties JSON property provides an array of OSCAL property objects. An OSCAL property with the name label is used to provide the section number label value. This is illustrated on lines 5 thru 8.
Finally, a control must have a set of control statements. Shown on lines 9 thru 13, the parts property allows an array of part JSON objects to be provided. a part object with the name statement provides the required statement text using Markdown text. This uses the same part structure we reviewed earlier in this tutorial for defining text within a group. This part is also assigning the identifier s1.1.1_stm using the id property. This identifier can be used to reference the specific statement in the OSCAL catalog.
| |
A control is represented as a YAML list item, with the list having the key controls as shown on line 1. Like most major YAML objects in OSCAL, a control is required to have an identifier provided using the id key (line 2).
Another required piece of information for a control is the control's title provided by the title key (line 4).
While optional in the OSCAL model, the need often exists to provide a section or control label that is used to identify the control within its source document. The properties key provides an array of OSCAL property items. An OSCAL property is defined on lines 5 thru 6, with a name label and the value 1.1.1 to provide the section number label value.
Finally, a control must have a set of control statements. Shown on lines 8 thru 10, a list of parts identified using the parts key allows a list of part YAML items to be provided. a part object with the name statement provides the required statement text using Markdown text. This uses the same part structure we reviewed earlier in this tutorial for defining text within a group. This part is also assigning the identifier s1.1.1_stm using the id property. This identifier can be used to reference the specific statement in the OSCAL catalog.
This represents the minimum information for defining a control. The next section discusses how to provide additional control-related information.
Including Implementation Guidance and Other Supplemental Information
The sample security catalog also has the Implementation Guidance and Other Information sections within the control. These sections can be expressed in an OSCAL control as additional markup content as follows:
| |
| |
| |
Using additional parts, all of the additional content is included. The Implementation Guidance section is contained within a part named guidance and the Other Information section is contained within a part named information. Notice in the above that each part has a unique identifier, and that the guidance part has child parts, which contain distinct areas of guidance.
The Final Catalog
The same control approach can also be applied to the rest of the controls in the Sample Security Catalog (i.e., 1.1.2, 2.1.1 and 2.2.1).
Assembling all of the control content described in this tutorial, we obtain the final structure of the Sample Security Catalog (XML, JSON, YAML):
| |
| |
| |
Summary
This concludes the tutorial. At this point you should be familiar with:
- The basic structure of a catalog of controls expressed in OSCAL.
- How to provide the basic metadata required to be included in an OSCAL control catalog.
- How to define a group and a collection of controls.
- How to use parts to provide additional control text.
For more information you can review the OSCAL catalog model documentation.