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 ofcontrols
and othergroups
properties. 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-matter
is 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 ofcontrols
and othergroups
keys. 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-matter
is 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
metadata
property, 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 usingtitle
property. 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 thepublished
property. 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-modified
property. 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 theversion
property. 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-version
property, 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
metadata
block, 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 usingtitle
key. 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 thepublished
key. 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-modified
key. 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 theversion
key. 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
key, 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@id
attribute 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 namelabel
provides 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
@id
attribute, which identifies the part.a name specified by the
@name
attribute, which identifies the type of the part. The nameobjective
is 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
groups
array.Line 3 where the
id
property 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
title
property. A title can be simple text or can include Markdown.Lines 5 thru 8 define an array of properties for the group using the
properties
property.On line 6 the property's name
label
is provided using thename
JSON property. A property with the namelabel
provides the text label that can be prepended to the title when formatting the content for human readability.On line 7 the property's value
1
is provided using thevalue
JSON 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 thetitle
andproperties
JSON properties.Lines 16 thru 20 define the sub-section's objective using the
parts
property and associated array of objects. In this case we have a single part object. A part requires:a unique identifier specified by the
id
property (line 17), which identifies the part.a name specified by the
name
property (line 18), which identifies the type of the part. The nameobjective
is used to indicate that the part represents an objective.A string of Markdown prose content (line 19) contained by the
prose
property. 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
part
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 1 declares a list of group items using the
groups
key.Line 2 starts a new group item and the
id
key 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
title
key. A title can be simple text or can include Markdown.Lines 4 thru 6 define a list of properties for the group using the
properties
key.Line 5 starts a new property item and the
name
key provides the namelabel
for the property. A property with the namelabel
provides the text label that can be prepended to the title when formatting the content for human readability.On line 6 the key
value
provides 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 thetitle
andproperties
keys.Lines 13 thru 18 define the sub-section's objective using the
parts
property and associated array of objects. In this case we have a single part object. A part requires:a unique identifier specified by the
id
property (line 17), which identifies the part.a name specified by the
name
property (line 18), which identifies the type of the part. The nameobjective
is used to indicate that the part represents an objective.A string of Markdown prose content (lines 17 and 18) contained by the
prose
key. 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\n
need 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
part
can 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.