RFC 9393

Concise Software Identification Tags

๐Ÿ“… published June 2023, from ietf

1. Introduction โœจ

okay so bestie, welcome to RFC 9393 ๐ŸŽ€ and yes, this one is a whole vibe ๐Ÿ’… Let me set the scene first, because the title block is giving very specific info ๐Ÿ‘€

Internet Engineering Task Force (IETF) ๐ŸŒธ Request for Comments: 9393 ๐Ÿฆ‹ Category: Standards Track ๐Ÿ’– (this means it's an official Internet Standard, no cap ๐Ÿ‘‘) ISSN: 2070-1721 ๐Ÿ’œ Date: June 2023 ๐Ÿงš

The authors are H. Birkholz of Fraunhofer SIT, J. Fitzgerald-McKay of the National Security Agency, C. Schmidt of The MITRE Corporation, and D. Waltermire of NIST ๐Ÿซถ A whole squad of brilliant people ๐Ÿ˜ญ

The title is Concise Software Identification Tags ๐Ÿ“ and the whole point is to make SWID tags way smaller so they fit on tiny devices and tiny networks ๐Ÿ”ฅ

Now the abstract, which is lowkey the TL;DR ๐Ÿ’… ISO/IEC 19770-2:2015 Software Identification (SWID) tags are an extensible XML-based structure for identifying and describing software components, patches, and installation bundles โœจ The problem is that SWID tags can be too big for devices with limited network and storage ๐Ÿ’€ So this document defines a concise version called Concise SWID (CoSWID) tags ๐ŸŽ€ CoSWID keeps the same semantics and features as SWID tags, plus some new semantics for describing extra kinds of info, all in a much more memory-efficient format ๐Ÿฆ‹

This document is labelled as a Standards Track document, which the IETF Steering Group approved after public review ๐Ÿ’œ You can find errata and feedback info at https://www.rfc-editor.org/info/rfc9393 ๐ŸŒˆ Also, the copyright is IETF Trust, 2023, and any Code Components pulled from this doc need Revised BSD License text, no warranties ๐Ÿ’…

Now let's get into the actual Introduction ๐Ÿงš

1.1. The SWID and CoSWID Tag Lifecycle

Hold on, this part is for Part 2! ๐Ÿ’– Stay tuned, we're just getting started ๐ŸŒˆ

Part 1 of 16 done โœจ Say "next" when you're ready ๐Ÿซถ

1.1. The SWID and CoSWID Tag Lifecycle ๐Ÿ”„โœจ

Okay so, besides dictating what a SWID tag record looks like ๐ŸŽ€, ISO/IEC 19770-2:2015 also lays down requirements for the whole SWID tag lifecycle. Basically, when a software component gets installed on an endpoint, its SWID tag gets installed too ๐Ÿงš. When that component is uninstalled or replaced, the tag is deleted or replaced, whichever makes sense. The result is a perfect vibe match: the installed software on an endpoint and the SWID tags for those components always line up ๐Ÿฆ‹. CoSWIDs share the same lifecycle requirements as a SWID tag ๐Ÿ’œ.

The SWID specification and supporting guidance in NIST Internal Report (NISTIR) 8060 ("Guidelines for the Creation of Interoperable Software Identification (SWID) Tags") [SWID-GUIDANCE] define four types of SWID tags: primary, patch, corpus, and supplemental. The following text is paraphrased from these sources ๐Ÿ“š.

  • Primary Tag: A SWID or CoSWID tag that identifies and describes an installed software component on an endpoint. A primary tag is intended to be installed on an endpoint along with the corresponding software component. ๐Ÿ‘‘
  • Patch Tag: A SWID or CoSWID tag that identifies and describes an installed patch that has made incremental changes to a software component installed on an endpoint. A patch tag is intended to be installed on an endpoint along with the corresponding software component patch. ๐Ÿฉน
  • Corpus Tag: A SWID or CoSWID tag that identifies and describes an installable software component in its pre-installation state. A corpus tag can be used to represent metadata about an installation package or installer for a software component, a software update, or a patch. ๐Ÿ“ฆ
  • Supplemental Tag: A SWID or CoSWID tag that allows additional information to be associated with a referenced SWID tag. This allows tools and users to record their own metadata about a software component without modifying CoSWID primary or patch tags created by a software provider. ๐ŸŒธ

The type of a tag is determined by specific data elements, which are discussed in Section 3. Section 3 also provides normative language for CoSWID semantics that implement this lifecycle. The following information helps to explain how these semantics apply to the use of a CoSWID tag ๐Ÿง .

Corpus, primary, and patch tags have similar functions in that they describe the existence and/or presence of different types of software components (e.g., software installers, software installations, software patches) and, potentially, different states of these software components. Supplemental tags have the same structure as other tags but are used to provide information not contained in the referenced corpus, primary, and patch tags. All four tag types come into play at various points in the software lifecycle and support software management processes that depend on the ability to accurately determine where each software component is in its lifecycle ๐Ÿ”ฅ.

                                    +------------+
                                    v            |
  Software      Software        Software     Software      Software
  Deployment -> Installation -> Patching  -> Upgrading  -> Removal

  Corpus        Primary         Primary      xPrimary      xPrimary
  Supplemental  Supplemental    Supplemental xSupplemental xSupplemental
                                Patch        xPatch
                                             Primary
                                             Supplemental

Figure 1: Use of Tag Types in the Software Lifecycle ๐Ÿ—บ๏ธ

Figure 1 illustrates the steps in the software lifecycle and the relationships among those lifecycle events supported by the four types of SWID and CoSWID tags. A detailed description of the four tag types is provided in Section 2.3. The figure identifies the types of tags that are used in each lifecycle event ๐Ÿ‘€.

There are many ways in which software tags might be managed for the host the software is installed on. For example, software tags could be made available on the host or to an external software manager when storage is limited on the host ๐Ÿ’พ.

In these cases, the host or external software manager is responsible for management of the tags, including deployment and removal of the tags as indicated by the above lifecycle. Tags are deployed, and previously deployed tags are typically removed (indicated by an x prefix) at each lifecycle stage as follows ๐Ÿงน:

  • Software Deployment: Before the software component is installed (i.e., pre-installation), and while the product is being deployed, a corpus tag provides information about the installation files and distribution media (e.g., CD/DVD, distribution package). ๐Ÿšš

Corpus tags are not actually deployed on the target system but are intended to support deployment procedures and their dependencies at install time, such as to verify the installation media ๐Ÿ”.

  • Software Installation: A primary tag will be installed with the software component (or subsequently created) to uniquely identify and describe the software component. Supplemental tags are created to augment primary tags with additional site-specific or extended information. While not illustrated in the figure, patch tags can also be installed during software installation to provide information about software fixes deployed along with the base software installation. ๐Ÿ› ๏ธ
  • Software Patching: When a patch is applied to the software component, a new patch tag is provided, supplying details about the patch and its dependencies. While not illustrated in the figure, a corpus tag can also provide information about the patch installer and patching dependencies that need to be installed before the patch. ๐Ÿฉน
  • Software Upgrading: As a software component is upgraded to a new version, new primary and supplemental tags replace existing tags, enabling timely and accurate tracking of updates to software inventory. While not illustrated in the figure, a corpus tag can also provide information about the upgrade installer and dependencies that need to be installed before the upgrade. ๐Ÿ†™
โš ๏ธ Note: In the context of software tagging, software patching and updating differ in an important way. When installing a patch, a set of file modifications are made to pre-installed software; these modifications do not alter the version number or the descriptive metadata of an installed software component. An update can also make a set of file modifications; in that case, the version number or the descriptive metadata of an installed software component is changed.
            |  Note: In the context of software tagging, software
            |  patching and updating differ in an important way.  When
            |  installing a patch, a set of file modifications are made
            |  to pre-installed software; these modifications do not
            |  alter the version number or the descriptive metadata of
            |  an installed software component.  An update can also make
            |  a set of file modifications; in that case, the version
            |  number or the descriptive metadata of an installed
            |  software component is changed.
  • Software Removal: Upon removal of the software component, relevant SWID tags are removed. This removal event can trigger timely updates to software inventory reflecting the removal of the product and any associated patch or supplemental tags. ๐Ÿ—‘๏ธ

As illustrated in the figure, supplemental tags can be associated with any corpus, primary, or patch tag to provide additional metadata about an installer, installed software, or installed patch, respectively ๐Ÿงฉ.

Understanding the use of CoSWIDs in the software lifecycle provides a basis for understanding the information provided in a CoSWID and the associated semantics of this information. Each different SWID and CoSWID tag type provides different sets of information. For example, a "corpus tag" is used to describe a software component's installation image on an installation medium, while a "patch tag" is meant to describe a patch that modifies some other software component ๐Ÿ’–.


1.2. Concise SWID Format ๐Ÿชถ

This document defines the CoSWID tag format, which is based on CBOR. CBOR-based CoSWID tags offer a more concise representation of SWID information as compared to the XML-based SWID tag representation in ISO-19770-2:2015. The structure of a CoSWID is described via the Concise Data Definition Language (CDDL) [RFC8610]. The resulting CoSWID data definition is aligned with the information able to be expressed with the XML Schema definition of ISO-19770-2:2015 [SWID]. This alignment allows both SWID and CoSWID tags to represent a common set of software component information and allows CoSWID tags to support the same uses as a SWID tag ๐Ÿคโœจ.

The vocabulary (i.e., the CDDL names of the types and members used in the CoSWID CDDL specification) is mapped to more concise labels represented as small integer values (indices). The names used in the CDDL specification and the mapping to the CBOR representation using integer indices are based on the vocabulary of the XML attribute and element names defined in ISO/IEC 19770-2:2015 ๐Ÿ”ข.


1.3. Requirements Notation ๐Ÿ“

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 ๐ŸŽ€.

2. Concise SWID Data Definition โœจ

okay so this section is basically the rulebook for how a CoSWID gets written in CDDL ๐Ÿ’… It covers the general rules and processes for encoding data using CDDL representation. Prior familiarity with CBOR and CDDL concepts will help you vibe with this CoSWID spec ๐Ÿงš

This section describes the conventions for how a CoSWID is represented in the CDDL structure. So the CamelCase notation [CamelCase] from the XML Schema definition gets switched to a hyphen-separated notation [KebabCase] in the CoSWID CDDL spec. For example, "ResourceCollection" becomes "resource-collection" ๐ŸŽ€ This little glow-up reduces ambiguity when the text refers to certain attributes. An attribute written in CamelCase explicitly relates to XML SWID tags, and an attribute written in KebabCase explicitly relates to CBOR CoSWID tags. It also makes it way easier to write future work that references both XML SWID and CBOR CoSWID documents ๐Ÿฆ‹

Most of the time, you can map attribute names between SWID and CoSWID just by converting CamelCase to KebabCase, which is so convenient ๐Ÿ™Œ But some CoSWID CDDL attribute names are a bit more different from their XML Schema buddies. This happens when the change makes the CoSWID spec clearer. For example, the "name" and "version" SWID fields correspond to the "software-name" and "software-version" CoSWID fields. So it's not always possible to translate names mechanically between the two formats, and in those cases a manual mapping is needed ๐Ÿ—บ๏ธ XPath expressions [W3C.REC-xpath20-20101214] need to use SWID names. See Section 5.2.

The 57 human-readable text labels of the CDDL-based CoSWID vocabulary get mapped to integer indices through a block of rules at the bottom of the definition. This gives you a more concise, integer-based form that's great for storing or transporting, compared to the less efficient text-based form of the original vocabulary ๐Ÿ’œ

Because of the CDDL-based integer labels, CoSWID can expand in future revisions of this spec and through extensions (see Section 2.2) โœจ New constructs can get a new integer index, and a deprecated construct can be replaced by a new construct with a new integer index. An implementation can use these integer indices to figure out which construct to parse. The "CoSWID Items" registry, defined in Section 6.1, makes sure new constructs get a unique index value. This approach means there's no need for an explicit CoSWID version ๐ŸŒธ

In a number of places, the value encoding admits both integer values and text strings. The integer values are defined in a registry specific to the kind of value. The text values are not meant for interchange and are exclusively for private use, as defined in Section 6.2.2 ๐Ÿ™ˆ Encoders SHOULD NOT use string values based on the names registered in the registry, since these are less concise than their index value equivalents. A decoder MUST, however, be prepared to accept text strings that aren't specified in this document, and ignore the construct if a string is unknown ๐Ÿซถ In the rest of this document, we call this an "integer label with text escape" ๐Ÿงš

The root of the CDDL specification in this document is the rule coswid (as defined in Section 8):

start = coswid

In CBOR, an array is encoded using bytes that identify the array, plus the array's length or stop point (see [RFC8949]). To make items that support one or more values, the following CDDL notation is used ๐Ÿ‘‘

_name_ = (_label_ => _data_ / [ 2* _data_ ])

That rule lets you give either a single data item or an array of two or more data values. When you provide a singleton data value, the CBOR markers for the array, array length, and stop point aren't needed, so you save bytes ๐Ÿ’… When two or more data values are provided, they get encoded as an array. This modeling pattern shows up a lot in the CoSWID CDDL spec, because it makes singleton values way more efficient ๐Ÿฆ‹

You can simplify usage of this construct with

one-or-more<T> = T / [ 2* T ]

which means the example above becomes

_name_ = (_label_ => one-or-more<_data_>)

The following subsections describe the different parts of the CoSWID model ๐ŸŒˆ

2.1. Character Encoding

The CDDL "text" type is represented in CBOR as major type 3, which is a string of Unicode characters encoded as UTF-8 [RFC3629] (see Section 3.1 of [RFC8949]). So both SWID and CoSWID use UTF-8 for encoding characters in text strings ๐Ÿ’–

To make sure UTF-8 strings can be encoded, decoded, and exchanged interoperably, text strings in CoSWID MUST be encoded in a way that is consistent with the Net-Unicode definition in [RFC5198]. No cap, this one is important ๐Ÿ˜ญ

All names registered with IANA under the requirements in Section 6.2 also MUST be valid according to the XML Schema NMTOKEN data type (see [W3C.REC-xmlschema-2-20041028], Section 3.3.4). This keeps things compatible with the SWID spec wherever these names get used ๐ŸŽ€

2.2. Concise SWID Extensions

The CoSWID spec has two features that aren't in the SWID spec it's based on. These features are:

  • The explicit definition of types for some attributes in the ISO-19770-2:2015 XML representation that are usually represented by the any-attribute item in the SWID model. These are covered in Section 2.5.
  • The inclusion of extension points in the CoSWID spec using CDDL sockets (see Section 3.9 of [RFC8610]). CDDL sockets let you define well-formed extensions in supplementary CDDL descriptions that support extra uses of CoSWID tags beyond the original scope of ISO-19770-2:2015 tags ๐Ÿงš

The following CDDL sockets (extension points) are defined in this document. They let you add new information structures to their respective CDDL groups ๐Ÿฆ‹

 +=====================+=================================+=========+
 | Map Name            | CDDL Socket                     | Defined |
 |                     |                                 | in      |
 +=====================+=================================+=========+
 | concise-swid-tag    | $$coswid-extension              | Section |
 |                     |                                 | 2.3     |
 +---------------------+---------------------------------+---------+
 | entity-entry        | $$entity-extension              | Section |
 |                     |                                 | 2.6     |
 +---------------------+---------------------------------+---------+
 | link-entry          | $$link-extension                | Section |
 |                     |                                 | 2.7     |
 +---------------------+---------------------------------+---------+
 | software-meta-entry | $$software-meta-extension       | Section |
 |                     |                                 | 2.8     |
 +---------------------+---------------------------------+---------+
 | resource-collection | $$resource-collection-extension | Section |
 |                     |                                 | 2.9.2   |
 +---------------------+---------------------------------+---------+
 | file-entry          | $$file-extension                | Section |
 |                     |                                 | 2.9.2   |
 +---------------------+---------------------------------+---------+
 | directory-entry     | $$directory-extension           | Section |
 |                     |                                 | 2.9.2   |
 +---------------------+---------------------------------+---------+
 | process-entry       | $$process-extension             | Section |
 |                     |                                 | 2.9.2   |
 +---------------------+---------------------------------+---------+
 | resource-entry      | $$resource-extension            | Section |
 |                     |                                 | 2.9.2   |
 +---------------------+---------------------------------+---------+
 | payload-entry       | $$payload-extension             | Section |
 |                     |                                 | 2.9.3   |
 +---------------------+---------------------------------+---------+
 | evidence-entry      | $$evidence-extension            | Section |
 |                     |                                 | 2.9.4   |
 +---------------------+---------------------------------+---------+

Table 1: CoSWID CDDL Group Extension Points

The "CoSWID Items" registry, defined in Section 6.1, is a registration mechanism that lets new items, and their associated index values, get added to the CoSWID model through the CDDL sockets in the table above. It also gives well-known index values for data items in CoSWID extensions, so implementations that support a given extension can recognize those index values ๐ŸŒŸ

The following additional CDDL sockets are defined in this document too. They let you add new values to corresponding type choices (aka enumerations) through custom CDDL specifications ๐Ÿ’…

        +==================+=================+=============+
        | Enumeration Name | CDDL Socket     | Defined in  |
        +==================+=================+=============+
        | version-scheme   | $version-scheme | Section 4.1 |
        +------------------+-----------------+-------------+
        | role             | $role           | Section 4.2 |
        +------------------+-----------------+-------------+
        | ownership        | $ownership      | Section 4.3 |
        +------------------+-----------------+-------------+
        | rel              | $rel            | Section 4.4 |
        +------------------+-----------------+-------------+
        | use              | $use            | Section 4.5 |
        +------------------+-----------------+-------------+

Table 2: CoSWID CDDL Enumeration Extension Points

A bunch of IANA registries for CoSWID values are also defined in Section 6.2. These registries let new values get registered with IANA for the enumerations above. This registration mechanism supports defining new well-known index values and names for new enumeration values used by CoSWID, which other software tagging specs can use too. It also means new standardized enumerated values can be shared between multiple tagging specs (and their implementations) over time ๐ŸŒˆ

Okay so picking up right where we left off, bestie ๐ŸŽ€ Now we're in the part where the root map gets its full spec, and it is EXTREMELY the main character of this whole doc ๐Ÿ‘‘

2.3. The concise-swid-tag Map

The CDDL for the root concise-swid-tag map is below ๐Ÿ’… This rule and its constraints MUST be followed when creating or validating a CoSWID tag, so no skipping, no vibes-only implementations ๐Ÿ˜ญ

concise-swid-tag = {
  tag-id => text / bstr .size 16,
  tag-version => integer,
  ? corpus => bool,
  ? patch => bool,
  ? supplemental => bool,
  software-name => text,
  ? software-version => text,
  ? version-scheme => $version-scheme,
  ? media => text,
  ? software-meta => one-or-more<software-meta-entry>,
  entity => one-or-more<entity-entry>,
  ? link => one-or-more<link-entry>,
  ? payload-or-evidence,
  * $$coswid-extension,
  global-attributes,
}

payload-or-evidence //= ( payload => payload-entry )
payload-or-evidence //= ( evidence => evidence-entry )

tag-id = 0
software-name = 1
entity = 2
evidence = 3
link = 4
software-meta = 5
payload = 6
corpus = 8
patch = 9
media = 10
supplemental = 11
tag-version = 12
software-version = 13
version-scheme = 14

$version-scheme /= multipartnumeric
$version-scheme /= multipartnumeric-suffix
$version-scheme /= alphanumeric
$version-scheme /= decimal
$version-scheme /= semver
$version-scheme /= int / text
multipartnumeric = 1
multipartnumeric-suffix = 2
alphanumeric = 3
decimal = 4
semver = 16384

Here's the member-by-member breakdown, the fun way โœจ

  • global-attributes: a list of items, including an optional language definition for text-string values, plus an unbounded set of any-attribute items ๐Ÿงš Described in Section 2.5.
  • tag-id (index 0): a 16-byte binary string OR a textual identifier that uniquely references a software component ๐Ÿฆ‹ The tag identifier MUST be globally unique, bestie, because the tag-id is the global key for matching and lookups, so duplicates = total chaos ๐Ÿ’€ If it's a 16-byte binary string, it MUST be a valid UUID as defined by [RFC4122]. There are no strict rules on structure, but examples include a 16-byte GUID (e.g., class 4 UUID) [RFC4122], or a DNS domain name followed by a "/" and a text string, where the domain name keeps things unique across organizations ๐ŸŒˆ A textual tag-id value MUST NOT contain a sequence of two underscores ("__"). That's because two underscores separate the TAG_CREATOR_REGID value and UNIQUE_ID value in a Software Identifier, so a double underscore in a tag-id could make parsing ambiguous ๐Ÿ™ˆ See Section 6.7.
  • software-name (index 1): a textual item with the software component's name ๐Ÿ“ This is likely the same name you'd see in a package management tool. This item maps to /SoftwareIdentity/@name in [SWID].
  • entity (index 2): info about one or more organizations responsible for producing the CoSWID tag, and producing or releasing the software component ๐ŸŽ€ Described in Section 2.6.
  • evidence (index 3): can record the results of a software discovery process used to identify untagged software on an endpoint, or represent indicators for why software is believed to be installed there ๐Ÿ” Either way, a CoSWID tag can be created by the tool analyzing the installed components. This item is mutually exclusive to payload, because evidence is always generated on the target device ad hoc. Described in Section 2.9.4.
  • link (index 4): a means to establish relationship arcs between the tag and another item ๐Ÿ”— A link can relate tags to each other or reference another related resource, like a vulnerability database association, a Resource-Oriented Lightweight Information Exchange (ROLIE) Feed [RFC8322], a Manufacturer Usage Description (MUD) resource [RFC8520], a software download location, etc. It's modeled after the HTML "link" element ๐Ÿ’œ Described in Section 2.7.
  • software-meta (index 5): an open-ended map of key/value data pairs ๐ŸŒธ A number of predefined keys give you common usage and semantics across the industry, and any additional attribute can be included too. Industry groups are expected to use a common set of attribute names so their communities can interoperate ๐Ÿซถ Described in Section 2.8. This item maps to /SoftwareIdentity/Meta in [SWID].
  • payload (index 6): a collection of software artifacts (described by child items) that compose the target software ๐Ÿ“ฆ For a corpus tag, these could be the files in an installer. For a primary or patch tag, they could be the files installed on an endpoint. The artifacts in a payload may be a superset of what's actually installed, since user selections at install time might leave some artifacts out โœจ This item is mutually exclusive to evidence, because payload can only be provided by an external entity. Described in Section 2.9.3.
  • corpus (index 8): a boolean that says whether the tag identifies an installable software component in its pre-installation state ๐Ÿ’– Installable software includes an installation package or installer, a software update, or a patch. If the CoSWID tag represents installable software, corpus MUST be set to "true". If not provided, the default value MUST be considered "false".
  • patch (index 9): a boolean that says whether the tag identifies an installed patch that made incremental changes to a software component on an endpoint ๐Ÿฉน If a CoSWID tag is for a patch, patch MUST be set to "true". If not provided, the default value MUST be considered "false". A patch item's value MUST NOT be set to "true" if installing the associated software package changes the version of a software component.
  • media (index 10): a text value hinting to the tag consumer which target platform the tag applies to ๐Ÿ“ฑ It MUST be formatted as a query as defined by the W3C "Media Queries Level 3" Recommendation (see [W3C.REC-mediaqueries-3-20220405]). Media query support is here for interoperability with [SWID], which doesn't add further requirements for media query use. So this spec doesn't clarify how a media query is to be used for a CoSWID ๐Ÿคทโ€โ™€๏ธ
  • supplemental (index 11): a boolean that says whether the tag provides extra info to be associated with another referenced SWID or CoSWID tag ๐Ÿง This lets tools and users record their own metadata about a software component WITHOUT modifying the primary or patch tags made by the software provider. If a CoSWID tag is a supplemental tag, supplemental MUST be set to "true". If not provided, the default value MUST be considered "false".
  • tag-version (index 12): an integer for the specific release revision of the tag ๐Ÿ”ข Typically it starts at 0 and goes up for each subsequent tag produced for the same software component release. This lets a producer fix an incorrect tag without implying any change to the underlying software, like adding new metadata, fixing a broken link, or adding a missing payload entry ๐Ÿ› ๏ธ When producing a revised tag, the new tag-version value MUST be greater than the old tag-version value.
  • software-version (index 13): a textual value for the specific release or development version of the software component ๐Ÿท๏ธ This item maps to /SoftwareIdentity/@version in [SWID].
  • version-scheme (index 14): an integer or textual value for the versioning scheme used for software-version, as an integer label with text escape ๐ŸŒŸ For the "Version Scheme" values, see Section 4.1. If an integer is used, it MUST be an index value in the range -256 to 65535. Integers from -256 to -1 are reserved for testing and use in closed environments (see Section 6.2.2). Integers from 0 to 65535 correspond to registered entries in the IANA "Software ID Version Scheme Values" registry (see Section 6.2.4).
  • $$coswid-extension: a CDDL socket used to add new information structures to the concise-swid-tag root map ๐Ÿงฉ See Section 2.2.

2.4. concise-swid-tag Co-constraints

The following co-constraints apply to the information provided in the concise-swid-tag group ๐Ÿฆ‹

  • The patch and supplemental items MUST NOT both be set to "true" ๐Ÿ™…โ€โ™€๏ธ
  • If the patch item is set to "true", the tag MUST contain at least one link item (see Section 2.7) with both the rel item value of "patches" AND an href item specifying an association with the software that was patched. Without at least one link item, the target of the patch can't be identified, and the patch tag can't be applied without external context ๐Ÿ˜ญ
  • If all of the corpus, patch, and supplemental items are "false", OR if the corpus item is set to "true", then a software-version item MUST be included with a value set to the version of the software component ๐Ÿ’…

2.5. The global-attributes Group

The global-attributes group provides a list of items, including an optional language definition to support the processing of text-string values, plus an unbounded set of any-attribute items. These allow additional items to be provided as a general point of extension in the model ๐ŸŒˆ

The CDDL for the global-attributes group is below ๐Ÿ’œ

global-attributes = (
  ? lang => text,
  * any-attribute,
)

any-attribute = (
  label => one-or-more<text> / one-or-more<int>
)

label = text / int

Here's what each child item of this group does ๐Ÿซถ

  • lang (index 15): a textual language tag that conforms with the IANA "Language Subtag Registry" [RFC5646]. The context of the specified language applies to all sibling and descendant textual values, UNLESS a descendant object has defined a different language tag. So a new context is established when a descendant redefines a new language tag. All textual values within a given context MUST be considered expressed in the specified language ๐ŸŒ
  • any-attribute: a sub-group that provides a means to include arbitrary information via label/index ("key") value pairs ๐Ÿ—๏ธ Labels can be either a single integer or a text string. Values can be a single integer, a text string, or an array of integers or text strings ๐ŸŽ

2.6. The entity-entry Map โœจ

okay so this is the entity-entry map, aka the "who's involved" card ๐Ÿ’… here's the CDDL, bestie:

entity-entry = {
  entity-name => text,
  ? reg-id => any-uri,
  role => one-or-more<$role>,
  ? thumbprint => hash-entry,
  * $$entity-extension,
  global-attributes,
}

entity-name = 31
reg-id = 32
role = 33
thumbprint = 34

$role /= tag-creator
$role /= software-creator
$role /= aggregator
$role /= distributor
$role /= licensor
$role /= maintainer
$role /= int / text
tag-creator=1
software-creator=2
aggregator=3
distributor=4
licensor=5
maintainer=6

okay here's the rundown on each child item ๐ŸŽ€

  • global-attributes: this is the global-attributes group from Section 2.5 ๐Ÿซถ
  • entity-name (index 31): the textual name of the organizational entity that claims the roles set by the role item for this CoSWID tag. This one maps to /SoftwareIdentity/Entity/@name in [SWID].
  • reg-id (index 32): the registration ID, which is basically the thing that uniquely identifies a naming authority in a given scope (global, organization, vendor, customer, administrative domain, etc.) for the entity. The value of a registration ID MUST be a URI as defined in [RFC3986]; it is not intended to be dereferenced. The scope is usually the scope of an organization ๐ŸŒธ
  • role (index 33): an integer or text value (integer label with text escape, see Section 2) that describes the relationship(s) between the entity and this tag or the software component it's tied to. If an integer is used, it MUST be an index value in the range -256 to 255. The range -256 to -1 is reserved for testing and for use in closed environments (see Section 6.2.2), and the range 0 to 255 lines up with registered entries in the IANA "Software ID Entity Role Values" registry (see Section 6.2.5) ๐Ÿ’œ

there are also some extra rules for role, and these are a big deal:

  • an entity item MUST be provided with the role of "tag-creator" for every CoSWID tag. this is the org that made the tag ๐Ÿ‘‘
  • an entity item SHOULD be provided with the role of "software-creator" for every CoSWID tag, if the tag creator knows that info. this is the org that made the software component being described ๐Ÿ”ฅ
  • thumbprint (index 34): a value that holds a hash (aka the thumbprint) of the signing entity's public key certificate. It tells you which entity signed the CoSWID tag, which is usually the tag creator. See Section 2.9.1 for more on the hash-entry data structure ๐Ÿฆ‹
  • $$entity-extension: a CDDL socket for extending the entity-entry group model. See Section 2.2 ๐Ÿงš

2.7. The link-entry Map ๐ŸŒˆ

now the link-entry map, which is the "where else do I go" section ๐Ÿ“ here's the CDDL:

link-entry = {
  ? artifact => text,
  href => any-uri,
  ? media => text,
  ? ownership => $ownership,
  rel => $rel,
  ? media-type => text,
  ? use => $use,
  * $$link-extension,
  global-attributes,
}

media = 10
artifact = 37
href = 38
ownership = 39
rel = 40
media-type = 41
use = 42

$ownership /= shared
$ownership /= private
$ownership /= abandon
$ownership /= int / text
abandon=1
private=2
shared=3

$rel /= ancestor
$rel /= component
$rel /= feature
$rel /= installationmedia
$rel /= packageinstaller
$rel /= parent
$rel /= patches
$rel /= requires
$rel /= see-also
$rel /= supersedes
$rel /= supplemental
$rel /= -256..65536 / text
ancestor=1
component=2
feature=3
installationmedia=4
packageinstaller=5
parent=6
patches=7
requires=8
see-also=9
supersedes=10
supplemental=11

$use /= optional
$use /= required
$use /= recommended
$use /= int / text
optional=1
required=2
recommended=3

okay so here's every member of this map, one by one ๐Ÿ’–

  • global-attributes: the global-attributes group from Section 2.5 ๐Ÿซถ
  • media (index 10): a hint for whoever's consuming the link, so they know which target platform the link applies to. This item is a query as defined by the W3C "Media Queries Level 3" Recommendation (see [W3C.REC-mediaqueries-3-20220405]). Like we flagged in the media item in Section 2.3, media queries are in here for interoperability with [SWID], which doesn't give any extra requirements on how to use them. So this spec doesn't clarify how a media query is supposed to work for a CoSWID ๐Ÿ™ˆ
  • artifact (index 37): used with rel="installationmedia". The value is the absolute filesystem path to the installer executable or script that can be run to launch the referenced installation. Links with the same artifact name MUST be considered mirrors of each other, so the installation media can be pulled from any of the listed sources ๐Ÿ”ฅ
  • href (index 38): a URI-reference [RFC3986] for the referenced resource. The value can be, but isn't limited to, the following (a slightly modified excerpt from [SWID]):
    • if there's no URI scheme, the URI-reference is a relative reference to the base URI of the CoSWID tag, which is the URI the CoSWID tag was served under. for example, ./folder/supplemental.coswid ๐Ÿ“
    • it can be a physical resource location with any acceptable URI scheme (e.g., <file://>, <http://>, <https://>, <ftp://>) ๐ŸŒธ
    • a URI-like expression with swid: as the scheme points to another SWID or CoSWID by that tag's tag-id. This needs to get resolved in the context of the endpoint, by software that can look up other SWID or CoSWID tags. for example, swid:2df9de35-0aff-4a86-ace6-f7dddd1ade4c references the tag whose tag-id is 2df9de35-0aff-4a86-ace6-f7dddd1ade4c. See Section 5.1 for guidance on swid expressions ๐Ÿงš
    • a URI-like expression with swidpath: as the scheme refers to another software tag through an XPath query [W3C.REC-xpath20-20101214] that matches items in that tag (Section 5.2). This scheme is only here for compatibility with [SWID]. This spec doesn't define how to resolve an XPath query in the context of CBOR. See Section 5.2 for guidance on swidpath expressions ๐Ÿ’œ
  • ownership (index 39): an integer or text value (integer label with text escape, see Section 2). The list of values lives in Section 4.3. This item gets used when href points at another software component, and it shows the degree of ownership between the component the CoSWID tag describes and the component the link points to. If an integer is used, it MUST be an index value in the range -256 to 255. The range -256 to -1 is reserved for testing and for closed environments (see Section 6.2.2), and the range 0 to 255 maps to registered entries in the "Software ID Link Ownership Values" registry ๐Ÿ‘‘
  • rel (index 40): an integer or text value (integer label with text escape, see Section 2). The list of values is in Section 4.4. This item says what the relationship is between this CoSWID and the target resource that href points to. If an integer is used, it MUST be an index value in the range -256 to 65535. The range -256 to -1 is reserved for testing and closed environments (see Section 6.2.2), and the range 0 to 65535 maps to registered entries in the IANA "Software ID Link Relationship Values" registry (see Section 6.2.7). If a string is used, it MUST be either a private use name as defined in Section 6.2.2, or a "Relation Name" from the IANA "Link Relation Types" registry (see <https://www.iana.org/assignments/link-relations/>) as defined by [RFC8288]. When a string value defined in the IANA "Software ID Link Relationship Values" registry matches a Relation Name defined in the IANA "Link Relation Types" registry, the index value from the IANA "Software ID Link Relationship Values" registry MUST be used instead, because that relationship has a specialized meaning in the context of a CoSWID tag. String values correspond to registered entries in the "Software ID Link Relationship Values" registry ๐Ÿฆ‹
  • media-type (index 41): gives the resource consumer a hint about what type of resource to expect. A link can point at arbitrary resources on the endpoint, the local network, or the Internet through href. (This is a hint: the server hosting the target of the URI has no obligation to use the indicated media type when the URI gets dereferenced.) Media types are identified by a "Name" from the IANA "Media Types" registry (see <https://www.iana.org/assignments/media-types/>). This item maps to /SoftwareIdentity/Link/@type in [SWID] ๐ŸŒˆ
  • use (index 42): an integer or text value (integer label with text escape, see Section 2). The list of values is in Section 4.5. This item decides whether the referenced software component has to be installed before the software component identified by the CoSWID tag gets installed. If an integer is used, it MUST be an index value in the range -256 to 255. The range -256 to -1 is reserved for testing and closed environments (see Section 6.2.2), and the range 0 to 255 maps to registered entries in the IANA "Software ID Link Use Values" registry (see Section 6.2.8). If a string is used, it MUST be a private use name as defined in Section 6.2.2. String values correspond to registered entries in the "Software ID Link Use Values" registry ๐Ÿ“
  • $$link-extension: a CDDL socket for extending the link-entry map model. See Section 2.2 โœจ

2.8. The software-meta-entry Map โœจ

okay bestie, here's the CDDL for the software-meta-entry map ๐Ÿ’–

software-meta-entry = {
  ? activation-status => text,
  ? channel-type => text,
  ? colloquial-version => text,
  ? description => text,
  ? edition => text,
  ? entitlement-data-required => bool,
  ? entitlement-key => text,
  ? generator => text / bstr .size 16,
  ? persistent-id => text,
  ? product => text,
  ? product-family => text,
  ? revision => text,
  ? summary => text,
  ? unspsc-code => text,
  ? unspsc-version => text,
  * $$software-meta-extension,
  global-attributes,
}

activation-status = 43
channel-type = 44
colloquial-version = 45
description = 46
edition = 47
entitlement-data-required = 48
entitlement-key = 49
generator = 50
persistent-id = 51
product = 52
product-family = 53
revision = 54
summary = 55
unspsc-code = 56
unspsc-version = 57

Now let's go through each child item in this group, one by one ๐ŸŽ€

  • global-attributes: this is the global-attributes group from Section 2.5, so you already know the drill ๐Ÿงš
  • activation-status (index 43): a textual value that tells you how the software component got activated ๐Ÿ”“. It might be tied to specific terms and conditions for use (like trial, serialized, licensed, unlicensed, etc.) and it can relate to an entitlement. This one is usually found in supplemental tags, because it holds info that might get picked during one specific install.
  • channel-type (index 44): a textual value that says which sales, licensing, or marketing channel the software component was targeted for (like volume, retail, original equipment manufacturer (OEM), academic, etc.) ๐Ÿ›๏ธ. This is typically used in supplemental tags too, since it's the kind of info that might get selected during a specific install.
  • colloquial-version (index 45): a textual value for the software component's informal or colloquial version ๐ŸŒธ. Examples could be a year value, a major version number, or something similar that identifies a group of specific releases in the same release/support cycle. This version can stay the same across multiple releases of a component, while the software-version in the concise-swid-tag group is way more specific and changes with every release. Heads up: this one is only meant for string comparison (byte by byte). It is not meant to tell you whether one value comes earlier or later in a sequence, so don't try ๐Ÿ™…โ€โ™€๏ธ
  • description (index 46): a textual value with a detailed description of the software component ๐Ÿ“. This value MAY be multiple paragraphs separated by CR LF characters, as described by [RFC5198].
  • edition (index 47): a textual value showing that the component is a functional variation of the code base that's used to support multiple software components ๐Ÿ‘‘. For example, this is how you can tell apart enterprise, standard, or professional variants.
  • entitlement-data-required (index 48): a boolean value that helps decide whether accompanying proof of entitlement is needed when a software license reconciliation process is performed ๐Ÿงพ.
  • entitlement-key (index 49): a vendor-specific textual key that can identify and connect to an entitlement ๐Ÿ”‘. Examples are a serial number, product key, or license key. For values tied to one specific install (like a license key), a supplemental tag usually holds this info. In other cases, where one general-purpose key works for every possible install of the component on different endpoints, a primary tag usually holds it. Important tea: CoSWID tags aren't meant to contain confidential info, so tag authors are advised not to record unprotected, private software license keys in this field ๐Ÿ™ˆ
  • generator (index 50): the name (or tag-id) of the software component that created the CoSWID tag ๐Ÿ› ๏ธ. If the generating software component has a SWID or CoSWID tag, then the tag-id for that generating component SHOULD be provided.
  • persistent-id (index 51): a globally unique identifier used to identify a set of software components that are related ๐Ÿฆ‹. Components sharing the same persistent-id can be different versions. This is handy for relating components that were released at different points in time or through different release channels, especially when they can't be related using the link item.
  • product (index 52): a basic name for the software component that can be common across multiple tagged software components ๐Ÿ“. For example, Apache HTTP daemon (HTTPD).
  • product-family (index 53): a textual value showing the software components' overall product family ๐Ÿ’œ. This should be used when multiple related software components form a larger capability that gets installed on multiple different endpoints. For example, some families might have a server, a client, and shared service components that are part of one bigger capability. Email systems, enterprise applications, backup services, web conferencing, and similar capabilities are all examples of families. Heads up, this item is not meant to represent groups of software that are bundled or installed together ๐Ÿ™…โ€โ™€๏ธ For bundled software, the persistent-id or link items SHOULD be used to relate the components.
  • revision (index 54): a string value for an informal or colloquial release version of the software โœจ. This can give a different version value than the software-version in the concise-swid-tag group. It's super useful when one or more releases need an informal label that's different from the exact version value given by software-version. Examples include SP1, RC1, Beta, etc.
  • summary (index 55): a short description of the software component ๐Ÿ“ฃ. This MUST be a single sentence that's suitable for display in a user interface.
  • unspsc-code (index 56): an 8-digit United Nations Standard Products and Services Code (UNSPSC) classification code for the software component, as defined by the UNSPSC [UNSPSC] ๐ŸŒ.
  • unspsc-version (index 57): the UNSPSC version used to define the unspsc-code value ๐Ÿ—‚๏ธ.
  • $$software-meta-extension: a CDDL socket that can be used to extend the software-meta-entry group model ๐Ÿ”Œ. See Section 2.2.

2.9. The Resource Collection Definition ๐ŸŒˆ

2.9.1. The hash-entry Array

Okay so CoSWID adds explicit support for representing hash entries using algorithms registered in the IANA "Named Information Hash Algorithm Registry" [IANA.named-information] ๐Ÿ”. This array is used by both the hash (index 7) and thumbprint (index 34) values. It's basically the equivalent of the namespace qualified "hash" attribute in [SWID] ๐Ÿ’…

hash-entry = [
  hash-alg-id: int,
  hash-value: bytes,
]

So the number you use as the value for hash-alg-id is an integer-based hash algorithm identifier, and its value MUST refer to an ID in the IANA "Named Information Hash Algorithm Registry" [IANA.named-information] with a Status of "current" (at the time the generator software was built or later). Other hash algorithms MUST NOT be used. ๐Ÿšซ If the hash-alg-id is not known, then the integer value 0 MUST be used. This is what makes conversion from ISO SWID tags [SWID] possible, since those tags don't let you identify an algorithm for this field ๐Ÿฆ‹

And for hash-value, it MUST represent the raw hash value as a byte string (as opposed to, say, base64 encoded) ๐Ÿซถ. It's generated from the representation of the resource using the hash algorithm indicated by hash-alg-id. Slay, we're getting closer to the end of this part! ๐Ÿ’–

2.9.2. The resource-collection Group โœจ

Okay bestie, the resource-collection group is where we list all the stuff a CoSWID tag document is talking about ๐Ÿ“‚. It's used in both the evidence (what a software discovery process found ๐Ÿ”) and the payload (what's actually installed on an endpoint ๐Ÿ’ป), so it helps tell different kinds of CoSWID tag content apart. We're talking directories, files, processes, or resources. Obsessed with how organized this is ๐ŸŽ€

Here's the CDDL for the resource-collection group:

path-elements-group = ( ? directory => one-or-more<directory-entry>,
                        ? file => one-or-more<file-entry>,
                      )

resource-collection = (
  path-elements-group,
  ? process => one-or-more<process-entry>,
  ? resource => one-or-more<resource-entry>,
  * $$resource-collection-extension,
)

filesystem-item = (
  ? key => bool,
  ? location => text,
  fs-name => text,
  ? root => text,
)

file-entry = {
  filesystem-item,
  ? size => uint,
  ? file-version => text,
  ? hash => hash-entry,
  * $$file-extension,
  global-attributes,
}

directory-entry = {
  filesystem-item,
  ? path-elements => { path-elements-group },
  * $$directory-extension,
  global-attributes,
}

process-entry = {
  process-name => text,
  ? pid => integer,
  * $$process-extension,
  global-attributes,
}

resource-entry = {
  type => text,
  * $$resource-extension,
  global-attributes,
}

hash = 7
directory = 16
file = 17
process = 18
resource = 19
size = 20
file-version = 21
key = 22
location = 23
fs-name = 24
root = 25
path-elements = 26
process-name = 27
pid = 28
type = 29

Here's the rundown on each member of the groups and maps above ๐Ÿงš

  • filesystem-item: A list of common items used to represent the filesystem root, relative location, name, and significance of a file or directory item. The main squad ๐Ÿซถ
  • global-attributes: The global-attributes group as described in Section 2.5.
  • hash (index 7): The value that provides a hash of a file ๐Ÿ”. This item gives an integrity measurement for a specific file. See Section 2.9.1 for more details on how the hash-entry data structure gets used.
  • directory (index 16): An item that lets child directory and file items be defined within a directory hierarchy for the software component ๐Ÿ—‚๏ธ.
  • file (index 17): An item that lets details about a file be provided for the software component ๐Ÿ“„.
  • process (index 18): An item that lets details be provided about the runtime behavior of the software component, like the stuff that shows up in a process listing on an endpoint ๐Ÿƒโ€โ™€๏ธ.
  • resource (index 19): An item that can give details about an artifact or capability expected to be found on an endpoint, or evidence collected related to the software component ๐Ÿฆ‹. It can represent concepts the directory, file, or process items don't cover directly. Examples include registry keys, bound ports, etc. The equivalent construct in [SWID] is currently underspecified, so this item might be further defined through extensions in the future ๐Ÿ‘€.
  • size (index 20): The file's size in bytes ๐Ÿ“.
  • file-version (index 21): The file's version as reported by querying information on the file from the operating system (if available). This item maps to /SoftwareIdentity/(Payload|Evidence)/File/@version in [SWID].
  • key (index 22): A boolean value indicating whether a file or directory is significant or required for the software component to execute or function properly ๐Ÿ”‘. These are files or directories that can be used to affirmatively determine if the software component is installed on an endpoint.
  • location (index 23): The filesystem path where a file is expected to be located when installed or copied ๐Ÿ“. The location MUST be either an absolute path, a path relative to the path value included in the parent directory item (preferred), or a path relative to the location of the CoSWID tag if no parent is defined. The location MUST NOT include a file's name, which is provided by the fs-name item. Don't mix those up, bestie ๐Ÿ™…โ€โ™€๏ธ
  • fs-name (index 24): The name of the directory or file without any path information. This lines up with a file "name" in [SWID]. This item maps to /SoftwareIdentity/(Payload|Evidence)/(File|Directory)/@name in [SWID].
  • root (index 25): A host-specific name for the root of the filesystem ๐ŸŒณ. The location item is considered relative to this location if it's specified. If it's not provided, the value given by the location item is expected to be relative to its parent, or to the location of the CoSWID tag if no parent is provided.
  • path-elements (index 26): A group that allows a hierarchy of directory and file items to be defined in payload or evidence items ๐Ÿช†. This is a construction within the CDDL definition of CoSWID to support shared syntax, and it does not appear in [SWID].
  • process-name (index 27): The software component's process name, as it will appear in an endpoint's process list ๐Ÿ’…. This lines up with a process "name" in [SWID]. This item maps to /SoftwareIdentity/(Payload|Evidence)/Process/@name in [SWID].
  • pid (index 28): The process ID identified for a running instance of the software component in the endpoint's process list ๐Ÿ”ข. This is used as part of the evidence item.
  • type (index 29): A human-readable string indicating the type of resource ๐Ÿท๏ธ.
  • $$resource-collection-extension: A CDDL socket that can be used to extend the resource-collection group model. It's how you add new specialized types of resources โœจ. See Section 2.2.
  • $$file-extension: A CDDL socket that can be used to extend the file-entry group model. See Section 2.2.
  • $$directory-extension: A CDDL socket that can be used to extend the directory-entry group model. See Section 2.2.
  • $$process-extension: A CDDL socket that can be used to extend the process-entry group model. See Section 2.2.
  • $$resource-extension: A CDDL socket that can be used to extend the resource-entry group model. See Section 2.2.

2.9.3. The payload-entry Map ๐ŸŽ

The CDDL for the payload-entry map is below. Payload is the stuff that's actually installed, so this is the map for that ๐Ÿ’œ

payload-entry = {
  resource-collection,
  * $$payload-extension,
  global-attributes,
}

Here's what each child item of this group does ๐ŸŒธ

  • global-attributes: The global-attributes group as described in Section 2.5.
  • resource-collection: The resource-collection group as described in Section 2.9.2.
  • $$payload-extension: A CDDL socket that can be used to extend the payload-entry group model. See Section 2.2.

2.9.4. The evidence-entry Map ๐Ÿ”Ž

The CDDL for the evidence-entry map is next. Evidence is what the discovery process actually found, so this one's the detective of the bunch ๐Ÿ•ต๏ธโ€โ™€๏ธ

evidence-entry = {
  resource-collection,
  ? date => integer-time,
  ? device-id => text,
  ? location => text,
  * $$evidence-extension,
  global-attributes,
}

date = 35
device-id = 36

Here's what each child item of this group does ๐Ÿ’–

  • global-attributes: The global-attributes group as described in Section 2.5.
  • resource-collection: The resource-collection group as described in Section 2.9.2.
  • location (index 23): The filesystem path of the location of the CoSWID tag generated as evidence. This path is always an absolute file path ๐Ÿ“Œ. That's different from the value of a location item found within a filesystem-item as described in Section 2.9.2, which can be either a relative path or an absolute path.
  • date (index 35): The date and time the information was collected for the evidence item, in epoch-based date/time format as specified in Section 3.4.2 of [RFC8949] โฐ.
  • device-id (index 36): The endpoint's string identifier that the evidence was collected from ๐Ÿ–ฅ๏ธ.
  • $$evidence-extension: A CDDL socket that can be used to extend the evidence-entry group model. See Section 2.2.

2.10. Full CDDL Specification ๐Ÿ’…

Okay bestie, this is the whole enchilada ๐Ÿ“ If you want a valid CoSWID document, the structure of the CBOR message you build MUST adhere to the CDDL below. No vibes-based shapes here, it has to match exactly โœจ

<CODE BEGINS> file "concise-swid-tag.cddl"
concise-swid-tag = {
  tag-id => text / bstr .size 16,
  tag-version => integer,
  ? corpus => bool,
  ? patch => bool,
  ? supplemental => bool,
  software-name => text,
  ? software-version => text,
  ? version-scheme => $version-scheme,
  ? media => text,
  ? software-meta => one-or-more<software-meta-entry>,
  entity => one-or-more<entity-entry>,
  ? link => one-or-more<link-entry>,
  ? payload-or-evidence,
  * $$coswid-extension,
  global-attributes,
}

payload-or-evidence //= ( payload => payload-entry )
payload-or-evidence //= ( evidence => evidence-entry )

any-uri = uri
label = text / int

$version-scheme /= multipartnumeric
$version-scheme /= multipartnumeric-suffix
$version-scheme /= alphanumeric
$version-scheme /= decimal
$version-scheme /= semver
$version-scheme /= int / text

any-attribute = (
  label => one-or-more<text> / one-or-more<int>
)

one-or-more<T> = T / [ 2* T ]

global-attributes = (
  ? lang => text,
  * any-attribute,
)

hash-entry = [
  hash-alg-id: int,
  hash-value: bytes,
]

entity-entry = {
  entity-name => text,
  ? reg-id => any-uri,
  role => one-or-more<$role>,
  ? thumbprint => hash-entry,
  * $$entity-extension,
  global-attributes,
}

$role /= tag-creator
$role /= software-creator
$role /= aggregator
$role /= distributor
$role /= licensor
$role /= maintainer
$role /= int / text

link-entry = {
  ? artifact => text,
  href => any-uri,
  ? media => text,
  ? ownership => $ownership,
  rel => $rel,
  ? media-type => text,
  ? use => $use,
  * $$link-extension,
  global-attributes,
}

$ownership /= shared
$ownership /= private
$ownership /= abandon
$ownership /= int / text

$rel /= ancestor
$rel /= component
$rel /= feature
$rel /= installationmedia
$rel /= packageinstaller
$rel /= parent
$rel /= patches
$rel /= requires
$rel /= see-also
$rel /= supersedes
$rel /= supplemental
$rel /= -256..65536 / text

$use /= optional
$use /= required
$use /= recommended
$use /= int / text

software-meta-entry = {
  ? activation-status => text,
  ? channel-type => text,
  ? colloquial-version => text,
  ? description => text,
  ? edition => text,
  ? entitlement-data-required => bool,
  ? entitlement-key => text,
  ? generator => text / bstr .size 16,
  ? persistent-id => text,
  ? product => text,
  ? product-family => text,
  ? revision => text,
  ? summary => text,
  ? unspsc-code => text,
  ? unspsc-version => text,
  * $$software-meta-extension,
  global-attributes,
}

path-elements-group = ( ? directory => one-or-more<directory-entry>,
                        ? file => one-or-more<file-entry>,
                      )

resource-collection = (
  path-elements-group,
  ? process => one-or-more<process-entry>,
  ? resource => one-or-more<resource-entry>,
  * $$resource-collection-extension,
)

file-entry = {
  filesystem-item,
  ? size => uint,
  ? file-version => text,
  ? hash => hash-entry,
  * $$file-extension,
  global-attributes,
}

directory-entry = {
  filesystem-item,
  ? path-elements => { path-elements-group },
  * $$directory-extension,
  global-attributes,
}

process-entry = {
  process-name => text,
  ? pid => integer,
  * $$process-extension,
  global-attributes,
}

resource-entry = {
  type => text,
  * $$resource-extension,
  global-attributes,
}

filesystem-item = (
  ? key => bool,
  ? location => text,
  fs-name => text,
  ? root => text,
)

payload-entry = {
  resource-collection,
  * $$payload-extension,
  global-attributes,
}

evidence-entry = {
  resource-collection,
  ? date => integer-time,
  ? device-id => text,
  ? location => text,
  * $$evidence-extension,
  global-attributes,
}

integer-time = #6.1(int)

; "global map member" integer indices
tag-id = 0
software-name = 1
entity = 2
evidence = 3
link = 4
software-meta = 5
payload = 6
hash = 7
corpus = 8
patch = 9
media = 10
supplemental = 11
tag-version = 12
software-version = 13
version-scheme = 14
lang = 15
directory = 16
file = 17
process = 18
resource = 19
size = 20
file-version = 21
key = 22
location = 23
fs-name = 24
root = 25
path-elements = 26
process-name = 27
pid = 28
type = 29
entity-name = 31
reg-id = 32
role = 33
thumbprint = 34
date = 35
device-id = 36
artifact = 37
href = 38
ownership = 39
rel = 40
media-type = 41
use = 42
activation-status = 43
channel-type = 44
colloquial-version = 45
description = 46
edition = 47
entitlement-data-required = 48
entitlement-key = 49
generator = 50
persistent-id = 51
product = 52
product-family = 53
revision = 54
summary = 55
unspsc-code = 56
unspsc-version = 57

; "version-scheme" integer indices
multipartnumeric = 1
multipartnumeric-suffix = 2
alphanumeric = 3
decimal = 4
semver = 16384

; "role" integer indices
tag-creator=1
software-creator=2
aggregator=3
distributor=4
licensor=5
maintainer=6

; "ownership" integer indices
abandon=1
private=2
shared=3

; "rel" integer indices
ancestor=1
component=2
feature=3
installationmedia=4
packageinstaller=5
parent=6
patches=7
requires=8
see-also=9
supersedes=10
; supplemental=11 ; already defined

; "use" integer indices
optional=1
required=2
recommended=3
<CODE ENDS>

3. Determining the Type of CoSWID ๐Ÿ”ฎ

Okay so remember how Section 1.1 walked us through the four CoSWID tag types? ๐Ÿฆ‹ This part is the rulebook for figuring out which type your tag actually is, so it gets identified properly. The first matching rule MUST determine the type of the CoSWID tag, so read the list in order and stop at the first one that fits ๐Ÿ‘‘

  • Primary Tag: A CoSWID tag MUST be considered a primary tag if the corpus, patch, and supplemental items are "false".
  • Supplemental Tag: A CoSWID tag MUST be considered a supplemental tag if the supplemental item is set to "true".
  • Corpus Tag: A CoSWID tag MUST be considered a corpus tag if the corpus item is "true".
  • Patch Tag: A CoSWID tag MUST be considered a patch tag if the patch item is "true".
๐Ÿ™ˆ Plot twist: corpus, patch, and supplemental can all be "true" at the same time! The rules above are how you sort out the type in that case. For example, a SWID or CoSWID tag for a patch installer might have both the corpus and patch items set to "true". Then the tag is a "corpus tag". The tag that installer puts on the system would have only the patch item set to "true", so the installed tag type is a "patch tag" ๐Ÿ’…

4. CoSWID Indexed Label Values ๐ŸŒˆ

Okay this section is all about the indexed label values ๐Ÿงš There are multiple kinds of them, and they live in several IANA registries, so you'll want to check out Section 6 for the full scoop ๐Ÿ’œ Every one of these values is a positive integer โœจ and in every registry the value 0 is marked as Reserved, so hands off zero ๐Ÿ™…

4.1. Version Scheme ๐ŸŽ€

okay so the concise-swid-tag group's version-scheme item has its own cute little lookup table ๐Ÿงš The Index column is the number you actually put in the item's value, and the Version Scheme Name column is the human-readable label. Those names match the version schemes from ISO/IEC 19770-2:2015 [SWID]. The Definition column tells you what a legal value looks like for each one โœจ

    +=======+=========================+===============================+
    | Index | Version Scheme Name     | Definition                    |
    +=======+=========================+===============================+
    | 1     | multipartnumeric        | Numbers separated by dots,    |
    |       |                         | where the numbers are         |
    |       |                         | interpreted as decimal        |
    |       |                         | integers (e.g., 1.2.3,        |
    |       |                         | 1.2.3.4.5.6.7, 1.4.5, 1.21)   |
    +-------+-------------------------+-------------------------------+
    | 2     | multipartnumeric+suffix | Numbers separated by dots,    |
    |       |                         | where the numbers are         |
    |       |                         | interpreted as decimal        |
    |       |                         | integers with an additional   |
    |       |                         | textual suffix (e.g., 1.2.3a) |
    +-------+-------------------------+-------------------------------+
    | 3     | alphanumeric            | Strictly a string, no         |
    |       |                         | interpretation as number      |
    +-------+-------------------------+-------------------------------+
    | 4     | decimal                 | A single decimal floating-    |
    |       |                         | point number                  |
    +-------+-------------------------+-------------------------------+
    | 16384 | semver                  | A semantic version as defined |
    |       |                         | by [SWID].  Also see the      |
    |       |                         | [SEMVER] specification for    |
    |       |                         | more information              |
    +-------+-------------------------+-------------------------------+

                       Table 3: Version Scheme Values

Sorting time, and this part is a little bit of a vibe ๐Ÿ’… "multipartnumeric" and the numbers part of "multipartnumeric+suffix" are treated as a sequence of numbers. They get sorted in lexicographical order by those numbers (i.e., not by the digits in the numbers), and then by the textual suffix if you're using "multipartnumeric+suffix". "alphanumeric" strings are sorted lexicographically as character strings. "decimal" version numbers are treated as single floating-point numbers, so 1.25 is less than 1.3 ๐Ÿค“

The values above are registered in the IANA "Software ID Version Scheme Values" registry, defined in Section 6.2.4. Additional entries will likely be registered over time in this registry ๐ŸŒˆ

Now for the producer side. A CoSWID producer that knows which version scheme was used to pick the version value SHOULD include the optional version-scheme item so nobody gets confused about what it means ๐Ÿซถ If the producer doesn't have that info, it SHOULD omit the version-scheme item. Consumers can use these heuristics, which work because the version schemes' value spaces partially overlap ๐Ÿ‘€

  • "decimal" and "multipartnumeric" partially overlap in their value space when a value matches a decimal number. When a corresponding software-version item's value falls within this overlapping value space, it is expected that the "decimal" version scheme is used.
  • "multipartnumeric" and "semver" partially overlap in their value space when a "multipartnumeric" value matches the semantic versioning syntax. When a corresponding software-version item's value falls within this overlapping value space, it is expected that the "semver" version scheme is used.
  • "alphanumeric" and other version schemes might overlap in their value space. When a corresponding software-version item's value falls within this overlapping value space, it is expected that the other version scheme is used and "alphanumeric" is not used.

Real talk though, these heuristics are imperfect and can guess wrong ๐Ÿ˜ญ That's exactly why the version-scheme item SHOULD be included by the producer whenever possible!

4.2. Entity Role Values ๐Ÿ‘‘

This table tells you which index value to use for the entity-entry group's role item (see Section 2.6). These values match the entity roles from the ISO/IEC 19770-2:2015 specification [SWID]. The Index column is the value you put in the role item, the Role Name column is the human-readable label, and the Definition column explains what each role actually means ๐Ÿ’œ

   +=======+=================+========================================+
   | Index | Role Name       | Definition                             |
   +=======+=================+========================================+
   | 1     | tagCreator      | The person or organization that        |
   |       |                 | created the containing SWID or CoSWID  |
   |       |                 | tag.                                   |
   +-------+-----------------+----------------------------------------+
   | 2     | softwareCreator | The person or organization entity that |
   |       |                 | created the software component.        |
   +-------+-----------------+----------------------------------------+
   | 3     | aggregator      | From [SWID], "An organization or       |
   |       |                 | system that encapsulates software from |
   |       |                 | their own and/or other organizations   |
   |       |                 | into a different distribution process  |
   |       |                 | (as in the case of virtualization), or |
   |       |                 | as a completed system to accomplish a  |
   |       |                 | specific task (as in the case of a     |
   |       |                 | value added reseller)."                |
   +-------+-----------------+----------------------------------------+
   | 4     | distributor     | From [SWID], "An entity that furthers  |
   |       |                 | the marketing, selling and/or          |
   |       |                 | distribution of software from the      |
   |       |                 | original place of manufacture to the   |
   |       |                 | ultimate user without modifying the    |
   |       |                 | software, its packaging or its         |
   |       |                 | labelling."                            |
   +-------+-----------------+----------------------------------------+
   | 5     | licensor        | From [SAM], as a "software licensor",  |
   |       |                 | a "person or organization who owns or  |
   |       |                 | holds the rights to issue a software   |
   |       |                 | license for a specific software        |
   |       |                 | [component]."                          |
   +-------+-----------------+----------------------------------------+
   | 6     | maintainer      | The person or organization that is     |
   |       |                 | responsible for coordinating and       |
   |       |                 | making updates to the source code for  |
   |       |                 | the software component.  This SHOULD   |
   |       |                 | be used when the "maintainer" is a     |
   |       |                 | different person or organization than  |
   |       |                 | the original "softwareCreator".        |
   +-------+-----------------+----------------------------------------+

                       Table 4: Entity Role Values

The values above are registered in the IANA "Software ID Entity Role Values" registry, defined in Section 6.2.5. Additional values will likely be registered over time โœจ

Next up is the index value for the link-entry group's ownership item (see Section 2.7). These values match the link ownership values from the ISO/IEC 19770-2:2015 specification [SWID]. The Index column is what goes into the link-entry group ownership item's value, the Ownership Type column gives the human-readable name, and the Definition column says what each one means ๐ŸŒธ

   +=======+===========+===============================================+
   | Index | Ownership | Definition                                    |
   |       | Type      |                                               |
   +=======+===========+===============================================+
   | 1     | abandon   | If the software component referenced          |
   |       |           | by the CoSWID tag is uninstalled,             |
   |       |           | then the referenced software SHOULD           |
   |       |           | NOT be uninstalled.                           |
   +-------+-----------+-----------------------------------------------+
   | 2     | private   | If the software component referenced          |
   |       |           | by the CoSWID tag is uninstalled,             |
   |       |           | then the referenced software SHOULD           |
   |       |           | be uninstalled as well.                       |
   +-------+-----------+-----------------------------------------------+
   | 3     | shared    | If the software component referenced          |
   |       |           | by the CoSWID tag is uninstalled,             |
   |       |           | then the referenced software SHOULD           |
   |       |           | be uninstalled if no other                    |
   |       |           | components are sharing the software.          |
   +-------+-----------+-----------------------------------------------+

                       Table 5: Link Ownership Values

The values above are registered in the IANA "Software ID Link Ownership Values" registry, defined in Section 6.2.6. Additional values will likely be registered over time ๐Ÿ“

Okay bestie, this table is the cheat sheet for the rel item in a link-entry group (see Section 2.7) ๐Ÿฆ‹. These numbers match the link rel values in ISO/IEC 19770-2:2015 [SWID] โœจ. The "Index" column gives the number you use as the link-entry group ownership item's value. The "Relationship Type" column has the human-readable name, and the "Definition" column says what each one actually means ๐Ÿ’….

+=======+===================+======================================+
| Index | Relationship Type | Definition                           |
+=======+===================+======================================+
| 1     | ancestor          | The link references a software tag   |
|       |                   | for a previous release of this       |
|       |                   | software.  This can be useful to     |
|       |                   | define an upgrade path.              |
+-------+-------------------+--------------------------------------+
| 2     | component         | The link references a software tag   |
|       |                   | for a separate component of this     |
|       |                   | software.                            |
+-------+-------------------+--------------------------------------+
| 3     | feature           | The link references a configurable   |
|       |                   | feature of this software that can be |
|       |                   | enabled or disabled without changing |
|       |                   | the installed files.                 |
+-------+-------------------+--------------------------------------+
| 4     | installationmedia | The link references the installation |
|       |                   | package that can be used to install  |
|       |                   | this software.                       |
+-------+-------------------+--------------------------------------+
| 5     | packageinstaller  | The link references the installation |
|       |                   | software needed to install this      |
|       |                   | software.                            |
+-------+-------------------+--------------------------------------+
| 6     | parent            | The link references a software tag   |
|       |                   | that is the parent of the            |
|       |                   | referencing tag.  This relationship  |
|       |                   | can be used when multiple software   |
|       |                   | components are part of a software    |
|       |                   | bundle, where the "parent" is the    |
|       |                   | software tag for the bundle and each |
|       |                   | child is a "component".  In such a   |
|       |                   | case, each child component can       |
|       |                   | provide a "parent" link relationship |
|       |                   | to the bundle's software tag, and    |
|       |                   | the bundle can provide a "component" |
|       |                   | link relationship to each child      |
|       |                   | software component.                  |
+-------+-------------------+--------------------------------------+
| 7     | patches           | The link references a software tag   |
|       |                   | that the referencing software        |
|       |                   | patches.  Typically only used for    |
|       |                   | patch tags (see Section 1.1).        |
+-------+-------------------+--------------------------------------+
| 8     | requires          | The link references a prerequisite   |
|       |                   | for installing this software.  A     |
|       |                   | patch tag (see Section 1.1) can use  |
|       |                   | this to represent base software or   |
|       |                   | another patch that needs to be       |
|       |                   | installed first.                     |
+-------+-------------------+--------------------------------------+
| 9     | see-also          | The link references other software   |
|       |                   | that may be of interest that relates |
|       |                   | to this software.                    |
+-------+-------------------+--------------------------------------+
| 10    | supersedes        | The link references other software   |
|       |                   | (e.g., an older software version)    |
|       |                   | that this software replaces.  A      |
|       |                   | patch tag (see Section 1.1) can use  |
|       |                   | this to represent another patch that |
|       |                   | this patch incorporates or replaces. |
+-------+-------------------+--------------------------------------+
| 11    | supplemental      | The link references a software tag   |
|       |                   | that the referencing tag             |
|       |                   | supplements.  Used on supplemental   |
|       |                   | tags (see Section 1.1).              |
+-------+-------------------+--------------------------------------+

Table 6: Link Relationship Values

The values above are registered in the IANA "Software ID Link Relationship Values" registry, defined in Section 6.2.7. Additional values will likely be registered over time โœจ.

This table is the same kind of cheat sheet, but for the use item in a link-entry group (see Section 2.7) ๐Ÿ’–. Again these match the link use values in ISO/IEC 19770-2:2015 [SWID]. The "Index" column is the value you use as the link-entry group use item's value, and the "Use Type" column gives the readable name ๐Ÿซถ.

  +=======+=============+========================================+
  | Index | Use Type    | Definition                             |
  +=======+=============+========================================+
  | 1     | optional    | From [SWID], "Not absolutely required; |
  |       |             | the [Link]'d software is installed     |
  |       |             | only when specified."                  |
  +-------+-------------+----------------------------------------+
  | 2     | required    | From [SWID], "The [Link]'d software is |
  |       |             | absolutely required for an operation   |
  |       |             | software installation."                |
  +-------+-------------+----------------------------------------+
  | 3     | recommended | From [SWID], "Not absolutely required; |
  |       |             | the [Link]'d software is installed     |
  |       |             | unless specified otherwise."           |
  +-------+-------------+----------------------------------------+

Table 7: Link Use Values

The values above are registered in the IANA "Software ID Link Use Values" registry, defined in Section 6.2.8. Additional values will likely be registered over time ๐ŸŒˆ.

5. "swid" and "swidpath" Expressions ๐Ÿฆ‹

Here we get the two new scheme names this spec defines for use in CoSWID, which also keep things interoperable with the scheme names used in [SWID] ๐Ÿงš. Both "swid" and "swidpath" are meant to be read in a local context, not a global one, so neither one is technically a URI scheme name as defined in [RFC3986] ๐Ÿ™ˆ. That's why IANA registers them as provisional instead of permanent. Still, registering them as provisional means the names are reserved and properly defined going forward, which is honestly the main point ๐Ÿ’œ.

The swid and swidpath expressions conform to all rules for URI syntax. All uses of these expressions encountered within a CoSWID are to be interpreted as described in this section โœจ.

5.1. "swid" Expressions ๐Ÿ“

A "swid" expression references a software tag by its tag-id. The tag-id can be used to identify the tag resource in the context where it's referenced from. For example, when a tag is installed on a device, that tag can reference related tags on the same device using expressions with this scheme ๐Ÿ’….

For expressions that use the "swid" scheme, the scheme-specific part MUST consist of a referenced software tag's tag-id. This tag-id MUST be URI encoded according to Section 2.1 of [RFC3986] ๐Ÿ”ฅ.

The following expression is a valid example:

swid:2df9de35-0aff-4a86-ace6-f7dddd1ade4c

5.2. "swidpath" Expressions ๐ŸŽ€

A "swidpath" expression filters tags out of a base collection, so the matching tags end up in the identified tag collection ๐ŸŒธ. The XPath expression [W3C.REC-xpath20-20101214] is what checks the data that a given software tag out of the base collection has to contain for that tag to count as a match. The tags being evaluated (the base collection) are all the tags in the context where the "swidpath" expression is referenced from. For example, when a tag is installed on a device, that tag can reference related tags on the same device using an expression with this scheme ๐Ÿ‘‘.

For URIs that use the "swidpath" scheme, the following requirements apply:

  • The scheme-specific part MUST be an XPath expression as defined by [W3C.REC-xpath20-20101214]. The included XPath expression will be URI encoded according to Section 2.1 of [RFC3986].
  • This XPath is evaluated over SWID tags, or CoSWID tags transformed into SWID tags, found on a system. A given tag MUST be considered a match if the XPath evaluation result value has an effective boolean value of "true" according to [W3C.REC-xpath20-20101214], Section 2.4.3. ๐Ÿ˜ญ

6. IANA Considerations ๐ŸŒˆ

This document has a number of IANA considerations, as described in the following subsections. In summary, six new registries are established by this document, with initial entries provided for each registry. New values for five other registries are also defined ๐Ÿ’–.

6.1. CoSWID Items Registry

okay so this section creates a brand new registry called "CoSWID Items" ๐Ÿ“šโœจ It uses integers as index values in CBOR maps (the keys in those little maps ๐Ÿ’œ). Future registrations follow [BCP26], and the rules depend on which range the number lands in ๐Ÿ‘€

     +==================+=====================================+
     | Range            | Registration Procedures             |
     +==================+=====================================+
     | 0-32767          | Standards Action with Expert Review |
     +------------------+-------------------------------------+
     | 32768-4294967295 | Specification Required              |
     +------------------+-------------------------------------+

           Table 8: CoSWID Items Registration Procedures

All negative values are reserved for private use ๐ŸŒ™

Now the starter set ๐ŸŽ€ Every assignment has an integer index value, an item name, and a reference to the spec that defines it. Here's the full initial list:

      +===============+===========================+===========+
      | Index         | Item Name                 | Reference |
      +===============+===========================+===========+
      | 0             | tag-id                    | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 1             | software-name             | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 2             | entity                    | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 3             | evidence                  | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 4             | link                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 5             | software-meta             | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 6             | payload                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 7             | hash                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 8             | corpus                    | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 9             | patch                     | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 10            | media                     | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 11            | supplemental              | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 12            | tag-version               | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 13            | software-version          | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 14            | version-scheme            | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 15            | lang                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 16            | directory                 | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 17            | file                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 18            | process                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 19            | resource                  | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 20            | size                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 21            | file-version              | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 22            | key                       | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 23            | location                  | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 24            | fs-name                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 25            | root                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 26            | path-elements             | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 27            | process-name              | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 28            | pid                       | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 29            | type                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 30            | Unassigned                |           |
      +---------------+---------------------------+-----------+
      | 31            | entity-name               | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 32            | reg-id                    | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 33            | role                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 34            | thumbprint                | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 35            | date                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 36            | device-id                 | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 37            | artifact                  | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 38            | href                      | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 39            | ownership                 | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 40            | rel                       | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 41            | media-type                | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 42            | use                       | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 43            | activation-status         | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 44            | channel-type              | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 45            | colloquial-version        | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 46            | description               | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 47            | edition                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 48            | entitlement-data-required | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 49            | entitlement-key           | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 50            | generator                 | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 51            | persistent-id             | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 52            | product                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 53            | product-family            | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 54            | revision                  | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 55            | summary                   | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 56            | unspsc-code               | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 57            | unspsc-version            | RFC 9393  |
      +---------------+---------------------------+-----------+
      | 58-4294967295 | Unassigned                |           |
      +---------------+---------------------------+-----------+

             Table 9: CoSWID Items Initial Registrations

6.2. Registries for Software ID Values

Next up are the registries that let SWID and CoSWID share common enumerations ๐Ÿฆ‹ New values can be added to them over time. Neither the CoSWID spec nor the SWID spec is subordinate to the other, and each one evolves at the pace of its own standards group ๐Ÿ’… Still, sharing code points keeps the two standards lined up, which is why these registries are shared and why the names use swidsoftware-id (instead of swid or coswid) ๐Ÿซถ

6.2.1. Registration Procedures

These registries take new index values and names through either a Standards Action with Expert Review policy or a Specification Required policy [BCP26] โœจ

They also set aside the integer index values from -1 to -256 for private use, as defined in Section 4.1 of [BCP26] ๐ŸŒ™ Values -1 to -24 fit in a single uint8_t in CBOR, and values -25 to -256 need one extra uint8_t.

6.2.2. Private Use of Index and Name Values

The private use index values (-1 to -256) are meant for testing and closed environments ๐Ÿงช Values outside that range SHOULD NOT be assigned for testing ๐Ÿ™ˆ

For names that match private use index values, an Internationalized Domain Name prefix MUST be used so names don't collide ๐Ÿ’œ The form is:

domainprefix/name

Both "domainprefix" and "name" MUST each be either a Non-Reserved LDH (NR-LDH) label or a U-label, as defined by [RFC5890]. On top of that, "name" also MUST be unique within the namespace defined by the "domainprefix". (LDH just stands for "letters, digits, hyphen" ๐Ÿ”ค) This prefix trick is how a name gets to live in the private use range, and it lines up with the guidance in [BCP178] ๐ŸŽ€

6.2.3. Expert Review Criteria ๐Ÿ’…โœจ

okay bestie, designated experts have some extra checks to run before anything new gets in ๐Ÿซถ Every new registration request MUST meet all of these:

  • The requesting specification MUST provide a clear semantic definition for the new entry. This definition MUST clearly differentiate the requested entry from other previously registered entries. ๐Ÿ”ฅ
  • The requesting specification MUST describe the intended use of the entry, including any co-constraints that exist between (1) the use of the entry's index value or name and (2) other values defined within the SWID/CoSWID model. ๐Ÿงš
  • Index values and names outside the private use space MUST NOT be used without registration. This is considered "squatting" and MUST be avoided. Designated experts MUST ensure that reviewed specifications register all appropriate index values and names. ๐Ÿ™ˆ squatting is not it, periodt
  • Standards Track documents MAY include entries registered in the range reserved for entries under the Specification Required policy. This can occur when a Standards Track document provides further guidance on the use of index values and names that are in common use but were not registered with IANA. This situation SHOULD be avoided. ๐ŸŒธ
  • All registered names MUST be valid according to the XML Schema NMTOKEN data type (see [W3C.REC-xmlschema-2-20041028], Section 3.3.4). This ensures that registered names are compatible with the SWID format [SWID] where they are used. ๐Ÿ’œ
  • Registration of vanity names SHOULD be discouraged. The requesting specification MUST provide a description of how a requested name will allow for use by multiple stakeholders. ๐Ÿ‘‘

6.2.4. Software ID Version Scheme Values Registry ๐ŸŽ€

this one is so organized it's giving filing cabinet ๐Ÿ—‚๏ธ The document sets up a brand new registry called "Software ID Version Scheme Values". It holds index values for use as version-scheme item values in this document, plus Version Scheme Names for use in [SWID].

This registry uses the registration procedures from Section 6.2.1, with these ranges:

           +=============+=====================================+
           | Range       | Registration Procedures             |
           +=============+=====================================+
           | 0-16383     | Standards Action with Expert Review |
           +-------------+-------------------------------------+
           | 16384-65535 | Specification Required              |
           +-------------+-------------------------------------+

             Table 10: Software ID Version Scheme Registration
                                 Procedures

Assignments MUST consist of an integer index value, the Version Scheme Name, and a reference to the defining specification. ๐Ÿฆ‹

The initial registrations for the "Software ID Version Scheme Values" registry are listed below. They're derived from the textual Version Scheme Names defined in [SWID] โœจ

     +=============+=========================+=======================+
     | Index       | Version Scheme Name     | Reference             |
     +=============+=========================+=======================+
     | 0           | Reserved                |                       |
     +-------------+-------------------------+-----------------------+
     | 1           | multipartnumeric        | RFC 9393, Section 4.1 |
     +-------------+-------------------------+-----------------------+
     | 2           | multipartnumeric+suffix | RFC 9393, Section 4.1 |
     +-------------+-------------------------+-----------------------+
     | 3           | alphanumeric            | RFC 9393, Section 4.1 |
     +-------------+-------------------------+-----------------------+
     | 4           | decimal                 | RFC 9393, Section 4.1 |
     +-------------+-------------------------+-----------------------+
     | 5-16383     | Unassigned              |                       |
     +-------------+-------------------------+-----------------------+
     | 16384       | semver                  | RFC 9393, Section 4.1 |
     +-------------+-------------------------+-----------------------+
     | 16385-65535 | Unassigned              |                       |
     +-------------+-------------------------+-----------------------+

         Table 11: Software ID Version Scheme Initial Registrations

Registrations MUST conform to the expert review criteria defined in Section 6.2.3. ๐Ÿ“‹

Designated experts MUST also make sure that newly requested entries define a value space for the corresponding software-version item that is unique from other previously registered entries. ๐Ÿ’–

Note: The initial registrations violate this requirement but are included for backwards compatibility with [SWID]. See also Section 4.1. ๐Ÿ™ˆ

6.2.5. Software ID Entity Role Values Registry ๐ŸŒˆ

next up, the entity role registry ๐Ÿซถ This document sets up a new registry called "Software ID Entity Role Values". It gives index values for use as entity-entry role item values in this document, and entity role names for use in [SWID].

This registry uses the registration procedures from Section 6.2.1, with these ranges:

             +=========+=====================================+
             | Range   | Registration Procedures             |
             +=========+=====================================+
             | 0-127   | Standards Action with Expert Review |
             +---------+-------------------------------------+
             | 128-255 | Specification Required              |
             +---------+-------------------------------------+

                     Table 12: Software ID Entity Role
                          Registration Procedures

Assignments consist of an integer index value, a role name, and a reference to the defining specification. ๐Ÿง

The initial registrations for the "Software ID Entity Role Values" registry are below. They're derived from the textual entity role names defined in [SWID] ๐Ÿ’…

            +=======+=================+=======================+
            | Index | Role Name       | Reference             |
            +=======+=================+=======================+
            | 0     | Reserved        |                       |
            +-------+-----------------+-----------------------+
            | 1     | tagCreator      | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 2     | softwareCreator | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 3     | aggregator      | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 4     | distributor     | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 5     | licensor        | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 6     | maintainer      | RFC 9393, Section 4.2 |
            +-------+-----------------+-----------------------+
            | 7-255 | Unassigned      |                       |
            +-------+-----------------+-----------------------+

                 Table 13: Software ID Entity Role Initial
                               Registrations

Registrations MUST conform to the expert review criteria defined in Section 6.2.3. ๐Ÿ”ฅ


last registry of this part, and it's giving main character energy ๐Ÿ‘‘ This document establishes a new registry called "Software ID Link Ownership Values". It provides index values for use as link-entry ownership item values in this document, and link ownership names for use in [SWID].

This registry uses the registration procedures from Section 6.2.1, with these ranges:

             +=========+=====================================+
             | Range   | Registration Procedures             |
             +=========+=====================================+
             | 0-127   | Standards Action with Expert Review |
             +---------+-------------------------------------+
             | 128-255 | Specification Required              |
             +---------+-------------------------------------+

                    Table 14: Software ID Link Ownership
                          Registration Procedures

Assignments consist of an integer index value, an ownership type name, and a reference to the defining specification. ๐ŸŒธ

The initial registrations for the "Software ID Link Ownership Values" registry are listed below. They're derived from the textual entity role names defined in [SWID] ๐Ÿ“

          +=======+=====================+=======================+
          | Index | Ownership Type Name | Reference             |
          +=======+=====================+=======================+
          | 0     | Reserved            |                       |
          +-------+---------------------+-----------------------+
          | 1     | abandon             | RFC 9393, Section 4.3 |
          +-------+---------------------+-----------------------+
          | 2     | private             | RFC 9393, Section 4.3 |
          +-------+---------------------+-----------------------+
          | 3     | shared              | RFC 9393, Section 4.3 |
          +-------+---------------------+-----------------------+
          | 4-255 | Unassigned          |                       |
          +-------+---------------------+-----------------------+

                Table 15: Software ID Link Ownership Initial
                               Registrations

Registrations MUST conform to the expert review criteria defined in Section 6.2.3. โœจ

okay bestie, this section makes a brand new registry called "Software ID Link Relationship Values" ๐Ÿ’… It holds index values for use as link-entry rel item values in this document, and link ownership names for use in [SWID]. so cute, right? ๐ŸŽ€

It uses the registration procedures from Section 6.2.1, with these ranges:

           +=============+=====================================+
           | Range       | Registration Procedures             |
           +=============+=====================================+
           | 0-32767     | Standards Action with Expert Review |
           +-------------+-------------------------------------+
           | 32768-65535 | Specification Required              |
           +-------------+-------------------------------------+

                  Table 16: Software ID Link Relationship
                          Registration Procedures

Every assignment is made up of an integer index value, the relationship type name, and a reference to the spec that defines it. ๐Ÿฆ‹

The initial registrations are derived from the link relationship values defined in [SWID], and they look like this:

       +==========+========================+=======================+
       | Index    | Relationship Type Name | Reference             |
       +==========+========================+=======================+
       | 0        | Reserved               |                       |
       +----------+------------------------+-----------------------+
       | 1        | ancestor               | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 2        | component              | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 3        | feature                | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 4        | installationmedia      | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 5        | packageinstaller       | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 6        | parent                 | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 7        | patches                | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 8        | requires               | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 9        | see-also               | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 10       | supersedes             | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 11       | supplemental           | RFC 9393, Section 4.4 |
       +----------+------------------------+-----------------------+
       | 12-65535 | Unassigned             |                       |
       +----------+------------------------+-----------------------+

       Table 17: Software ID Link Relationship Initial Registrations

Registrations MUST conform to the expert review criteria in Section 6.2.3. ๐Ÿ”ฅ

Designated experts MUST also check that a new entry documents the URI schemes that may be used in an href tied to the link relationship, plus the expected resolution behavior of those schemes. This helps applications that process software tags interoperate when they resolve resources referenced by a link of a given type. it's giving teamwork ๐Ÿซถ

next up is the "Software ID Link Use Values" registry ๐ŸŒธ It gives index values for use as link-entry use item values in this document, plus link use names for use in [SWID].

It follows the registration procedures from Section 6.2.1, with these ranges:

             +=========+=====================================+
             | Range   | Registration Procedures             |
             +=========+=====================================+
             | 0-127   | Standards Action with Expert Review |
             +---------+-------------------------------------+
             | 128-255 | Specification Required              |
             +---------+-------------------------------------+

                Table 18: Software ID Link Use Registration
                                 Procedures

Each assignment is an integer index value, the link use type name, and a reference to the defining specification. ๐Ÿ“

The initial registrations are derived from the link relationship values defined in [SWID]. they're listed here:

          +=======+====================+=======================+
          | Index | Link Use Type Name | Reference             |
          +=======+====================+=======================+
          | 0     | Reserved           |                       |
          +-------+--------------------+-----------------------+
          | 1     | optional           | RFC 9393, Section 4.5 |
          +-------+--------------------+-----------------------+
          | 2     | required           | RFC 9393, Section 4.5 |
          +-------+--------------------+-----------------------+
          | 3     | recommended        | RFC 9393, Section 4.5 |
          +-------+--------------------+-----------------------+
          | 4-255 | Unassigned         |                       |
          +-------+--------------------+-----------------------+

           Table 19: Software ID Link Use Initial Registrations

Registrations MUST conform to the expert review criteria in Section 6.2.3. ๐Ÿ’–


6.3. swid+cbor Media Type Registration

IANA has added the following to the "Media Types" registry [IANA.media-types]. it's a whole new media type, the girlie is official ๐ŸŽ€

Type name:  application

Subtype name:  swid+cbor

Required parameters:  none

Optional parameters:  none

Encoding considerations:  Binary (encoded as CBOR [RFC8949]).  See
   RFC 9393 for details.

Security considerations:  See Section 9 of RFC 9393.

Interoperability considerations:  Applications MAY ignore any key
   value pairs that they do not understand.  This allows backwards-
   compatible extensions to this specification.

Published specification:  RFC 9393

Applications that use this media type:  The type is used by software
   asset management systems and vulnerability assessment systems and
   is used in applications that use remote integrity verification.

Fragment Identifier Considerations:  The syntax and semantics of
   fragment identifiers specified for "application/swid+cbor" are as
   specified for "application/cbor".  (At publication of RFC 9393,
   there is no fragment identification syntax defined for
   "application/cbor".)

Additional information:
   Magic number(s):  If tagged, the first five bytes in hex: da 53 57
      49 44 (see Section 8 of RFC 9393).
   File extension(s):  coswid
   Macintosh file type code(s):  none
   Macintosh Universal Type Identifier code:  org.ietf.coswid
      conforms to public.data.

Person & email address to contact for further information:
   IESG <iesg@ietf.org>

Intended usage:  COMMON

Restrictions on usage:  none

Author:  Henk Birkholz <henk.birkholz@sit.fraunhofer.de>

Change controller:  IESG

Quick vibe check: applications MAY ignore any key value pairs they don't understand, which is how backwards-compatible extensions get to exist. โœจ


6.4. CoAP Content-Format Registration

IANA has assigned a CoAP Content-Format ID for the CoSWID media type. it lives in the "CoAP Content-Formats" subregistry, inside the "CoRE Parameters" registry [RFC7252] [IANA.core-parameters], and it comes from the "IETF Review or IESG Approval" space (256..999). ๐ŸŒˆ

    +=======================+================+=====+===========+
    | Content Type          | Content Coding | ID  | Reference |
    +=======================+================+=====+===========+
    | application/swid+cbor | -              | 258 | RFC 9393  |
    +-----------------------+----------------+-----+-----------+

                 Table 20: CoAP Content-Format IDs

6.5. CBOR Tag Registration

IANA has allocated a tag in the "CBOR Tags" registry [IANA.cbor-tags]. ๐Ÿงš

    +============+===========+=====================+===========+
    | Tag        | Data Item | Semantics           | Reference |
    +============+===========+=====================+===========+
    | 1398229316 | map       | Concise Software    | RFC 9393  |
    |            |           | Identifier (CoSWID) |           |
    +------------+-----------+---------------------+-----------+

                     Table 21: CoSWID CBOR Tag

6.6. URI Scheme Registrations

okay so the ISO 19770-2:2015 SWID spec [SWID] already describes the "swid" and "swidpath" URI schemes, and people are using them in real implementations right now ๐Ÿ™Œ This document keeps that going for CoSWID. The subsections below register both schemes, so there's a registration that works for the SWID and CoSWID specs. โœจ

URI schemes are registered in the "Uniform Resource Identifier (URI) Schemes" registry, which is maintained at [IANA.uri-schemes]. ๐Ÿ’œ

6.6.1. URI Scheme "swid"

IANA has registered the URI scheme "swid". the registration complies with [RFC7595]. ๐Ÿฆ‹

Scheme name:  swid

Status:  Provisional

Applications/protocols that use this scheme name:  Applications that
   require Software IDs (SWIDs) or Concise Software IDs (CoSWIDs);
   see Section 5.1 of RFC 9393.

Contact:  IETF Chair <chair@ietf.org>

Change controller:  IESG <iesg@ietf.org>

Reference:  Section 5.1 of RFC 9393

   |  Note: This scheme has been documented by an IETF working group
   |  and is mentioned in an IETF Standard specification.  However,
   |  as it describes a locally scoped, limited-purpose form of
   |  identification, it does not fully meet the requirements for
   |  permanent registration.
   |
   |  As long as this specification (or any successors that describe
   |  this scheme) is a current IETF specification, this scheme
   |  should be considered to be "in use" and not considered for
   |  removal from the registry.

6.6.2. URI Scheme "swidpath"

IANA has registered the URI scheme "swidpath" too. same deal: it complies with [RFC7595] ๐Ÿ’…

Scheme name:  swidpath

Status:  Provisional

Applications/protocols that use this scheme name:  Applications that
   require Software IDs (SWIDs) or Concise Software IDs (CoSWIDs);
   see Section 5.2 of RFC 9393.

Contact:  IETF Chair <chair@ietf.org>

Change controller:  IESG <iesg@ietf.org>

Reference:  Section 5.2 of RFC 9393

   |  Note: This scheme has been documented by an IETF working group
   |  and is mentioned in an IETF Standard specification.  However,
   |  as it describes a locally scoped, limited-purpose form of
   |  identification, it does not fully meet the requirements for
   |  permanent registration.
   |
   |  As long as this specification (or any successors that describe
   |  this scheme) is a current IETF specification, this scheme
   |  should be considered to be "in use" and not considered for
   |  removal from the registry.

6.7. CoSWID Model for Use in SWIMA Registration

okay so this one is about SWIMA, and it's giving collection vibes ๐Ÿ’œ "Software Inventory Message and Attributes (SWIMA) for PA-TNC" [RFC8412] is a standardized way to collect an endpoint device's software inventory. A CoSWID can be evidence that some software got installed, and SWIMA can use and exchange that evidence ๐Ÿฆ‹ So this registration adds a new entry to the IANA "Software Data Model Types" registry, which is defined by [RFC8412] and [IANA.pa-tnc-parameters], so CoSWID works in SWIMA:

  • Pen: 0
  • Integer: 2
  • Name: Concise Software Identifier (CoSWID)
  • Reference: RFC 9393

Deriving Software Identifiers: bestie, this is the naming formula ๐Ÿงš A Software Identifier generated from a CoSWID tag is a concatenation written in the form used in [RFC5234], like this:

TAG_CREATOR_REGID "_" "_" UNIQUE_ID

Here, TAG_CREATOR_REGID is the reg-id item value of the tag's entity item that has the role value of 1 (that's "tag-creator" ๐Ÿ‘‘), and UNIQUE_ID is the same tag's tag-id item. If the tag-id item's value is expressed as a 16-byte binary string, the UNIQUE_ID MUST be represented using the UUID string representation defined in [RFC4122], including the "urn:uuid:" prefix.

The TAG_CREATOR_REGID and the UNIQUE_ID are connected with a double underscore (_), with no other connecting character or whitespace. Literally no extra characters allowed ๐Ÿ™ˆ


7. Signed CoSWID Tags โœจ

okay so SWID tags, as defined in the ISO-19770-2:2015 XML Schema, can carry cryptographic signatures to protect the integrity of the tag ๐Ÿ” Usually the tag creator signs it (typically, though not always, the vendor of the software component the SWID tag identifies). Signatures make any change to the tag detectable, which matters a LOT when the tag is providing RIMs for files ๐Ÿ˜ญ The ISO-19770-2:2015 XML Schema uses XML Digital Signatures (XMLDSIG) to do the signing.

Signing CoSWID tags follows the procedures defined in CBOR Object Signing and Encryption (COSE) [RFC9052]. A CoSWID tag MUST be wrapped in a COSE Signature structure, either COSE_Sign1 or COSE_Sign. In the first case, a Single Signer Data Object (COSE_Sign1) has one signature and MUST be signed by the tag creator. The CDDL below defines a restrictive subset of COSE header parameters that MUST be used in the protected header in this case ๐Ÿ’…

Here's the COSE_Sign1 version:

<CODE BEGINS> file "sign1.cddl"
COSE_Sign1-coswid<payload> = [
    protected: bstr .cbor protected-signed-coswid-header,
    unprotected: unprotected-signed-coswid-header,
    payload: bstr .cbor payload,
    signature: bstr,
]

cose-label = int / tstr
cose-values = any

protected-signed-coswid-header = {
    1 => int,                      ; algorithm identifier
    3 => "application/swid+cbor",
    * cose-label => cose-values,
}

unprotected-signed-coswid-header = {
    * cose-label => cose-values,
}
<CODE ENDS>

The COSE_Sign structure lets more than one signature be applied to a CoSWID tag. One of those signatures MUST be issued by the tag creator, and the structure MAY be used this way ๐Ÿฆ‹ The usage scenarios are domain specific and need well-specified application guidance, so don't wing it bestie.

And here's the COSE_Sign version:

<CODE BEGINS> file "sign.cddl"
COSE_Sign-coswid<payload> = [
    protected: bstr .cbor protected-signed-coswid-header1,
    unprotected: unprotected-signed-coswid-header,
    payload: bstr .cbor payload,
    signature: [ * COSE_Signature ],
]

protected-signed-coswid-header1 = {
    3 => "application/swid+cbor",
    * cose-label => cose-values,
}

protected-signature-coswid-header = {
    1 => int,                      ; algorithm identifier
    * cose-label => cose-values,
}

unprotected-signed-coswid-header = {
    * cose-label => cose-values,
}

COSE_Signature =  [
    protected: bstr .cbor protected-signature-coswid-header,
    unprotected: unprotected-signed-coswid-header,
    signature: bstr
]
<CODE ENDS>

Also, the COSE header countersignature MAY be used as an attribute in the unprotected header map of the COSE envelope of a CoSWID [RFC9338]. Countersigning lets second parties put a signature on a signature, which gives proof that a signature existed at a given time (basically a timestamp ๐Ÿ•ฐ๏ธ).

A CoSWID MUST be signed, using the mechanism above, to protect the integrity of the CoSWID tag. Check Section 9 ("Security Considerations") for more on why a signed CoSWID is valuable in most cases. Spoiler: it's a lot ๐Ÿ’€


8. CBOR-Tagged CoSWID Tags ๐ŸŽ€

okay so this spec allows both tagged and untagged CBOR data items to be CoSWID tags ๐ŸŒˆ Because of that, the CBOR tag this document defines for CoSWID tags (Table 21) SHOULD be used together with CBOR data items that are CoSWID tags. Other CBOR tags MUST NOT be used with a CBOR data item that is a CoSWID tag. If tagged, both signed and unsigned CoSWID tags MUST use the CoSWID CBOR tag. If a signed CoSWID is tagged, a CoSWID CBOR tag MUST be appended before the COSE envelope, whether that envelope is a COSE_Untagged_Message or a COSE_Tagged_Message. If an unsigned CoSWID is tagged, a CoSWID CBOR tag MUST be appended before the CBOR data item that is the CoSWID tag ๐Ÿ“

<CODE BEGINS> file "tags.cddl"
coswid = unsigned-coswid / signed-coswid
unsigned-coswid = concise-swid-tag / tagged-coswid<concise-swid-tag>
signed-coswid1 = signed-coswid-for<unsigned-coswid>
signed-coswid = signed-coswid1 / tagged-coswid<signed-coswid1>

tagged-coswid<T> = #6.1398229316(T)

signed-coswid-for<payload> = #6.18(COSE_Sign1-coswid<payload>)
    / #6.98(COSE_Sign-coswid<payload>)
<CODE ENDS>

This spec also lets a CBOR-tagged CoSWID tag sit inside a COSE envelope that's also tagged with a CoSWID CBOR tag. When the tag creator isn't a signer (like hand-offs between entities in a trusted part of a supply chain), keeping the CBOR tags on unsigned CoSWID tags can be super useful ๐Ÿซถ Still, redundant use of tags SHOULD be avoided when possible, so don't stack tags just because you can โœจ

9. Security Considerations ๐Ÿ”’โœจ

okay bestie, this one is SERIOUS ๐Ÿ˜ญ but we're gonna make it readable. The following security considerations for the use of CoSWID tags focus on:

  • ensuring the integrity and authenticity of a CoSWID tag ๐Ÿ”
  • the application of CoSWID tags to address security challenges related to unmanaged or unpatched software ๐Ÿ› ๏ธ
  • reducing the potential for unintended disclosure of a device's software load ๐Ÿซฃ

So a tag counts as "authoritative" if the software provider is the one who created it ๐Ÿ’…. An authoritative tag has info about a software component that comes from the supplier of that component, who is expected to be an expert in their own software ๐Ÿง . So yeah, authoritative tags can represent authoritative information about the component โœจ. How much you can trust that info depends on the tag's chain of custody (who has handled it along the way ๐Ÿงพ) and whether you can verify a signature from the supplier, if one is in the tag. Provisioning and validation are handled by local policy and are outside the scope of this doc, bestie ๐Ÿ“œ.

A signed CoSWID tag (check out Section 7 ๐ŸŽ€) whose signature has been validated can be trusted to be unchanged since the moment it was signed ๐Ÿ”. Unsigned tags, on the other hand? Any user or process with write access to the tag can change their data ๐Ÿ˜ฌ. To make signature validation work, you need to link the right key to the software provider (or whoever originated the signature) in a secure way ๐Ÿ—๏ธ. That part is application specific, so the app or its user has to handle it. A specific approach for it is out of scope for this document.

When an authoritative tag is signed, you can verify who originated the signature ๐Ÿ‘€. A trustworthy link between the signature and its originator can be built via trust anchors โš“. A certification path from a trust anchor down to a certificate, including the public key that validates a tag signature, can be used to judge how trustworthy an authoritative tag is ๐Ÿ…. Checking that the software provider is the actual signer is a different story ๐Ÿ™ˆ. You have to verify that the party who signed the tag is the same party named in the software-creator role of the tag's entity item. No mechanism is defined in this document to make that association, so local policy has to handle it. And as always, a valid signature does not mean the signed statements are true ๐Ÿšฉ. Anyone can sign assertions saying the software is from a specific software-creator or that a specific persistent-id applies. Policy needs to evaluate these statements and decide if they're suitable for a specific use.

Losing control of the signing credentials is a total nightmare ๐Ÿ’€. It would cast doubt on the authenticity and integrity of any CoSWID tags signed with the compromised keys. In that case, the legitimate tag signer (namely, the software provider for an authoritative CoSWID tag) can use uncompromised signing credentials to create a new signature on the original tag. The tag's version number would not be incremented, since the tag itself was not modified. Consumers of CoSWID tags would need to validate the tag using the new credentials, and they'd also need to use revocation information for the compromised credentials so they don't validate tags signed with them. The process for doing this is beyond the scope of this specification.

The CoSWID format lets you use hash values without an accompanying hash algorithm identifier ๐Ÿค”. That exposes tags to some risk of cross-algorithm attacks. We believe this can only become a practical problem if some implementations allow insecure hash algorithms. It may not become known right away when an algorithm becomes insecure, so the advice is strong: only support hash algorithms that are generally considered secure, and not just marginally so ๐Ÿ”ฅ.

CoSWID tags are meant to contain public information about software components ๐Ÿ“ข. So the contents of a CoSWID tag (as opposed to the set of tags that apply to the endpoint; see below) don't need to be protected against unintended disclosure on an endpoint. The flip side is that generators of CoSWID tags need to make sure only public information gets disclosed. The entitlement-key item is a prime example of info that needs extra care. Tag authors are advised not to record unprotected, private software license keys in this field ๐Ÿ™…โ€โ™€๏ธ.

CoSWID tags are meant to be easy to find for authorized applications and users on an endpoint, so it's simple to figure out the tagged software load ๐Ÿ”Ž. Still, access to the collection of an endpoint's CoSWID tags needs to be limited to authorized applications and users, using an appropriate access control mechanism ๐Ÿ”.

The tag-id of a CoSWID tag can be used as a global index value, so failing to keep each tag-id unique can cause collisions or ambiguity in the CoSWID tags retrieved or processed with it ๐Ÿ’ฅ. CoSWID is designed to not require a registry of identifiers, so the tag creator has to use a method of generating a unique tag identifier ๐Ÿ†”. Specific methods for that are beyond the scope of this specification. A collision in tag-ids can cause false positives or negatives in software integrity checks, or misidentification of installed software. That undermines CoSWID use cases like vulnerability identification and software inventory ๐Ÿ˜ต. If a collision is detected, the tag consumer may want to contact the maintainer of the CoSWID so they can issue a correction for it. But heads up: that also tells the maintainer that the consumer has the other tag with that tag-id in their database ๐Ÿ‘€. More generally, a tag consumer needs to be robust against these collisions, or the collision could become a viable attack vector ๐Ÿฆน.

CoSWID tags are designed to be easily added and removed from an endpoint along with the installation or removal of software components ๐Ÿ”„. On endpoints where adding or removing software is tightly controlled, adding or removing CoSWID tags can be controlled the same way ๐Ÿ”’. On more open systems, where lots of users can manage the software inventory, CoSWID tags are easier to add or remove ๐Ÿ™Œ. On those systems, it can be possible to add or remove CoSWID tags in a way that doesn't match the actual presence or absence of the software components. Also, not all software products automatically install CoSWID tags, so products can be on an endpoint without a matching CoSWID tag ๐Ÿซ . So any collection of CoSWID tags cannot automatically be assumed to be a complete or fully accurate picture of the endpoint's software inventory. Still, especially on endpoint devices that more strictly control adding or removing applications, CoSWID tags are an easy way to get a preliminary understanding of that endpoint's software inventory ๐Ÿ’–.

CoSWID tags don't expire โณ, so if new CoSWID tags can't reach an intended consumer, that consumer gets stuck with outdated info. That could leave vulnerabilities or weaknesses unmitigated ๐Ÿ˜ฑ. So a CoSWID tag consumer should actively check for updated tag-versions via more than one means ๐Ÿ”.

This specification uses relative paths (like filesystem paths) in several places ๐Ÿ—บ๏ธ. A signed CoSWID tag can't use those to derive info that is covered under the signature. Typically, relative filesystem paths identify targets for an installation, not sources of tag information ๐Ÿ“‚.

Any report of an endpoint's CoSWID tag collection tells you about that endpoint's software inventory ๐Ÿ“‹. If an attacker gets that report, they can learn which software products and versions are on the endpoint. By checking that list, the attacker might find applications that are vulnerable to certain types of attacks ๐Ÿฅ€. As noted earlier, CoSWID tags are designed to be easily discoverable by authorized applications and users on an endpoint. That doesn't pose a significant risk, since an attacker would already need access to the endpoint to view that info ๐Ÿ™„. But when the endpoint sends its software inventory to another party, or the inventory gets stored on a server for later analysis, attackers who don't have access to the endpoint could potentially see it ๐Ÿ‘ป. So it's important to protect the confidentiality of CoSWID tag info collected from an endpoint, both in transit and at rest. The reason isn't that the tags individually hold sensitive info. It's that the collection of CoSWID tags, and their association with an endpoint, reveals info about that endpoint's attack surface ๐ŸŽฏ.

Finally, both the ISO-19770-2:2015 XML Schema SWID definition and the CoSWID CDDL specification allow for building "infinite" tags with link item loops ๐ŸŒ€. They can also carry malicious content meant to create non-deterministic states during validation or processing of those tags ๐Ÿ‘พ. Software providers are unlikely to do this, but CoSWID tags can be created by any party. The CoSWID tags collected from an endpoint could be a mix of vendor-made and non-vendor-made tags ๐Ÿงฉ. So a CoSWID tag might contain potentially malicious content. Input sanitization, loop detection, and signature verification are ways implementations can address this concern ๐Ÿ›ก๏ธ.

More generally speaking, the Security Considerations sections of [RFC8949], [RFC9052], and [RFC9338] apply ๐Ÿ“š.


10. Privacy Considerations ๐Ÿซฃ๐ŸŒธ

As noted in Section 9, info collected about an endpoint's software load, like what an endpoint's CoSWID tag collection represents, could be used by attackers to find vulnerable software ๐Ÿ•ต๏ธโ€โ™€๏ธ. Collections of endpoint software info can also have privacy implications for users ๐Ÿ’œ. The set of apps a user installs can give clues about personal stuff like political affiliation, banking and investments, gender, sexual orientation, medical concerns, etc. ๐Ÿ˜ณ. Having a collection of CoSWID tags on an endpoint wouldn't increase privacy risks, since anyone who can view those tags could also view the apps themselves ๐Ÿคทโ€โ™€๏ธ. But if those CoSWID tags get gathered and stored in a repository somewhere, then seeing into the repository also means seeing into a user's app collection ๐Ÿ‘€. So repositories of collected CoSWID tags need to be protected against collection by malicious parties. Even authorized parties need to be vetted and made aware of the privacy responsibilities that come with access to this info ๐Ÿ”. Likewise, users should be made aware that their software inventories are being collected from endpoints ๐Ÿซถ. And when authorized parties or systems collect and store inventory data, that data needs to be protected as both security-sensitive and privacy-sensitive info ๐ŸŒˆ.


11. References ๐Ÿ“š๐Ÿ’…

11.1. Normative References ๐Ÿ“šโœจ

okay bestie, here's the reading list ๐Ÿซถ these are the docs this one leans on, and they're all listed exactly as the original gives them ๐Ÿ’…

[BCP178] Saint-Andre, P., Crocker, D., and M. Nottingham, "Deprecating the "X-" Prefix and Similar Constructs in Application Protocols", BCP 178, RFC 6648, June 2012. <https://www.rfc-editor.org/info/bcp178>

[BCP26] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, June 2017. <https://www.rfc-editor.org/info/bcp26>

[IANA.cbor-tags] IANA, "Concise Binary Object Representation (CBOR) Tags", <https://www.iana.org/assignments/cbor-tags>.

[IANA.core-parameters] IANA, "Constrained RESTful Environments (CoRE) Parameters", <https://www.iana.org/assignments/core-parameters>.

[IANA.media-types] IANA, "Media Types", <https://www.iana.org/assignments/media-types>.

[IANA.named-information] IANA, "Named Information", <https://www.iana.org/assignments/named-information>.

[IANA.pa-tnc-parameters] IANA, "Posture Attribute (PA) Protocol Compatible with Trusted Network Connect (TNC) Parameters", <https://www.iana.org/assignments/pa-tnc-parameters>.

[IANA.uri-schemes] IANA, "Uniform Resource Identifier (URI) Schemes", <https://www.iana.org/assignments/uri-schemes>.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <https://www.rfc-editor.org/info/rfc3629>.

[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.

[RFC5198] Klensin, J. and M. Padlipsky, "Unicode Format for Network Interchange", RFC 5198, DOI 10.17487/RFC5198, March 2008, <https://www.rfc-editor.org/info/rfc5198>.

[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.

[RFC5646] Phillips, A., Ed. and M. Davis, Ed., "Tags for Identifying Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009, <https://www.rfc-editor.org/info/rfc5646>.

[RFC5890] Klensin, J., "Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework", RFC 5890, DOI 10.17487/RFC5890, August 2010, <https://www.rfc-editor.org/info/rfc5890>.

[RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, <https://www.rfc-editor.org/info/rfc7252>.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8288] Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, October 2017, <https://www.rfc-editor.org/info/rfc8288>.

[RFC8412] Schmidt, C., Haynes, D., Coffin, C., Waltermire, D., and J. Fitzgerald-McKay, "Software Inventory Message and Attributes (SWIMA) for PA-TNC", RFC 8412, DOI 10.17487/RFC8412, July 2018, <https://www.rfc-editor.org/info/rfc8412>.

[RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, <https://www.rfc-editor.org/info/rfc8610>.

[RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, <https://www.rfc-editor.org/info/rfc8949>.

[RFC9052] Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, August 2022, <https://www.rfc-editor.org/info/rfc9052>.

[RFC9338] Schaad, J., "CBOR Object Signing and Encryption (COSE): Countersignatures", STD 96, RFC 9338, DOI 10.17487/RFC9338, December 2022, <https://www.rfc-editor.org/info/rfc9338>.

[SAM] "Information technology - IT asset management - Part 5: Overview and vocabulary", ISO/IEC 19770-5:2015, August 2015, <https://www.iso.org/standard/68291.html>.

[SWID] "Information technology - IT asset management - Part 2: Software identification tag", ISO/IEC 19770-2:2015, October 2015, <https://www.iso.org/standard/65666.html>.

[UNSPSC] "United Nations Standard Products and Services Code", 2022, <https://www.unspsc.org/>.

[W3C.REC-mediaqueries-3-20220405] Rivoal, F., Ed., "Media Queries Level 3", W3C Recommendation REC-mediaqueries-3-20220405, 5 April 2022, <https://www.w3.org/TR/mediaqueries-3/>.

[W3C.REC-xmlschema-2-20041028] Biron, P. V., Ed. and A. Malhotra, Ed., "XML Schema Part 2: Datatypes Second Edition", W3C Recommendation REC-xmlschema-2-20041028, 28 October 2004, <https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/>.

[W3C.REC-xpath20-20101214] Berglund, A., Ed., Boag, S., Ed., Chamberlin, D., Ed., Fernรกndez, M. F., Ed., Kay, M., Ed., Robie, J., Ed., and J. Simรฉon, Ed., "XML Path Language (XPath) 2.0 (Second Edition)", W3C Recommendation REC-xpath20-20101214, 14 December 2010, <https://www.w3.org/TR/2010/REC-xpath20-20101214/>.


11.2. Informative References ๐ŸŒธ

these ones are the extra-credit reading, lowkey super helpful for context ๐Ÿงš

[CamelCase] "Camel Case (upper camel case)", 18 December 2014, <http://wiki.c2.com/?CamelCase>.

[KebabCase] "Kebab Case", 29 August 2014, <http://wiki.c2.com/?KebabCase>.

[RFC3444] Pras, A. and J. Schoenwaelder, "On the Difference between Information Models and Data Models", RFC 3444, DOI 10.17487/RFC3444, January 2003, <https://www.rfc-editor.org/info/rfc3444>.

[RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI 10.17487/RFC4122, July 2005, <https://www.rfc-editor.org/info/rfc4122>.

[RFC7595] Thaler, D., Ed., Hansen, T., and T. Hardie, "Guidelines and Registration Procedures for URI Schemes", BCP 35, RFC 7595, DOI 10.17487/RFC7595, June 2015, <https://www.rfc-editor.org/info/rfc7595>.

[RFC8322] Field, J., Banghart, S., and D. Waltermire, "Resource-Oriented Lightweight Information Exchange (ROLIE)", RFC 8322, DOI 10.17487/RFC8322, February 2018, <https://www.rfc-editor.org/info/rfc8322>.

[RFC8520] Lear, E., Droms, R., and D. Romascanu, "Manufacturer Usage Description Specification", RFC 8520, DOI 10.17487/RFC8520, March 2019, <https://www.rfc-editor.org/info/rfc8520>.

[RFC9334] Birkholz, H., Thaler, D., Richardson, M., Smith, N., and W. Pan, "Remote ATtestation procedureS (RATS) Architecture", RFC 9334, DOI 10.17487/RFC9334, January 2023, <https://www.rfc-editor.org/info/rfc9334>.

[SEMVER] Preston-Werner, T., "Semantic Versioning 2.0.0", <https://semver.org/spec/v2.0.0.html>.

[SWID-GUIDANCE] Waltermire, D., Cheikes, B. A., Feldman, L., and G. Witte, "Guidelines for the Creation of Interoperable Software Identification (SWID) Tags", NISTIR 8060, April 2016, <https://doi.org/10.6028/NIST.IR.8060>.

[X.1520] ITU-T, "Common vulnerabilities and exposures", ITU-T Recommendation X.1520, January 2014, <https://www.itu.int/rec/T-REC-X.1520>.


Acknowledgments ๐Ÿ™โœจ

this document draws heavily on the concepts defined in the ISO/IEC 19770-2:2015 specification. the authors are grateful for the prior work of the 19770-2 contributors ๐ŸŒˆ

they're also grateful for the careful reviews from the IESG reviewers, with special thanks going to Benjamin Kaduk ๐Ÿ’œ

Contributors ๐Ÿซถ

Carsten Bormann
Universitรคt Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63921
Email: cabo@tzi.org

Carsten Bormann contributed to the CDDL specifications and the IANA considerations ๐ŸŽ€

Authors' Addresses ๐Ÿ’…

Henk Birkholz
Fraunhofer SIT
Rheinstrasse 75
64295 Darmstadt
Germany
Email: henk.birkholz@sit.fraunhofer.de
Jessica Fitzgerald-McKay
National Security Agency
9800 Savage Road
Ft. Meade, Maryland 20755
United States of America
Email: jmfitz2@cyber.nsa.gov
Charles Schmidt
The MITRE Corporation
202 Burlington Road
Bedford, Massachusetts 01730
United States of America
Email: cmschmidt@mitre.org
David Waltermire
National Institute of Standards and Technology
100 Bureau Drive
Gaithersburg, Maryland 20877
United States of America
Email: david.waltermire@nist.gov
๐Ÿ“ฆ where this page comes from