Internet DRAFT - draft-bormann-cbor-cddl-modules
draft-bormann-cbor-cddl-modules
CBOR C. Bormann
Internet-Draft Universität Bremen TZI
Intended status: Standards Track 10 March 2023
Expires: 11 September 2023
CDDL Module Structure
draft-bormann-cbor-cddl-modules-00
Abstract
At the time of writing, the Concise Data Definition Language (CDDL)
is defined by RFC 8610 and RFC 9165. The latter has used the
extension point provided in RFC 8610, the _control operator_.
As CDDL is being used in larger projects, the need for corrections
and additional features has become known that cannot be easily mapped
into this single extension point. Hence, there is a need for
evolution of the base CDDL specification itself.
The present document defines a backward- and forward-compatible way
to add a module structure to CDDL.
// Previous versions of the changes in this document were part of
// draft-bormann-cbor-cddl-2-draft and previously draft-bormann-cbor-
// cddl-freezer. This submission extracts out the functionality that
// is ready for WG adoption and further WG work.
About This Document
This note is to be removed before publishing as an RFC.
The latest revision of this draft can be found at https://cbor-
wg.github.io/cddl-modules/. Status information for this document may
be found at https://datatracker.ietf.org/doc/draft-bormann-cbor-cddl-
modules/.
Discussion of this document takes place on the CBOR Working Group
mailing list (mailto:cbor@ietf.org), which is archived at
https://mailarchive.ietf.org/arch/browse/cbor/. Subscribe at
https://www.ietf.org/mailman/listinfo/cbor/.
Source for this draft and an issue tracker can be found at
https://github.com/cbor-wg/cddl-modules.
Bormann Expires 11 September 2023 [Page 1]
Internet-Draft CDDL Module Structure March 2023
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 11 September 2023.
Copyright Notice
Copyright (c) 2023 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Conventions and Definitions . . . . . . . . . . . . . . . 3
2. Module superstructure . . . . . . . . . . . . . . . . . . . . 4
2.1. Compatibility . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Namespacing . . . . . . . . . . . . . . . . . . . . . . . 4
2.3. "Directives", the "module" . . . . . . . . . . . . . . . 5
2.4. Naming and Finding Modules . . . . . . . . . . . . . . . 5
2.5. Basic Set of Directives . . . . . . . . . . . . . . . . . 6
2.6. Explicit selection of names . . . . . . . . . . . . . . . 7
include . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
import . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.7. Tool Support for Command-Line Control . . . . . . . . . . 9
3. Security Considerations . . . . . . . . . . . . . . . . . . . 10
4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10
5. References . . . . . . . . . . . . . . . . . . . . . . . . . 10
Bormann Expires 11 September 2023 [Page 2]
Internet-Draft CDDL Module Structure March 2023
5.1. Normative References . . . . . . . . . . . . . . . . . . 10
5.2. Informative References . . . . . . . . . . . . . . . . . 10
Appendix A. ABNF Specification . . . . . . . . . . . . . . . . . 11
Appendix B. A CDDL 2.0 Tool . . . . . . . . . . . . . . . . . . 11
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 12
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 12
1. Introduction
At the time of writing, the Concise Data Definition Language (CDDL)
is defined by RFC 8610 and RFC 9165. The latter has used the
extension point provided in RFC 8610, the _control operator_.
As CDDL is being used in larger projects, the need for corrections
and additional features has become known that cannot be easily mapped
into this single extension point. Hence, there is a need for
evolution of the base CDDL specification itself.
The present document defines a backward- and forward-compatible way
to add a module structure to CDDL.
// Previous versions of the changes in this document were part of
// draft-bormann-cbor-cddl-2-draft and previously draft-bormann-cbor-
// cddl-freezer. This submission extracts out the functionality that
// is ready for WG adoption and further WG work.
// Proposals for additional functionality that needs more work can be
// found in [I-D.bormann-cbor-cddl-2-draft]. Proposals for other
// additions to the CDDL specification base are in
// [I-D.draft-bormann-cbor-cddl-freezer].
The present document is intended to be the specification base of what
has colloquially been called CDDL 2.0, a term hat is now focusing on
module structure (other documents make up what is now called CDDL
1.1). Additional documents describe further work on CDDL.
1.1. Conventions and Definitions
The Terminology from [RFC8610] applies.
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.
Bormann Expires 11 September 2023 [Page 3]
Internet-Draft CDDL Module Structure March 2023
2. Module superstructure
_Compatibility_: bidirectional (both backward and forward)
Originally, CDDL was used for small data models that could be
expressed in a few lines. As the size of data models that need to be
expressed in CDDL has increased, the need to modularize and re-use
components is increasing.
CDDL 1.0 has been designed with a crude form of composition:
Concatenating a number of CDDL snippets creates a valid CDDL data
model unless there is a name collision (identical redefinition is
allowed to facilitate this approach). With larger models, managing
the name space to avoid collisions becomes more pressing.
The knowledge which CDDL snippets need to be concatenated in order to
obtain the desired data model lives entirely outside the CDDL
snippets in CDDL 1.0. In CDDL 2.0, rules are packaged as modules and
referenced from other modules, providing methods for control of
namespace pollution.
Further work may be expended on unambiguous referencing into evolving
specifications ("versioning") and selection of alternatives (as was
emulated with snippets in Section 11 of [RFC8428]. Note that one
approach for expressing variants is demonstrated in [useful] based on
Section 4 of [RFC9165]). See also Section 4 of
[I-D.bormann-cbor-cddl-2-draft].
2.1. Compatibility
To achieve the module structure in a way that is friendly to existing
environments that operate with CDDL 1.0 snippets and CDDL 1.0
implementations, we add a super-syntax (similar to the way pragmas
are often added to a language), by carrying them in what is parsed as
comments in CDDL 1.0.
This enables each module source file to be valid CDDL\ 1 (but
possibly needing to add some rule definitions imported from other
source files).
2.2. Namespacing
When importing rules from other modules, there is the potential for
name collisions. This is exacerbated when the modules evolve, which
may lead to the introduction of a name into an imported module that
is also used (likely in a different way) in the importing module.
Bormann Expires 11 September 2023 [Page 4]
Internet-Draft CDDL Module Structure March 2023
To be able to manage names in such a way that collisions can be
avoided, we introduce means to prepend a prefix to the names of rules
being imported: the "as" clause.
2.3. "Directives", the "module"
This specification introduces _directives_ into CDDL. A single CDDL
file becomes a _module_ by processing the (zero or more) directives
in it.
The semantics of the module are independent of the module(s) using
it, however, importing a module may involve transforming its rule
names into a new namespace (Section 2.2).
Directives look like comments in CDDL 1, so they do not interfere
with forward compatibility.
Lines starting with the prefix ;# are parsed as directives in
CDDL 2.0.
2.4. Naming and Finding Modules
We assume that module names are filenames taken from one of several
source directories available to the CDDL 2.0 processor via the
environment. This avoids the need to nail down brittle pathnames or
(partial?) URIs into the CDDL files.
The exact way how these source directories and possibly a precedence
between them are established is intentionally not fully defined in
this specification; it is expected that this will be specified in the
context of the models just as the way they are intended to be used
will be. (A more formal structure may follow later.)
In the CDDL 2.0 Tool described in Appendix B, the set of sources is
determined from an environment variable, CDDL_INCLUDE_PATH, which is
modeled after usual command-line search paths. It is a colon-
separated list of pathnames to directories, with one special feature:
an empty element points to the tool's own collection. This
collection contains fragments of extracted CDDL from published RFCs,
using names such as rfc9052.
(Future versions might augment this with Web extractors and/or ways
to extract CDDL modules from github and from Internet-Drafts; see
Appendix A.2 of [I-D.bormann-cbor-cddl-2-draft] for some design
considerations.)
The default CDDL_INCLUDE_PATH is:
Bormann Expires 11 September 2023 [Page 5]
Internet-Draft CDDL Module Structure March 2023
.:
That is: files are found in the current directory (.) and, if not
found there, cddlc’s collection.
In the examples following, a cddlc command line will be shown
(starting with an isolated $ sign) with the CDDL 2.0 input; the
resulting CDDL 1 will be shown separately.
2.5. Basic Set of Directives
Two groups of directives are defined at this point:
* include, which includes all the rules from a module (which
includes the ones imported/included there, transitively), or
specific explicitly selected rules (clause ending in "from");
* import, which includes only those rules from the module that are
referenced, implicitly or explicitly (clause ending in "from"),
including the rules that are referenced from these rules,
transitively.
The include function is more useful for composing a single model from
parts controlled by one author, while the import function is more
about treating a module as a library:
The way an import works is shown by this simple example:
$ cddlc -2tcddl -
start = COSE_Key
;# import rfc9052
This results in the following CDDL 1.0 specification:
start = COSE_Key
COSE_Key = {
1 => tstr / int,
? 2 => bstr,
? 3 => tstr / int,
? 4 => [+ tstr / int],
? 5 => bstr,
* label => values,
}
label = int / tstr
values = any
Bormann Expires 11 September 2023 [Page 6]
Internet-Draft CDDL Module Structure March 2023
This is appropriate for using libraries that are well known to the
importing specification. However, if it is not acceptable that the
library can pollute the namespace of the importing module, the import
directive can specify a namespace prefix ("as" clause):
$ cddlc -2tcddl -
start = cose.COSE_Key
;# import rfc9052 as cose
This results in the following CDDL 1.0 specification:
start = cose.COSE_Key
cose.COSE_Key = {
1 => tstr / int,
? 2 => bstr,
? 3 => tstr / int,
? 4 => [+ tstr / int],
? 5 => bstr,
* cose.label => cose.values,
}
cose.label = int / tstr
cose.values = any
Note how the imported names are prefixed with cose. as specified in
the import directive, but CDDL prelude (Appendix D of [RFC8610])
names such as tstr and any are not.
2.6. Explicit selection of names
Both import and include directives can be augmented by an explicit
mentioning of rule names (clause ending in "from").
include
Starting with include:
$ cddlc -2tcddl -
mydata = {* label => values}
;# include label, values from rfc9052
With include, only exactly the rules mentioned are included:
mydata = {* label => values}
label = int / tstr
values = any
The module from which rules are explicitly imported can be
namespaced:
Bormann Expires 11 September 2023 [Page 7]
Internet-Draft CDDL Module Structure March 2023
$ cddlc -2tcddl -
mydata = {* label => values}
;# include cose.label, cose.values from rfc9052 as cose
Again, only exactly the rules mentioned are included:
mydata = {* label => values}
cose.label = int / tstr
cose.values = any
import
Both examples would work exactly the same with import, as the
included rules do not reference anything else from the included
module.
An import however also draws in the transitive closure of the rules
referenced:
$ cddlc -2tcddl -
mydata = {Fritz: cose.empty_or_serialized_map}
;# import cose.empty_or_serialized_map from rfc9052 as cose
The transitive closure of the rules mentioned is included:
mydata = {"Fritz" => cose.empty_or_serialized_map}
cose.empty_or_serialized_map = bstr .cbor cose.header_map / bstr .size 0
cose.header_map = {
cose.Generic_Headers,
* cose.label => cose.values,
}
cose.Generic_Headers = (
? 1 => int / tstr,
? 2 => [+ cose.label],
? 3 => tstr / int,
? 4 => bstr,
? (5 => bstr // 6 => bstr),
)
cose.label = int / tstr
cose.values = any
The import statement can also request an alias for an imported name:
$ cddlc -2tcddl -
mydata = {Fritz: cose.empty_or_serialized_map}
;# import empty_or_serialized_map from rfc9052 as cose
Bormann Expires 11 September 2023 [Page 8]
Internet-Draft CDDL Module Structure March 2023
Note how an additional rule provides an alias for
empty_or_serialized_map that does not have the namespace prefix:
mydata = {"Fritz" => cose.empty_or_serialized_map}
empty_or_serialized_map = cose.empty_or_serialized_map
cose.empty_or_serialized_map = bstr .cbor cose.header_map / bstr .size 0
cose.header_map = {
cose.Generic_Headers,
* cose.label => cose.values,
}
cose.Generic_Headers = (
? 1 => int / tstr,
? 2 => [+ cose.label],
? 3 => tstr / int,
? 4 => bstr,
? (5 => bstr // 6 => bstr),
)
cose.label = int / tstr
cose.values = any
2.7. Tool Support for Command-Line Control
Tools may provide a convenient way to initiate the processing of
directives from the command line.
A tool may provide a way to root the module tree from the command
line:
$ cddlc -2tcddl -icose=rfc9052 -scose.COSE_Key
The command line argument -icose=rfc9052 is a shortcut for
;# import rfc9052 as cose
Together with the start rule name, cose.COSE_Key, this results in the
following CDDL 1.0 specification:
$.start.$ = cose.COSE_Key
cose.COSE_Key = {
1 => tstr / int,
? 2 => bstr,
? 3 => tstr / int,
? 4 => [+ tstr / int],
? 5 => bstr,
* cose.label => cose.values,
}
cose.label = int / tstr
cose.values = any
Bormann Expires 11 September 2023 [Page 9]
Internet-Draft CDDL Module Structure March 2023
In other words, the module synthesized from the command line had an
empty CDDL file, which therefore was not provided (no - on the
command line).
3. Security Considerations
The module structure specified in this document is not believed to
create additional security considerations beyond the general security
considerations in Section 5 of [RFC8610].
Implementations that employ the module structure defined in this
document need to ascertain the provenance of the modules they combine
into the CDDL models they employ operationally. This specification
does not define how the source directories accessed via the
CDDL_INCLUDE_PATH are populated; this process needs to undergo the
same care and scrutiny as any other introduction of source code into
a build environment.
4. IANA Considerations
This document has no IANA actions.
5. References
5.1. Normative References
[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/rfc/rfc2119>.
[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/rfc/rfc8174>.
[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/rfc/rfc8610>.
[RFC9165] Bormann, C., "Additional Control Operators for the Concise
Data Definition Language (CDDL)", RFC 9165,
DOI 10.17487/RFC9165, December 2021,
<https://www.rfc-editor.org/rfc/rfc9165>.
5.2. Informative References
Bormann Expires 11 September 2023 [Page 10]
Internet-Draft CDDL Module Structure March 2023
[cddlc] "CDDL conversion utilities", n.d.,
<https://github.com/cabo/cddlc>.
[I-D.bormann-cbor-cddl-2-draft]
Bormann, C., "CDDL 2.0 -- a draft plan", Work in Progress,
Internet-Draft, draft-bormann-cbor-cddl-2-draft-01, 5
March 2023, <https://datatracker.ietf.org/doc/html/draft-
bormann-cbor-cddl-2-draft-01>.
[I-D.draft-bormann-cbor-cddl-freezer]
Bormann, C., "A feature freezer for the Concise Data
Definition Language (CDDL)", Work in Progress, Internet-
Draft, draft-bormann-cbor-cddl-freezer-10, 24 October
2022, <https://datatracker.ietf.org/doc/html/draft-
bormann-cbor-cddl-freezer-10>.
[RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C.
Bormann, "Sensor Measurement Lists (SenML)", RFC 8428,
DOI 10.17487/RFC8428, August 2018,
<https://www.rfc-editor.org/rfc/rfc8428>.
[useful] "Useful CDDL", n.d.,
<https://github.com/cbor-wg/cddl/wiki/Useful-CDDL>.
Appendix A. ABNF Specification
TO DO
directive = ";#" RS (%s"import" / %s"include") RS [from-clause]
filename [as-clause] CRLF
from-clause = 1*(id [","] RS) %s"from" RS
as-clause = RS %s"as" RS id
filename = 1*("-" / "." / %x30-39 / %x41-5a / "_" / %x61-7a)
id = ("$" / %x40-5a / "_" / %x61-7a)
*("$" / %x30-39 / %x40-5a / "_" / %x61-7a)
RS = 1*WS
WS = SP
SP = %x20
CRLF = %x0A / %x0D.0A
Appendix B. A CDDL 2.0 Tool
This appendix is for information only.
A rough CDDL 2.0 tool is available [cddlc]. It can process CDDL 2.0
models into CDDL 1 models that can then be processed by the CDDL tool
described in Appendix F of [RFC8610].
Bormann Expires 11 September 2023 [Page 11]
Internet-Draft CDDL Module Structure March 2023
A typical command line involving both tools might be:
cddlc -2 -tcddl mytestfile.cddl | cddl - gp 10
Install on a system with a modern Ruby (Ruby version ≥ 3.0) via:
gem install cddlc
The present document assumes the use of cddlc version 0.1.6.
Acknowledgments
TODO acknowledge.
Author's Address
Carsten Bormann
Universität Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63921
Email: cabo@tzi.org
Bormann Expires 11 September 2023 [Page 12]