Web of Things (WoT) Thing Description

W3C Working Editor's Draft 21 October 2018

This version:
https://www.w3.org/TR/2018/WD-wot-thing-description-20181021/ https://w3c.github.io/wot-thing-description/
Latest published version:
https://www.w3.org/TR/wot-thing-description/
Latest editor's draft:
https://w3c.github.io/wot-thing-description/
Previous version: https://www.w3.org/TR/2018/WD-wot-thing-description-20180405/ Editors:
Sebastian Kaebisch ( Siemens AG )
Takuki Kamiya ( Fujitsu Laboratories of America, Inc. )
Contributors:
In the GitHub repository
Repository:
We are on GitHub
File a bug

Editor's note : First draft based on Simplified TD This is the first draft of the new simplified TD approach based on JSON-LD 1.1. Some definitions are not finished yet and are still in progress. A stable Thing Description deliverable version based on JSON-LD 1.0 can be found here .

Abstract

This document describes a formal model and a common representation for a Web of Things (WoT) Thing Description. A Thing Description describes the metadata and interfaces of Things, where a Thing is an abstraction of a physical or virtual entity that provides interactions to and participates in the Web of Things. Thing Descriptions provide a set of interactions based on a small vocabulary that makes it possible both to integrate diverse devices and to allow diverse applications to interoperate. Thing Descriptions, by default, are encoded in a JSON format that also allows JSON-LD processing. The latter provides a powerful foundation to represent knowledge about Things in a machine-understandable way. A Thing Description instance can be hosted by the Thing itself or hosted externally when a Thing has resource restrictions (e.g., limited memory space) or when a Web of Things-compatible legacy device is retrofitted with a Thing Description.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

Implementers need to be aware that this specification is considered unstable. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the repository and take part in the discussions.

Editor's note : The W3C WoT WG is asking for feedback Please contribute to this draft using the GitHub Issue feature of the WoT Thing Description repository. For feedback on security and privacy considerations, please use the WoT Security and Privacy Issues, as security and privacy is cross-cutting over all our documents.

This document was published by the Web of Things Working Group as a Working an Editor's Draft. This document is intended to become a W3C Recommendation.

Comments regarding this document are welcome. Please send them to public-wot-wg@w3.org ( archives ).

Changes from the previous publication can be found in Appendix B . A diff-marked version of this document is also available for comparison purposes. Publication as a Working an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .

This document is governed by the 1 February 2018 W3C Process Document .

1. Introduction

The Thing Description (TD) is a central building block in the W3C Web of Things (WoT) and can be considered as the entry point of a Thing (much like the index.html of a Web site). The TD consists of semantic metadata for the Thing itself, an interaction model based on WoT's Properties , Actions , and Events paradigm, a semantic schema to make data models machine-understandable, and features for Web Linking to express relations among Things.

Properties can be used for sensing and controlling parameters, such as getting the current value or setting an operation state. Actions model invocation of physical (and hence time-consuming) processes, but can also be used to abstract RPC-like calls of existing platforms. Events are used for the push model of communication where notifications, discrete events, or streams of values are sent asynchronously to the receiver. In general, the TD provides metadata for different communication bindings identified by URI schemes (e.g., "http", "coap", "mqtt", etc.), media content types (e.g., "application/json", "application/xml", "application/cbor", "application/exi" etc.), and security mechanisms (for authentication, authorization, confidentiality, etc.). Serialization of TD instances is based on JSON and includes at least the TD core vocabulary as JSON keys names as defined in this specification document.

Example 1 shows a simple TD instance in such a JSON serialization serializiation and depicts WoT's Properties , Actions , and Events paradigm by describing a lamp Thing with the name MyLampThing .

Based on this content, we know there exists one Property interaction resource with the name status . In addition, information is provided to indicate that this Property is accessible via (the secure form of) the HTTP protocol with a GET method at the URI https://mylamp.example.com/status (announced within the forms structure by the href key), name), and will return a string status value. The use of the GET method is not stated explicitly, but is one of the default assumptions defined by this document. document and explained in [ WOT-PROTOCOL-BINDING ].

In a similar manner, an Action is specified to toggle the switch status using the POST method applied to the https://mylamp.example.com/toggle resource, where POST is again a default assumption for invoking Actions.

The Event pattern enables a mechanism for asynchronous messages to be sent by a Thing. Here, a subscription to be notified upon a possible overheating event of the lamp can be obtained by using the HTTP with its long polling sub-protocol at https://mylamp.example.com/oh .

This example also specifies the basic security scheme, requiring a username and password for access. Note that a security scheme is first given a name in a securityDefinition and then activated by specifying that name in a security section. In combination with the use of the HTTP protocol this indicates example demonstrates the use of HTTP Basic Authentication. Specification of a at least one security scheme at the top level as in this example indicates that it is required mandatory, and gives the default access requirements for every resource. However, security schemes can also be specified per-interaction or per-form, with lower-level configurations overriding higher-level ones, allowing for the specification of fine-grained access control. Examples It is also possible to use a special nosec security scheme to indicate that no access control mechanisms are used. Additional examples will be provided later.

The TD in Example 1 reflects some additional defined default assumptions that are not explicitly described. For example, the media content type of the exchange format of the interactions is assumed to be JSON (= mediaType contentType ) and the Property status resource is not writable readOnly as well as not observable. observable . Specifically, the TD specification defines vocabulary terms ( (e.g., writable readOnly , writeOnly , observable , mediaType contentType ) that have default values. If these vocabulary terms are not explicitly used in a Thing Description instance, the Thing Description processor follows default assumptions for interpretation as defined in this specification. The Full tab in Example 1 shows the identical information of the simple form of the Thing Description instance, but includes these mentioned implicit vocabulary terms with its default values.

The TD Thing Description offers the possibility to add context knowledge from different namespaces. This mechanism can be also processed used to add additional semantics, such as an RDF-based model. In that case, specific domain knowledge, to the content of the Thing Description instance needs instance, and to be transformed into valid JSON-LD first. In terms specify some configurations and behavior of JSON-LD 1.1 serialization, the open-world assumption of RDF semantic processing requires vocabulary terms with default values to be always present explicitly underlying communication protocols declared in the instances. forms field. Example 2 shows extends the same TD in a sample from Example 1 and uses the @context known from JSON-LD 1.1 serialization representing exactly to introduce the same information as in Example 1; however, default values have been filled in. http context. This context is used to specify explicitly the http methods for the property and action within the forms .

For more examples, including The TD can be also processed as an RDF-based model. In that case, the use of other protocols besides HTTP, see Section 7. Example Thing Description Instances . instance needs to be transformed into valid JSON-LD first which will be specified in this document.

2. Terminology

Generic WoT terminology is defined in [ WOT-ARCHITECTURE ]: Thing , Thing Description (in short TD ), Web of Things (in short WoT ), WoT Interface etc.

3. Namespaces

The namespace for the W3C TD Thing Description vocabulary as defined in this document is http://www.w3.org/ns/td .

Using content negotiation, this namespace serves either the TD ontology file (Turtle) or the TD context file (JSON-LD).

The suggested prefix for the TD namespace is td . The security ontology that can be used with the TD is available at https://www.w3.org/ns/wot-security . The data schema ontology that can be used with the TD is available at https://www.w3.org/ns/json-schema . Editor's note : Binding Vocabulary and Prefixes The TD will reuse existing vocabulary definitions such as for http from the http://www.w3.org/2011/http# namespace. In that case the prefix http is used. However, there are prefixes such as coap and mqtt which have no namespace yet. Currently there are efforts to have such namespace representations which will be referenced in the TD specification in the future. In the meantime, the [ WOT-PROTOCOL-BINDING ] provides the list of terms that can be used to specify the protocol metadata in the Thing Description.

4. Conformance

As well as all sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MUST , MUST NOT , REQUIRED , SHOULD , SHOULD NOT , RECOMMENDED , MAY , and OPTIONAL in this specification are to be interpreted as described in [ RFC2119 ].

A Thing Description instance complies with this specification if it follows the normative statements in Section 5. Information Model and Section 6. Thing Description Serialization regarding Thing Description serialization.

A JSON Schema [ JSON-SCHEMA-VALIDATION ] is provided in Annex A. JSON Schema for TD Instance Validation to validate Thing Description instances based on JSON-LD 1.1. JSON serialization.

Editor's note

In the future some information about RDF validation will be provided.

5. Information Model

5.1 Overview

The W3C Thing Description provides a set of vocabulary for describing physical and virtual Things. To increase interoperability the vocabulary terms are defined using the Resource Description Framework (RDF). All vocabulary restrictions noted in these tables MUST be followed,including mandatory items and default values. In general, the Thing Description vocabulary set is grouped in three modules:

An overview of this vocabulary with its class context and class relation is given by the following three figures: the TD core model, the TD data schema model, and the TD security model. figures. Please note that the figures reflect the vocabulary terms and structure as they would be used in a Thing Description instance (see Section 6. Thing Description Serialization ).The full ontology definitions of the different modules can be viewed by following the namespaces as provided in Section ).

3. Namespaces Editor's note .

The following diagrams are automatically generated from the ontology files. The layout will be improved in one of the next TD updates.

TD core model figure
Figure 1 TD core model ( Click SVG file )
TD data schema model figure
Figure 2 TD data schema model ( Click SVG file )
TD security model figure
Figure 3 TD security model ( Click SVG file )
Editor's note : Default Values and Mandatory Attributes

In the figures above, and in the tables to follow, items which have default values are indicated as being optional. However, technically, these are optional only in the JSON serialization . They are actually mandatory parts of the information model and are also mandatory in the JSON-LD serialization. In addition, the security scheme configuration is not actually optional even in the JSON serialization. Security configuration is mandatory at least one of the three levels at which it may be specified... so it can be omitted only if it is specified at a different level for each form. A future version of this document should better express the status of these attributes.

A detailed description of the vocabulary of the TD core model and TD data schema model is given in the next sub-section.

All vocabulary restrictions noted in tables in Section 5.2 Core Vocabulary Definition , 5.3 Data Schema Vocabulary Definition , and 5.4 Security Vocabulary Definition MUST be followed, including mandatory items and default values.

How to serialize these vocabulary terms to a Thing Description instance using a JSON-based representation is explained in section 6. Thing Description Serialization .

5.2 Core Vocabulary Definition

5.2.1 Thing

Describes a physical and/or virtual Thing (may represent one or more physical and/or virtual Things) in the Web of Things context. When a concrete Thing is defined in a Thing Description, it is called an "thing resource".

Field Name Vocabulary term Description Mandatory Default value Type
id unique identifier of the Thing (URI, e.g. custom URN) URN). yes . anyURI
description support Provides additional (human) readable information. information about the TD maintainer (e.g., author, link or telephone number to get support, etc). no . string
name lastModified Name of Provides information when the Thing. TD instance was last modified. yes no . string
descriptions Can be used to get support, etc). support (human-readable) information in different languages. no . string MultiLanguage
securityDefinitions Set of named security configurations (definitions only). Not actually applied unless names are used in a security section. no . SecurityScheme
version Provides version information. no . Versioning
base Define the base URI that is valid for all defined local interaction resources. All other URIs in the TD must then be resolved using the algorithm defined in [ RFC3986 ]. no . anyURI
properties created All Property-based interaction patterns of Provides information when the Thing. TD instance was created. no . Property string
forms Indicates one or more endpoints at which operation(s) on this resource are accessible. In this version of TD, all operations that can be described at the Thing level are concerning Properties.

Each endpoint is for accessing one or more of "readallproperties", "writeallproperties", "writemultipleproperties" and "readmultipleproperties" operations on the thing resource. (See an example. ) Payloads are assigned an object type schema with its properties equal to the Thing's property resources.
no . array of Form
actions All Action-based interaction patterns of the Thing. no . Action
security Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources at or below the current level, if not overridden at a lower level. yes . array of string
events All Event-based interaction patterns of the Thing. no . Event
links description Provides Web links to arbitrary resources that relate to the specified Thing Description. additional (human-readable) information based on a default language. no . array of Link string
security properties Set All Property-based interaction patterns of security configurations, provided as an array, that must all be satisfied for access to resources at or below the current level, if not overridden at a lower level. Thing. no . array Property
name Name of the Thing. yes . SecurityScheme string

5.2.2 InteractionPattern

Three interaction patterns are defined as subclasses: Property, Action and Event. When a concrete Property, Action or Event is defined in a Thing Description, it is called an "interaction resource". Interactions between Things can be as simple as one Thing accessing another Thing's data to get or (in the case the data is also writable) change the representation of data such as metadata, status or mode. A Thing may also be interested in getting asynchronously notified of future changes in another Thing, or may want to initiate a process served in another Thing that may take some time to complete and monitor the progress. Interactions between Things may involve exchanges of data between them. This data can be either given as input by the client Thing, returned as output by the server Thing or both.

Each instance of a Property , Action , and Event class MUST have an identifier that is unique within the context of a Thing Description document. See Section Representation Format for more details about JSON-LD 1.1 identifiers.
Field Name Vocabulary term Description Mandatory Default value Type
forms descriptions Indicates one or more endpoints from which an interaction pattern is accessible. Can be used to support (human-readable) information in different languages. yes no . array of Form MultiLanguage
label title Provides a label human-readable title (e.g., display a text for UI representation) of the interaction pattern. pattern based on a default language. no . string
description scopes Provides additional (human) readable information. Set of authorization scope identifiers, provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. no . array of string
uriVariables Define URI template variables as collection based on DataSchema declarations. no . DataSchema
forms Indicates one or more endpoints at which operation(s) on this resource are accessible. yes . array of Form
titles Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages) of the interaction pattern. no . MultiLanguage
security Set of security configurations, provided as an array, that definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources at or below the current level, if not overridden at a lower level. no . array of SecurityScheme string
scopes description Set of authorization scope identifiers, provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources Provides additional (human-readable) information based on a client may access and how. default language. no . array of string

The class InteractionPattern has the following subclasses:

Each instance of a Property , Action , and Event class MUST have an identifier that is unique within the context of a Thing Description document.

5.2.3 Property

Properties expose internal state of a Thing that can be directly retrieved (get) and optionally modified (set). In addition, Things can also choose to make Properties observable by pushing the new state (not an event) after a change; this must follow eventual consistency (also see CAP Theorem).

Field Name Vocabulary term Description Mandatory Default value Type
observable Indicates whether a remote servient can subscribe to ("observe") the Property, to receive change notifications or periodic updates (true/false). no false boolean false writable Boolean value that indicates whether a property is writable (=true) or not (=false). no false boolean
Note

Property instances may are also be instances of the class DataSchema and therefore . Therefore, it can contain, among others, contain the type , unit , readOnly term. and writeOnly members, among others.

5.2.4 Action

Actions offer functions of the Thing. These functions may manipulate the internal state of a Thing in a way that is not possible through setting Properties. Examples are changing internal state that is not exposed as a Property, changing multiple Properties, changing Properties over time or with a process that should not be disclosed. Actions may also be pure functions, that is, they may not use any internal state at all, and may simply process input data and return a result that directly depends only on the input given.

Field Name Vocabulary term Description Mandatory Default value Type
input Link Used to define the n-ary class that allows the declaration of the accepted input data type schema of an the action. no . DataSchema
output safe Link to Signals if the n-ary class action is safe (=true) or not. Used to signal if there is no internal state (cf. resource state) is changed when invoking an Action. In that allows case responses can be cached as example. yes false boolean
idempotent Indicates whether the declaration of action is idempotent (=true) or not. Informs whether the action can be called repeatedly with the same result, if present, based on the same input. yes false boolean
output Used to define the output data type returned by an schema of the action. no . DataSchema

5.2.5 Event

The Event Interaction Pattern describes event sources that asynchronously push messages. Here not state, but state transitions (events) are communicated (e.g., "clicked"). Events may be triggered by internal state changes that are not exposed as Properties. Events usually follow strong consistency, where messages need to be queued to ensure eventual delivery of all events that have occurred.

Instances of the Event class contains the term definitions of the class InteractionPattern and DataSchema . 5.2.6 Form Communication metadata indicating where a service can be accessed by a client application. An interaction might have more than one form. application/json
Field Name Vocabulary term Description Mandatory Default value Type
href data URI Defines the data schema of the endpoint where an interaction pattern is provided. Event instance messages pushed by the Thing. yes no . anyURI DataSchema
mediaType cancellation Assign the underlying media type [ MEDIATYPES ] of an interaction pattern. Defines any data that needs to be passed to cancel a subscription, e.g., a specific message to remove a Webhook. no . string DataSchema
rel subscription Indicates the expected result of performing the operation described by the form. For example, the Property interaction allows get and set operations. The protocol binding may contain a form for the get operation and a different form for the set operation. The rel attribute indicates which form is which and allows the client Defines data that needs to select the correct form for the operation required. The value of the rel attribute of the form must be one of readproperty, writeproperty, observeproperty, invokeaction, subscribeevent, passed upon subscription, e.g., filters or unsubscribeevent. message format for setting up Webhooks. no . string DataSchema (one of "readproperty" , "writeproperty" , "observeproperty" , "invokeaction" , "subscribeevent" , or "unsubscribeevent" )

5.2.6 subProtocol Form Indicates the exact mechanism by which an interaction will be accomplished for a given protocol when there are multiple options. For example, for HTTP and Events, it indicates which of several available mechanisms should be used for asynchronous notifications. no . string

(one of "LongPoll" ) Communication metadata indicating where a service can be accessed by a client application. An interaction might have more than one form.

Vocabulary term Description Mandatory Default value Type
security Set of security configurations, provided as an array, that definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources at or below the current level, if not overridden at a lower level. no . array of SecurityScheme string
scopes Set of authorization scope identifiers, provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. no . array of string
5.2.7 Link response This optional term can be used if, e.g., the output communication metadata differ from input metdata (e.g., output contentType differ from the input contentType). The response name contains metadata that is only valid for the reponse messages. no . ExpectedResponse A Web link, as specified by IETF RFC 8288 (https://tools.ietf.org/html/rfc8288). Field Name Description Mandatory Default value Type
href subprotocol URI of Indicates the endpoint where exact mechanism by which an interaction pattern is provided. will be accomplished for a given protocol when there are multiple options.

For example, for HTTP and Events, it indicates which of several available mechanisms should be used for asynchronous notifications.

yes no . anyURI string (one of longpoll )
mediaType contentType Assign the underlying a content type based on a media type [ MEDIATYPES ] of an interaction pattern. (e.g., 'application/json) and (optional) parameters (e.g., 'charset=utf-8'). no yes application/json string
rel href URI of the endpoint where an interaction pattern is provided. yes . anyURI
op Indicates the expected result semantic intention of performing the operation operation(s) described by the form.

For example, the Property interaction allows get and set operations.
The protocol binding may contain a form for the get operation and a different form for the set operation.
The rel op attribute indicates which form is for which and allows the client to select the correct form for the operation required.

op can be assigned one or more interaction verb(s) each representing a semantic intention of an operation.

no . (array of) string each representing an interaction verb (EDNOTE: Link to wot-binding-templates) (one of readproperty , writeproperty , observeproperty , invokeaction , subscribeevent , unsubscribeevent , readallproperties , writeallproperties , readmultipleproperties , or writemultipleproperties )

5.2.8 Versioning

Carries version information about the TD instance. If required, additional version information such as firmware and hardware version (term definitions outside of the TD namespace) can be extended here.

Vocabulary term Description Mandatory Default value Type
instance Provides a version identicator of this TD instance. yes . string

5.2.9 ExpectedResponse

Communication metadata for response messages (e.g., contentType of the response).

Vocabulary term Description Mandatory Default value Type
contentType Assign a content type based on a media type [ MEDIATYPES ] (e.g., 'application/json) and (optional) parameters (e.g., 'charset=utf-8'). no . string

5.2.10 MultiLanguage

Container to provide human-readable text in different languages using language tags described in [ BCP47 ]. Each used language tags code MUST be decleared as vocabulary term member of this container (e.g., en, de, ja, zh-Hans, zh-Hant).

5.3 Data Schema Vocabulary Definition

5.3.1 DataSchema

Field Name Vocabulary term Description Mandatory Default value Type
description title Provides additional (human) readable information. a human-readable title (e.g., display a text for UI representation) of the interaction pattern based on a default language. no . string
oneOf Used to ensure that the data is valid against one of the specified schemas in the array. no . array of DataSchema
readOnly Boolean value that indicates whether a property interaction / value is read only (=true) or not (=false). yes false boolean
type Assignment of JSON-based data types compatible with JSON Schema (one of boolean, integer, number, string, object, array, or null). no . string (one of "boolean" object , "integer" array , "number" string , "string" number , "object" integer , "array" boolean , or "null" null )
descriptions Can be used to support (human-readable) information in different languages. no . MultiLanguage
description Provides additional (human-readable) information based on a default language. no . string
const Provides a constant value. no . a value of any type that is consistent with the type given to the above type field definition if any
enum Restricted set of values provided as an array. no . array of values of any type with each consistent with the type given to
titles Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages) of the above interaction pattern. no . type MultiLanguage field definition if any
writeOnly Boolean value that indicates whether a property interaction / value is write only (=true) or not (=false). yes false boolean
unit Provides unit information that is used, e.g., in international science, engineering, and business. no . string

The class DataSchema has the following subclasses:

5.3.2 ArraySchema

A JSON array specification ("type": "array").

items Used to define the characteristics of an array. no . DataSchema 5.3.3 ObjectSchema A JSON object specification ("type": "object"). Field Name Description Mandatory Default value Type required Defines which members of the object type are mandatory. no . array of string
Field Name Vocabulary term Description Mandatory Default value Type
minItems Defines the minimum number of items that have to be in the array. no . unsignedInt
maxItems Defines the maximum number of items that have to be in the array. no . unsignedInt
properties items Data schema nested definitions. Used to define the characteristics of an array. no . DataSchema

5.3.4 5.3.3 BooleanSchema

A JSON boolean value specification ("type": "boolean").

5.3.5 5.3.4 NumberSchema

A JSON number value specification ("type": "number").

Field Name Vocabulary term Description Mandatory Default value Type
minimum maximum Specifies a minimum maximum numeric value. Only applicable for associated number or integer types. no . double
maximum minimum Specifies a maximum minimum numeric value. Only applicable for associated number or integer types. no . double
5.3.6 StringSchema A JSON string value specification ("type": "string").

5.3.7 5.3.5 IntegerSchema

A JSON integer value specification, that is, numbers without a fractional part ("type": "integer").

Field Name Vocabulary term Description Mandatory Default value Type
minimum maximum Specifies a minimum maximum numeric value. Only applicable for associated number or integer types. no . integer
maximum minimum Specifies a maximum minimum numeric value. Only applicable for associated number or integer types. no . integer

5.3.6 ObjectSchema

A JSON object specification ("type": "object").

Vocabulary term Description Mandatory Default value Type
required Defines which members of the object type are mandatory. no . array of string
properties Data schema nested definitions. no . DataSchema

5.3.7 StringSchema

A JSON string value specification ("type": "string").

5.3.8 NullSchema

A JSON null value specification ("type": "null"). Is the type of null then it has only one acceptable value, namely null. E.g., it can be used as part of oneOf declearation, where it is used to indicate, that a data schema can also be null.

5.4 Security Vocabulary Definition

For the core TD vocabulary only well-established security mechanisms are supported, such as those built into protocols supported by WoT or already in wide use with those protocols. The current set of HTTP security schemes is partly based on OpenAPI 3.0.1 (see also [ OPENAPI ]). Note however that while the HTTP security schemes, vocabulary and syntax given in this specification share many similarities with OpenAPI they are not fully compatible. Also, since OpenAPI primarily targets web services built around HTTP, it does not cover the full set of use cases required for the IoT. Security schemes appropriate for IoT-centered protocols such as CoAP and MQTT are therefore also included.

Editor's note : Security Scheme Extensions

The vocabulary extension mechanism of the WoT Thing Description allows for additional security schemes if needed.However, needed. However, for more information about what additional security schemes or modifications are under discussion for the core WoT vocabulary(and vocabulary (and to file issues if you have a request) please visit the WoT Security TF repository.

5.4.1 SecurityScheme

Field Name Vocabulary term Description Mandatory Default value Type
scheme proxy Identification URI of the proxy server this security mechanism being configured. configuration provides access to. If not given, the corresponding security configuration is for the endpoint. yes no . string anyURI (one of "nosec" , "basic" , "cert" , "digest" , "bearer" , "pop" , "psk" , "public" , "oauth2" , or "apikey" )
description Provides additional (human) readable information. (human-readable) information based on a default language. no . string
proxyUrl scheme URI Identification of the proxy server this security configuration provides access to. If not given, the corresponding security configuration is for the endpoint. mechanism being configured. no yes . anyURI string (one of nosec , basic , cert , digest , bearer , pop , psk , public , oauth2 , or apikey )

The class SecurityScheme has the following subclasses:

5.4.2 NoSecurityScheme

A security configuration corresponding to ("scheme": "nosec"), indicating there is no authentication or other mechanism required to access the resource.

5.4.3 BasicSecurityScheme

Basic authentication security configuration ("scheme": "basic"), using an unencrypted username and password. This scheme should be used with some other security mechanism providing confidentiality, for example, TLS.

header .
Field Name Vocabulary term Description Mandatory Default value Type
in name Specifies the location of security authentication information (one of header, Name for query, body, header, or cookie). cookie parameters. no . string
name in Name for query, Specifies the location of security authentication information (one of header, query, body, or cookie parameters. cookie). no header string

5.4.4 CertSecurityScheme DigestSecurityScheme

Certificate-base asymmetric key Digest authentication security configuration ("scheme": "cert"). "digest"). This scheme is similar to basic authentication but with added features to avoid man-in-the-middle attacks.

Field Name Vocabulary term Description Mandatory Default value Type
identity in Pre-shared key identity. Specifies the location of security authentication information (one of header, query, body, or cookie). no header string
qop Quality of protection (one of auth or auth-int). no auth string
name Name for query, header, or cookie parameters. no . string

5.4.5 DigestSecurityScheme APIKeySecurityScheme

Digest API key authentication security configuration ("scheme": "digest"). "apikey"). This scheme is similar to basic authentication but with added features to avoid man-in-the-middle attacks. for the case where the access token is opaque and is not using a standard token format.

qop Quality of protection (one of auth or auth-int). no auth string
Field Name Vocabulary term Description Mandatory Default value Type
in Specifies the location of security authentication information (one of header, query, body, or cookie). no header query string
name Name for query, header, or cookie parameters. no . string

5.4.6 BearerSecurityScheme

Bearer token authentication security configuration ("scheme": "bearer"). This scheme is intended for situations where bearer tokens are used independently of OAuth2. If the oauth2 scheme is specified it is not generally necessary to specify this scheme as well as it is implied.

jwt .
Field Name Vocabulary term Description Mandatory Default value Type
authorizationUrl name URI of the authorization server. Name for query, header, or cookie parameters. no . anyURI string
alg Encoding, encryption, or digest algorithm (one of MD5, ES256, or ES512-256). no ES256 string
format authorization Specifies format of security authentication information (one URI of jwt, jwe, or jws). the authorization server. no . string anyURI
in Specifies the location of security authentication information (one of header, query, body, or cookie). no header string
name format Name for query, header, Specifies format of security authentication information (one of jwt, jwe, or cookie parameters. jws). no jwt string

5.4.7 PSKSecurityScheme CertSecurityScheme

Pre-shared Certificate-base asymmetric key authentication security configuration ("scheme": "psk"). "cert").

Field Name Vocabulary term Description Mandatory Default value Type
identity Pre-shared key identity. no . string

5.4.8 PublicSecurityScheme PSKSecurityScheme

Raw public key asymmetric Pre-shared key authentication security configuration ("scheme": "public"). "psk").

Field Name Vocabulary term Description Mandatory Default value Type
identity Pre-shared key identity. no . string

5.4.9 OAuth2SecurityScheme PublicSecurityScheme

OAuth2 authentication Raw public key asymmetric key security configuration ("scheme": "oauth2"). For the implicit flow the authorizationUrl and scopes are required. For the password and client flows both tokenUrl and scopes are required. For the code flow authorizationUrl, tokenUrl, and scopes are required. "public").

Field Name Vocabulary term Description Mandatory Default value Type
authorizationUrl identity URI of the authorization server. Pre-shared key identity. no . anyURI string

5.4.10 tokenUrl PoPSecurityScheme URI of the token server. no . anyURI

Proof-of-possession token authentication security configuration ("scheme": "pop").

. 5.4.10 APIKeySecurityScheme API key authentication security configuration ("scheme": "apikey"). This is for the case where the access token is opaque and is not using a standard token format. Field Name Description Mandatory Default value Type
Vocabulary term Description Mandatory Default value Type
refreshUrl name URI of the refresh server. Name for query, header, or cookie parameters. no . anyURI string
scopes in Set Specifies the location of authorization scope identifiers, provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. security authentication information (one of header, query, body, or cookie). no header array of string
flow format Authorization flow Specifies format of security authentication information (one of implicit, password, client, jwt, jwe, or code). jws). no implicit jwt string
in alg Specifies the location of security authentication information Encoding, encryption, or digest algorithm (one of header, query, body, MD5, ES256, or cookie). ES512-256). no query ES256 string
name authorization Name for query, header, or cookie parameters. URI of the authorization server. no . string anyURI

5.4.11 PoPSecurityScheme OAuth2SecurityScheme

Proof-of-possession token OAuth2 authentication security configuration ("scheme": "pop"). "oauth2"). For the implicit flow the authorization and scopes are required. For the password and client flows both token and scopes are required. For the code flow authorization, token, and scopes are required.

ES256 header
Field Name Vocabulary term Description Mandatory Default value Type
authorizationUrl authorization URI of the authorization server. no . anyURI
alg token Encoding, encryption, or digest algorithm (one URI of MD5, ES256, or ES512-256). the token server. no . string anyURI
format flow Specifies format of security authentication information Authorization flow (one of jwt, jwe, implicit, password, client, or jws). code). no jwt implicit string
in scopes Specifies the location of security authentication information (one Set of header, query, body, or cookie). authorization scope identifiers, provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. no . array of string
name refresh Name for query, header, or cookie parameters. URI of the refresh server. no . string anyURI

6. Thing Description Serialization

Editor's note : JSON-LD 1.1 This is the first draft that uses JSON-LD 1.1 as a serialization format of the Thing Description. As that is work in progress, working assumptions are based on the latest Community Draft of JSON-LD 1.1 . A new JSON-LD Working Group has already been chartered . It is planned that this section will conform to the latest working draft of their JSON-LD 1.1 deliverable and only use stable elements.

Thing Description instances are modeled and structured based on Section 5. Information Model . This section defines a TD serialization based on JSON [ RFC8259 ].

6.1 Basic Representation Format Assumptions

The JSON serialization of TDs follows the syntax of JSON-LD 1.1 in order to streamline semantic evaluation. Hence, serializations can be parsed either as raw JSON or with a JSON-LD 1.1 processor. In order to enable this convergence, all vocabulary terms defined in Section 5. 5.2 Information Model Core Vocabulary Definition will have a JSON key name representation.

In addition, Thing Description instances MAY contain JSON-LD 1.1 keywords such as @context and @type . The data types of the vocabulary as defined in Section 5.3 Data Schema Vocabulary Definition will be transformed to JSON-based types. The following rules are used for vocabulary terms based on some simple type definitions:

A Thing Description instance serialization MAY omit one ore more vocabulary terms that are mandatory AND have default values based on the definitions under 5.3 Data Schema Vocabulary Definition (e.g., readOnly and contentType ). In this specification, this form is referred to as Simple Thing Description representation. The processing of such Simple Thing Description representation will be explained in 6.4.1 Thing Description Processing . When a Thing Description instance carry all mandatory vocabulary terms we will call this representation as Full Thing Description.

In addition, Thing Description instances MAY contain additional JSON-LD keywords such as @context and @type . With these the Thing Description can be easily extended. You can find additional details in the Section 6.2 Context Extension . In the case of @type usage in the Thing Description instance, the @type MUST be serialized as JSON String or as JSON array of strings when multiple values are assigned to @type .

All vocabulary terms in Section 5. Information Model associated with more complex class-based types are defined separately for structured JSON type transformation in the following subsections.

6.1.1 Thing as a whole

The root object of a Thing Description instance MAY include the @context key name known from JSON-LD 1.1 with the value URI of the Thing description context file http://www.w3.org/ns/td .

{  
    "@context": "http://www.w3.org/ns/td",
    ...
}
Editor's note

http://www.w3.org/ns/td uses content negotiation to return the context file. Thus, it must be fetched with an Accept header set to application/ld+json .

When a Thing Description instance is processed and interpreted by a JSON-LD 1.1 processor the @context field MUST be present (see also Section JSON-LD 1.1 Processing ). When a single Thing Description instance involves several contexts, additional namespaces with prefixes MUST be appended to the @context array structure.

This option proves relevant if one wants to extend the existing Thing Description context without modifying it. For instance:

{
    "@context": ["http://www.w3.org/ns/td",
                {"iot": "hljs-string">"http://iotschema.org/"}],

"hljs-string">"http://example.org/iot"}],

    ...
}

Each mandatory and optional field member name as defined in the class Thing MUST be serialized as a JSON key name in the root object of the Thing Description instance.

The type of the fields members properties , actions , and events , version , and securityDefinitions MUST be a JSON object.

The type of the fields members forms , links , scopes , and security MUST be a JSON array.

A TD snippet based on the defined fields members of the class Thing without the optional field member @context is given below:

Alternatively, the same example can be written instead to explicitly include the (semantic) keys names used by JSON-LD 1.1 ( JSON-LD, namely @context and @type ): :

In that case the content can be directly associated as Thing Description based on the namespace http://www.w3.org/ns/td provided in the @context . The "@type": "Thing" associates an instantiations of the Thing class as defined in Section 5.2.1 Thing .

6.1.2 properties

Properties (and sub-properties) offered by a Thing MUST be collected in the JSON-object based properties field member with (unique) Property names as JSON keys. names.

Each mandatory and optional vocabulary term as defined in the class Property , as well as its two superclasses InteractionPattern and DataSchema , MUST be serialized as a JSON key name within a Property object. The type This means that at the level of an interaction property instance, the fields vocabulary terms of properties InteractionPattern and items DataSchema MUST can be serialized as a JSON object. presented at the same time.

The type of the fields members forms , required , and enum , scopes , and security , MUST be serialized as a JSON array.

A TD snippet based on the defined fields members is given below:

6.1.3 actions

Actions offered by a Thing MUST be collected in the JSON-object based actions field member with (unique) Action names as JSON keys. names.

Each optional vocabulary term as defined in the class Action and its superclass InteractionPattern MUST be serialized as a JSON key name within an Action object.

The type of the fields members input and output MUST be serialized as a JSON object.

The keys of names input and output rely on the the class DataSchema and will follow the serialization introduction provided in 6.1.9 Data Schema Representation .

The type of the fields members forms , scopes , and security MUST be serialized as a JSON array.

A TD snippet based on the defined fields members is given below:

6.1.4 events

Events offered by a Thing MUST be collected in the JSON-object based events field member with (unique) Event names as JSON keys. names.

Each optional vocabulary term as defined in the class Event , as well as its two superclasses InteractionPattern and DataSchema , MUST be serialized as a JSON key name within an Event object.

The type of the fields members properties subscription , data , and items cancellation MUST be serialized as a JSON object.

The type JSON names of the fields forms subscription , required data , and enum cancellation rely on the the class DataSchema and will follow the serialization introduction provided in 6.1.9 Data Schema Representation .

The type of the members forms , scopes , and security MUST be serialized as a JSON array.

A TD snippet based on the defined fields members is given below:

6.1.5 forms

Each mandatory and optional vocabulary term as defined in the class Form , MUST be serialized as a JSON key. name.

If required, the type of the member response MUST be serialized as a JSON array.

If required, forms MAY be supplemented with protocol-specific vocabulary terms identified with a prefix. See also 6.2 Context Extension .

A TD snippet based on the defined members is given below:

{  "@context": [
"hljs-string">"http://www.w3.org/ns/td",
    {"http": "http://www.w3.org/2011/http#"}],
  ...
  "securityDefinitions": {      "basic_sc": {
"hljs-string">"scheme":"basic", "in":"header"}
  },
    ...
    "forms": [{        "href" : 
"hljs-string">"http://mytemp.example.com:5683/temp",
        
"hljs-string">"contentType": "application/json",
        
"hljs-string">"http:methodName": "POST",
        "op": 
"hljs-string">"writeproperty",
        "security": [
"hljs-string">"basic_sc"]
    }]
    ...
}

href may also carry an URI that contains dynamic variables such as p and d in http://192.168.1.25/left?p=2&d=1. In that case the URI can be defined as template as defined in [ WOT-PROTOCOL-BINDING RFC6570 ]. ]: http://192.168.1.25/left{?p,d}

When a Thing Description instance is processed and interpreted by In such a JSON-LD 1.1 processor, each case these variables in the URI MUST be collected in the JSON-object based forms uriVariables (array) entry member with the associated (unique) variables names as JSON names.

Each defined JSON name of the uriVariables collection MUST rely on the the class DataSchema .

A TD snippet using URI template and uriVariables is given below:


"hljs-string">"@context": ["http://www.w3.org/ns/td",
    {"http": "http://www.w3.org/2011/http#"},
    {"eg": "http://www.example.org/iot"}],
...
"actions": {    "LeftDown": {      "uriVariables": {        "p" : { 
"hljs-string">"type": "integer", "minimum": 0, "maximum": 16, "@type": "eg:SomeKindOfAngle" },
        "d" : { 
"hljs-string">"type": "integer", "minimum": 0, "maximum": 1, "@type": "eg:Direction" }
        }
      },
      "forms": [{        
"hljs-string">"http:method": "GET",
        "href" : 
"hljs-string">"http://192.168.1.25/left{?p,d}"
      }]
    }
...

The contentType is used to assign a media types [ MEDIATYPES ] and MAY contain one or more parameters as attribute-value pair separated by a mediaType ; due to the open-world assumption character. Example:

...
"contentType" : "hljs-string">"application/text; charset=utf-8"
...

In some use cases, the form metadata of Linked Data. This assumption means that if a Linked Data model the interaction pattern must be distinguished between request and response based messages. E.g., an action 'takePhoto' defines an input to submit parameter settings of a Thing Description instance were to omit these vocabulary terms, then camera (aperture priority, timer,..) using json as content type (="contentType":"application/json"). The output of this action is the interpreter would not photo taken, which is available in jpeg format, for example. In such cases, the response can be able used to make any assumptions about their actual value. provide a response content type (e.g., "contentType":"image/jpeg").

If the response member is used in forms , it MUST contain the contentType as defined in class ExpectedResponse .

A TD form snippet with the response member is listed below based on the defined fields is given below: use case of the action 'takePhoto' described above:

... : [{ : <span class= "hljs-string">"http://mytemp.example.com:5683/temp", : <span class=
"hljs-string">"@context": ["http://www.w3.org/ns/td",
    {"http": "http://www.w3.org/2011/http#"}],
...
"forms": [
    {
      "href": 
"hljs-string">"http://upsq1c.local:9191/api/frame/crop",
      "contentType": "application/json",
    <span class=
"hljs-string">"http:methodName",
    : <span class=
"hljs-string">"writeProperty",
    : [{<span class=
"hljs-string">"scheme":<span class=
"hljs-string">"basic", <span class=
"hljs-string">"in":<span class=
"hljs-string">"header"}]
}]

      "op": ["hljs-string">"invokeaction"],
      
"hljs-string">"http:methodName": "POST",
      "response": {        
"hljs-string">"contentType": "image/jpeg"
      }
    }
  ]

...

When forms is present at the top level, it can be used to describe meta interactions supported by a Thing instance. For example, operations "readallproperties" and "writeallproperties" are meta interactions by which clients can read and write all properties of the thing at once. In the example below, forms is used at the top level, and the clients can access end point (i.e. https://mylamp.example.com/allproperties ) both to read or write all properties (i.e. "on" , "brightness" and "timer" property) of the thing by a single interaction.

{    "id": 
"hljs-string">"urn:dev:wot:com:example:servient:lamp",
    ...
    "forms": [
        {
          "href": 
"hljs-string">"https://mylamp.example.com/allproperties",
          
"hljs-string">"contentType": "application/json",
          "op": [
"hljs-string">"readallproperties", "writeallproperties"],
        }
    ],
    ...
    "properties": {        "on": {          "type": 
"hljs-string">"boolean",
          "forms": [...]
        },
        "brightness": {          "type": 
"hljs-string">"number",
          "forms": [...]
        },
        "timer": {          "type": 
"hljs-string">"integer",
          "forms": [...]
        }
    },
    ...
}

6.1.7 securityDefinitions and security

Each mandatory and optional vocabulary term as defined in the class SecurityScheme , MUST be serialized as a JSON key. name.

The following TD snippet shows a simple security configuration specifying basic username/password authentication in the header. The value of in given is actually the default value of header . First, a named security configuration must be given in a securityDefinitions block. Second, that definition must be activated in a security block.

...
: [{
    : <span class=

"securityDefinitions": {
    "basic_sc": {
        "scheme": "basic",
    : <span class=

        "in": "header"
}]

    }
},
...
"security": [
"hljs-string">"basic_sc"]

...

Here is a more complex example: a TD snippet showing digest authentication on a proxy combined with bearer token authentication on an endpoint. Here the default value of in in the digest scheme, header , is implied.

...
: [
    {

"securityDefinitions": {
    "basic_sc": {
       "scheme": "digest",
       : <span class=

       "proxy": "https://portal.example.com/"
    },
    {

    "bearer_sc": {
       "scheme": "bearer",
       "format": "jwt",
       "alg": "ES256",
       "hljs-string">"authorizationUrl": <span class=

"hljs-string">"authorization": 
"hljs-string">"https://servient.example.com:8443/"
    }
]

},
...
"security": [
"hljs-string">"basic_sc","bearer_sc"],

...

Security definitions can be given configuration is mandatory. Every Thing MUST have at more than least one security scheme specified at the top level. Security schemes MAY also be specified at the interaction and form levels. In this case, definitions at the lower levels override (completely replace) the definitions at the higher level.

Security configuration is mandatory. Every form in must accurately reflect the requirements of the Thing. If a Thing requires a specific access mechanism for a resource, that mechanism MUST have a security configuration either provided in the form itself, at the interaction level directly above it (if security is not configured be specified in the form), or at the Thing level (if Description's security is not configured in either the form or at the interaction level). In the vocabulary defined above, note scheme configuration for that security is marked as non-mandatory. However, this is only true locally (at a specific level), and only if the security is configured at resource. If a higher or lower level. In other words, Thing does not require a security configuration must be provided at some level specific access mechanism for each form. Security configuration is considered binding. The security configuration metadata provided in a Thing Description resource, that mechanism MUST NOT accurately reflect be specified in the Thing Description's security requirements of the Thing. scheme configuration for that resource.

Some protocols can ask for authentication dynamically.
If a protocol asks for a form of security credentials not declared in the Thing Description then the Thing Description is to be considered invalid.

The nosec security scheme is provided for the case that no security is needed. The minimal security configuration for a Thing is configuration of the nosec security scheme at the top level, as in the following example:

To give a more complex example, suppose we have a Thing where all interactions require basic authentication except for one interaction for which no authentication is required. In the following, the nosec scheme for the security configuration in the overheating event to indicate no authentication is required. For the status property and the toggle action, however, basic authentication is required as defined at the top level of the Thing.

{
    ...
    : [{<span class=

    "securityDefinitions": {
        "nosec_sc": {"scheme": "hljs-string">"basic"}],

"hljs-string">"nosec"},
        "basic_sc": {
"hljs-string">"scheme": "basic"}
    },
    "security": [
"hljs-string">"basic_sc"],
    ...

    "properties": {
        "status": {
            ...
            "forms": [{
                "href": "https://mylamp.example.com/status",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json",
            }]
        }
    },
    "actions": {
        "toggle": {
            ...
            "forms": [{
                "href": "https://mylamp.example.com/toggle",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json"
            }]
        }
    },
    "events": {
        "overheating": {
            ...
            "forms": [{
                "href": "https://mylamp.example.com/oh",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json",
                "hljs-string">"security": [{<span class=
"hljs-string">"scheme": <span class=
"hljs-string">"nosec"}] 

"hljs-string">"security": ["nosec_sc"] 

            }]
        }
    }
}

Security definitions configurations can also can be given specified for different elements at the same level. This may be required for devices that support multiple protocols, for example CoAP and HTTP, with support for different security mechanisms. This is also useful when alternative authentication mechanisms are allowed. Here is a TD snippet demonstrating three possible ways to access a resource: via HTTPS with basic authentication, via HTTPS via digest authentication, or via CoAPS with an API key. In other words, the use of multiple security configurations at the same level provides a way to combine security mechanisms an in "OR" fashion. In contrast, putting multiple security configurations in the same security field member combines them in an "AND" fashion, since in that case they would all need to be satisfied to allow access to the resource. Note that a security declaration is still mandatory at the Thing level. Here we use a nosec scheme for symmetry but could also have used any one of the other ones as it will be overridden in each form.

...
"hljs-string">"securityDefinitions": {
    "nosec_sc": {
"hljs-string">"scheme": "nosec"},
    "basic_sc": {
"hljs-string">"scheme": "basic"},
    "digest_sc": {
"hljs-string">"scheme": "digest"},
    "apikey_sc": {
"hljs-string">"scheme": "apikey"}
},
"security": [
"hljs-string">"nosec_sc"]
...

"properties": {
    "status": {
        ...
        "forms": [
            {
                "href": "https://mylamp.example.com/status",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json",
                "hljs-string">"security": [{<span class=
"hljs-string">"scheme": <span class=
"hljs-string">"basic"}]

"hljs-string">"security": ["basic_sc"]

            },
            {
                "href": "https://mylamp.example.com/status",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json",
                "hljs-string">"security": [{<span class=
"hljs-string">"scheme": <span class=
"hljs-string">"digest"}]

"hljs-string">"security": ["digest_sc"]

            },
            {
                "href": "coaps://mylamp.example.com:5683/status",
                "hljs-string">"mediaType": <span class=

"hljs-string">"contentType": 
"hljs-string">"application/json",
                "hljs-string">"security": [{<span class=
"hljs-string">"scheme": <span class=
"hljs-string">"apikey"}]

"hljs-string">"security": ["apikey_sc"]
            }
        ]
    }
},
...

As another more complex example, OAuth2 makes use of scopes. These are identifiers that may appear in tokens and must match with corresponding identifiers in a resource to allow access to that resource. For example, in the following, the "status" property can be read by users using bearer tokens containing the scope "limited" but the "configure" action can only be used when the interaction is invoked with a token containing the "special" scope. Scopes are not identical to roles but are often associated with them; for example, perhaps only those in an administrative role can perform "special" interactions. Tokens can have more than one scope. In this example, an administrator would probably be issued tokens with both the "limited" and "special" scopes while ordinary users would only be issued tokens with the "limited" scope.

..."securityDefinitions": {    "oauth2_sc": {        "scheme": 
"hljs-string">"oauth2",
        ...
        "scopes": [
"hljs-string">"limited","special"]
    }
},
"security": [
"hljs-string">"oauth2_sc"],
"properties": {    "status": {
        ...
        "forms": [
            {
                
"hljs-string">"href": "https://scopes.example.com/status",
                
"hljs-string">"contentType": "application/json",
                
"hljs-string">"scopes": ["limited"]
            }
        ]
    }
},
"action": {    "configure": {
        ...
        "forms": [
            {
                
"hljs-string">"href": "https://scopes.example.com/configure",
                
"hljs-string">"contentType": "application/json",
                
"hljs-string">"scopes": ["special"]

            }
        ]
    }
},
...

6.1.8 version

The mandatory vocabulary term as defined in the class Versioning , MUST be serialized as a JSON name.

The recommended version identification pattern value is to rely on the semantic versioning policy: [ SemVer ]

A TD snippet based on the defined members is given below:

..."version": {
"hljs-string">"instance":"1.2.1"}
...

The version container MAY be used to provide additional application and/or device specific version information based on terms from non-TD namespaces.

A TD snippet based on such additional version metadata from a v context is given below:


"hljs-string">"@context": ["http://www.w3.org/ns/td",
            {"v": "http://www.example.org/versioningTerms#"}],
...
"version": {
"hljs-string">"instance":"1.2.1", "v:firmware": "0.9.1", "v:hardware": "1.0"}
...

6.1.9 Data Schema Representation

The data schema concept within the Thing Description is based on a subset of JSON schema terms. The data schema concept is applied to the properties interaction declaration, input and output within actions interaction declaration, subscription , data and cancellation within events interaction declaration, and uriVariables that can be used within the forms container.

Each mandatory and optional vocabulary term as defined in the class DataSchema , MUST be serialized as a JSON name.

The type of the members properties and items MUST be serialized as a JSON object.

The type of the member enum , required , and oneOf MUST be serialized as a JSON array.

A TD snippet based on the defined members is given below:

..."type": 
"hljs-string">"object",
"properties": {    "status": {        "title": 
"hljs-string">"Status",
        "type": 
"hljs-string">"string",
        "enum": [
"hljs-string">"On", "Off", "Error"]
    },
    "brightness": {        "title": 
"hljs-string">"Brightness value",
        "type": 
"hljs-string">"number",
        "minimum": 
"hljs-number">0.0,
        "maximum": 
"hljs-number">100.0
    },
    "rgb": {        "title": 
"hljs-string">"RGB color value",
        "type": 
"hljs-string">"array",
        "items" : {            "type" : 
"hljs-string">"number",
            
"hljs-string">"minimum": 0,
            
"hljs-string">"maximum": 255
        },
        "minItems": 
"hljs-number">3,
        "maxItems": 
"hljs-number">3
    }
},
...

The terms readOnly and writeOnly MAY be used to signalize which data members are exchanged for a read request (e.g., read an interaction property) and which one for a write process (e.g. write an interaction property).

An TD snippet with the usage of readOnly and writeOnly is given below:

...    "properties": {        "status": {          
"hljs-string">"description": "Read or write On/Off status.",
          "type": 
"hljs-string">"object",
          "properties": {            "latestStatus": {              "type": 
"hljs-string">"string",
              
"hljs-string">"enum": ["On", "Off"],
              
"hljs-string">"readOnly": true
            },
            "newStatusValue": {              "type": 
"hljs-string">"string",
              
"hljs-string">"enum": ["On", "Off"],
              
"hljs-string">"writeOnly": true
            }
          },
          forms:[...]
        }
      }
...

If the interaction property status is read, the status data is returned using latestStatus in the payload. To manipulate the status of the interaction property, the new value must be provided by assigning newStatusValue in the payload.

As an additional feature, a Thing Description instance allows the usage of the term unit within data schema definitions. This can be used to associates some unit information to some data members. The unit values can be free selected, however, it is recommended to select units based on existing definitions by integrating the corresponding namespace context (e.g., from Smart Appliances REFerence (SAREF) ontology or Ontology of units of Measure (OM)).

{"@context": [
"hljs-string">"http://www.w3.org/ns/td",
            {"om": "http://www.wurvoc.org/vocabularies/om-1.8/"}],
...
"properties": {    "latestValues": {        
"hljs-string">"description": "Provides all current values of the weather station.",
        "type": 
"hljs-string">"object",
        "properties": {        "temperature": {            "type": 
"hljs-string">"number",
            
"hljs-string">"minimum" : -32.5,
            
"hljs-string">"maximum" : -55.2,
            "unit": 
"hljs-string">"om:degree_Celsius"
        },
        "humidity": {            "type": 
"hljs-string">"number",
            
"hljs-string">"minimum" : 0,
            
"hljs-string">"maximum" : 100,
            "unit": 
"hljs-string">"om:percent"
        }
        },
        forms:[...]
    }
}
...

6.1.10 titles and descriptions

The vocabulary terms titles and descriptions enables human-readable text description in multi-languages using language tags described in [ BCP47 ]. Whenever the vocabulary terms titles and descriptions can be used, both MUST be serialized as JSON Object. The member names of the JSON Object MUST be the language tags as defined in [ BCP47 ] (e.g., "en", "de", "ja", "zh-Hans", "zh-Hant"). The value of each member MUST be serialized as JSON string.

A TD snippet using titles and descriptions in different levels is given below:

{    "name": 
"hljs-string">"MyThing",
    "descriptions": {        "en":
"hljs-string">"Human readable information.",
        "de": 
"hljs-string">"Menschenlesbare Informationen.",
        "ja" : 
"hljs-string">"人間が読むことができる情報",
        "zh-Hans" : 
"hljs-string">"人们可阅读的信息", 
        "zh-Hant" : 
"hljs-string">"人們可閱讀的資訊"
    },
    ...
    "properties": {        "on": {            "titles": {                "en": 
"hljs-string">"On/Off",
                "de": 
"hljs-string">"An/Aus",
                "ja": 
"hljs-string">"オンオフ",
                
"hljs-string">"zh-Hans": "开关",
                
"hljs-string">"zh-Hant": "開關" },
            "type": 
"hljs-string">"boolean",
            "forms": [...]
        },
        "status": {            "titles": {                "en": 
"hljs-string">"Status",
                "de": 
"hljs-string">"Zustand",
                "ja": 
"hljs-string">"状態",
                
"hljs-string">"zh-Hans": "状态",
                
"hljs-string">"zh-Hant": "狀態" },
            "type": 
"hljs-string">"object",
            ...
}

TD instances may also additional use title and description beside of titles and descriptions . If title and titles description and descriptions are defined at the same time at the JSON level, title and description MAY be seen as default text.

{    "name": 
"hljs-string">"MyThing",
    "description": 
"hljs-string">"Menschenlesbare Informationen.",
    "descriptions": {        "en":
"hljs-string">"Human readable information.",
        "de": 
"hljs-string">"Menschenlesbare Informationen.",
        "ja" : 
"hljs-string">"人間が読むことができる情報",
        "zh-Hans" : 
"hljs-string">"人们可阅读的信息", 
        "zh-Hant" : 
"hljs-string">"人們可閱讀的資訊"
    },
    ...
    "properties": {        "on": {            "title" : 
"hljs-string">"An/Aus",
            "titles": {                "en": 
"hljs-string">"On/Off",
                "de": 
"hljs-string">"An/Aus",
                "ja": 
"hljs-string">"オンオフ",
                
"hljs-string">"zh-Hans": "开关",
                
"hljs-string">"zh-Hant": "開關" },
            "type": 
"hljs-string">"boolean",
            "forms": [...]
        },
        "status": {            "title" : 
"hljs-string">"Zustand",
            "titles": {                "en": 
"hljs-string">"Status",
                "de": 
"hljs-string">"Zustand",
                "ja": 
"hljs-string">"状態",
                
"hljs-string">"zh-Hans": "状态",
                
"hljs-string">"zh-Hant": "狀態" },
            "type": 
"hljs-string">"object",
            ...
}

6.2 Context Extension

In addition to the standard vocabulary definitions as defined in Section 5. Information Model , the Thing Description offers the possibility to add context knowledge from different namespaces. This mechanism can be used to enrich the content of the Thing Description instances with additional (e.g., domain specific) semantics. In addition, it can also be used to specify some configurations and behaviors of the underlying communication protocols announced in the forms field.

For this extension the Thing Description uses the @context mechanism known from JSON-LD. The usage and serializiation of the @context within the Thing Description is specified in Section 6.1.1 Thing as a whole .

When adding additional vocabulary to a Thing Description instance, it is recommended that these vocabulary be linked to a namespace context that is within the JSON name @context container is specified.

If included namespaces are based on class definitions such as those provided by the RDF Schema or OWL, the Things Description also allows the use of @type known from JSON-LD to associate the affiliation to a class.

{    "@context": [        "http://www.w3.org/ns/td",
        {"om": "http://www.wurvoc.org/vocabularies/om-1.8/"},
        {"saref": "https://w3id.org/saref#"}
    ],
    "@type": 
"hljs-string">"Thing",
    ...
    "properties": {        "Temperature": {            "@type": 
"hljs-string">"saref:Temperature",
            
"hljs-string">"description": "Temperature value of the weather station",
            
"hljs-string">"om:unit_of_measure": "om:degree_Celsius",
            
"hljs-string">"readOnly": true,
            
"hljs-string">"observable": true,
            
"hljs-string">"writeOnly": false,
            "type": 
"hljs-string">"number",
            "forms" : [...]
        },
        ...
    }
}

With the context extension in the Thing Description, communication metadata can be supplemented or specified in the declarations forms . This is useful when default assumptions as defined in [[ WOT-PROTOCOL-BINDING ]] need to be overwritten.

The following example shows a property "brightness" that offers a read, write, and observe operation within the forms deceleration.

For the read operation, the deceleration follows the default assumption to execute an HTTP GET as defined in [[ WOT-PROTOCOL-BINDING ]]. The write operation overwrites the default assumption (= HTTP PUT) and declares with the context extension the HTTP POST method to be used for this operation. In order to observe this property, the context extension is used here to announce that an HTTP GET is always running to follow the long poll mechanism.

6.3 Media Type

The JSON-based serialization of the TD is identified by the media type [ MEDIATYPES ] application/td+json .

Editor's note : CoAP Content Format

CoAP-based WoT implementations can use the experimental Content-Format 65100 until a proper identifier has been registered.

The media type application/td+json MUST be also associated with the JSON-LD context http://www.w3.org/ns/td . That means that this media type can also be used for contextual identification of the vocabulary within a (simplified) TD instance that may omit the @context key name term.

Editor's note : IANA Considerations

Neither the application/td+json media content type nor a CoAP Content-Format identifier have been registered with IANA yet.

6.3 6.4 Implementation Notes

6.3.1 6.4.1 JSON Thing Description Processing

The minimum requirement to read the content of a Thing Description instance is a (simple) JSON parser.

For reasons of simplification and/or compactness, exchanged Thing Descriptions instances may omit mandatory vocabulary terms that have default value assumptions (aka Simple Thing Description representation). In this case, the Thing Description Processor must follow the default assumptions for these vocabulary terms: If the key name terms writable readOnly , writeOnly , and/or observable are not present within a properties interaction definition, the default value defined in 5. 5.2.3 Information Model Property MUST be assumed.

If the name terms mediaType idempotent key and/or safe are not present within an actions interaction definition, the default value defined in 5.2.4 Action MUST be assumed.

If the contentType name term is not present within a forms definition, the default value as defined in 5. 5.2.6 Information Model Form MUST be assumed.

To validate the semantic meaning and follow references to external context vocabulary terms (e.g., iot.schema.org), use of JSON-LD or RDF-based tools and libraries is highly recommended as explained in the next sub-section.

6.3.2 6.4.2 JSON-LD 1.1 1.0 Processing

To interpret the semantic meaning of a Thing Description in terms of RDF triples, a Thing Description instance first requires a valid JSON-LD 1.1 representation based on this Thing Description specification. Then this representation can be passed to a JSON-LD 1.1 processor. The following pre-processing steps of a Thing Description instance must be executed before starting JSON-LD 1.1 processing: Before starting JSON-LD 1.1 processing of a Thing Description instance, there MUST be a @context key from JSON-LD 1.1 as defined in Section 6.1.1 Thing as a whole . Before starting JSON-LD 1.1 processing of simple transformed into a Thing Description instance, all external vocabulary terms used in the Thing Description MUST provide their context URIs as prefix or within the @context field. Before starting RDF-based serializiation format by JSON-LD 1.1 processing of a Thing Description instance, all mandatory vocabulary terms as defined in Section 5. Information Model that are missing from the instance MUST be inserted explicitly with their default value. Section 1. Introduction shows an example of how the input and output of such preprocessing would appear. 1.0.

7. Example Thing Description Instances

7.1 MyLampThing Example with CoAP Binding

Feature list of the Thing:

Example 18 31 : MyLampThing represented as a compact JSON serialization
{
    "id": "urn:dev:wot:com:example:servient:lamp",
    "name": "MyLampThing",
    "description" : "hljs-string">"MyLampThing uses JSON-LD 1.1 serialization",
    : [{<span class=

"hljs-string">"MyLampThing uses JSON serialization",
    
"hljs-attr">"securityDefinitions": {"psk_sc":{
"hljs-attr">"scheme": "hljs-string">"psk"}],

"hljs-string">"psk"}},
    "security": [
"hljs-string">"psk_sc"],

    "properties": {
        "status": {
            "description" : "Shows the current status of the lamp",
            "type": "string",
            "forms": [{
                "href": "coaps://mylamp.example.com/status"
            }]
        }
    },
    "actions": {
        "toggle": {
            "description" : "Turn on or off the lamp",
            "forms": [{
                "href": "coaps://mylamp.example.com/toggle"
            }]
        }
    },
    "events": {
        "overheating": {
            "description" : "Lamp reaches a critical temperature (overheating)",
            : <span class=
"hljs-string">"string",

            "data": {"hljs-attr">"type": "string"},

            "forms": [{
                "href": "coaps://mylamp.example.com/oh"
            }]
        }
    }
}

7.2 MyLightSensor Example with MQTT Binding

Feature list of the Thing:

Example 19 32 : MyLampThing : MyLightSensor with semantic annotations based on a valid JSON-LD 1.1 representation MQTT binding
{
    : [<span class=
"hljs-string">"http://www.w3.org/ns/td", 
                {: <span class=
"hljs-string">"http://iotschema.org/"}],
     : <span class=
"hljs-string">"Thing",
    : <span class=
"hljs-string">"urn:dev:wot:com:example:servient:lamp",

    "name": "hljs-string">"MyLampThing",
     : <span class=
"hljs-string">"MyLampThing uses JSON-LD 1.1 serialization",
    : [{<span class=

"hljs-string">"MyLightSensor",
    "id": 
"hljs-string">"urn:dev:wot:com:example:servient:lightsensor",
    
"hljs-attr">"securityDefinitions": {"nosec_sc": {
"hljs-attr">"scheme": "hljs-string">"psk"}],
    : {
        : {
             : <span class=
"hljs-string">"iot:SwitchStatus",
            <span class=
"hljs-attr">"description" : <span class=
"hljs-string">"Shows the current status of the lamp",
            : <span class=
"hljs-literal">false,
            <span class=
"hljs-attr">"observable": <span class=
"hljs-literal">false,
            : <span class=
"hljs-string">"string",
            : [{
                : <span class=
"hljs-string">"coaps://mylamp.example.com/status",
                <span class=
"hljs-attr">"mediaType": <span class=
"hljs-string">"application/json"
            }]
        }
    },
    : {
        : {
             : <span class=
"hljs-string">"iot:SwitchStatus",
            <span class=
"hljs-attr">"description" : <span class=
"hljs-string">"Turn on or off the lamp",
            : [{
                : <span class=
"hljs-string">"coaps://mylamp.example.com/toggle",
                <span class=
"hljs-attr">"mediaType": <span class=
"hljs-string">"application/json"
            }]
        }
    },

"hljs-string">"nosec"}},
    "security": [
"hljs-string">"nosec_sc"],

    "events": {
        : {
             : <span class=
"hljs-string">"iot:TemperatureAlarm",
            <span class=
"hljs-attr">"description" : <span class=
"hljs-string">"Lamp reaches a critical temperature (overheating)",
            : <span class=
"hljs-string">"string",
            : [{

        "lightSensor": {
        "type": "hljs-string">"integer",
        "forms": [
            {

                "href": "hljs-string">"coaps://mylamp.example.com/oh",

"hljs-string">"mqtt://192.168.1.187:1883/lightSensor",

                "hljs-attr">"mediaType": <span class=
"hljs-string">"application/json"
            }]
        }

"hljs-attr">"contentType" : "application/text"
            }
        ]

    }
} 

}

8. Security and Privacy Considerations

In general the security measures taken to protect a WoT system will depend on the threats and attackers that system may face and the value of the assets needs to protect. A detailed discussion of security and privacy considerations for the Web of Things, including a threat model that can be adapted to various circumstances, is presented in the informative document [ Editor's note WOT-SECURITY-CONSIDERATIONS Please see ]. This section discusses only security and privacy risks and possible mitigations directly relevant to the WoT Security Thing Description.

A WoT Thing Description can describe both secure and Privacy repository for work insecure network interfaces. When a Thing Description is retro-fitted to an existing network interface, no change in progress regarding threat models, assets, risks, recommended mitigations, the security status of the network interface is to be expected.

When designing new devices and services for use with the WoT, we have documented a suggested set of best practices for in [ WOT-SECURITY-BEST-PRACTICES ] to improve security. This best-practices document may be updated as security measures evolve. Following these practices does not guarantee security, but it at least will help to avoid common known vulnerabilities.

The use of a WoT Thing Description introduces the security and privacy for systems using risks given in the Web following sections. After each risk, we suggest some possible mitigations.

8.1 Context Dereferencing Privacy Risk

Deferencing the vocabulary files given in the @context member of Things. Once complete, security any JSON-LD document can be a privacy risk. In the case of the WoT, an attacker can observe the network traffic produced by such deferences and can use the metadata of the dereference, such as the destination IP address, to infer information about the device especially if domain-specific vocabularies are used. This is a risk even if the connection is encrypted, and is related to DNS privacy considerations relevant leaks.

Mitigation:
Avoid actual dereferencing of vocabulary files. Vocabulary files should be cached whenever possible. Ideally they would be made immutable, built into the interpreting device, and not derefenced at all, with the URI in the @context member serving only as an identifier of the (known) vocabulary. This requires the use of strict version control, as updates should use a new URI to ensure that existing URIs can refer to immutable data. Use well-known standard vocabulary files whenever possible to improve the chances that the context file will be available locally to systems interpreting the metadata in a Thing Descriptions Description.

8.2 Immutable Identifiers Privacy Risk

The fact that a Thing Description contains a unique identifier means that should it be associated with a person it can be used to track that person and therefore pose a risk to privacy.

Mitigation:
All identifiers should be mutable, and there should be a mechanism to update the id of a Thing. Specifically, the id of a Thing should not be fixed in hardware. This does, however, conflict with the Linked Data ideal that identifiers are fixed URIs. In many circumstances it will be summarized acceptable to only allow updates to identifiers if a Thing is reinitialized. In this case as a software entity the old Thing ceases to exist and a new Thing is created. This can be sufficient to break a tracking chain when, for example, a device is sold to a new owner. Alternatively, if more frequent changes are desired during the operational phase of a device, a mechanism can be put into place to notify only authorized users of the change in identifier when a change is made. Note however that some classes of devices, e.g. medical devices, may require immutable IDs by law in some jurisdictions. In this section. case extra attention should be paid to secure access to files, such as Thing Descriptions, containing such immutable identifiers.

8.3 Fingerprinting Privacy Risk

As noted above, the id member in a TD can pose a privacy risk. However, even if the id is updated as described to mitigate its tracking risk, it may still be possible to associate a TD with a particular physical device, and from there to a person, through fingerprinting.

Mitigation:
Only authorized users should be provided access to the Thing Description for a Thing. If the TD is only distributed to authorized users through secure and confidential channels, for example through a directory service that requires authentication, the risk can be minimized.

8.4 TD Interception and Tampering Security Risk

Intercepting and tampering with TDs can be used to launch man-in-the-middle attacks, for example by rewriting URLs in TDs to redirect accesses to a malicious intermediary that can capture or manipulate data.

Mitigation:
Obtain Thing Descriptions only through mutually authenticated channels. This ensures that the client and the server are both sure of the identity of the other party to the communication. This is also necessary in order to deliver TDs only to authorized users.

8.5 Context Interception and Tampering Security Risk

Intercepting and tampering with context files can be used to facilitate attacks by modifying the interpretation of vocabulary.

Mitigation:
Ideally context files would only be obtained through authenticated channels but it is notable (and unfortunate) that many contexts are indicated using HTTP URLs, which are vulnerable to interception and modification if dereferenced. However, if context files are immutable and cached, and dereferencing is avoided whenever possible, then this risk can be reduced.

8.6 Inferencing of Personally Identifiable Information Privacy Risk

In many locales, in order to protect the privacy of users, there are legal requirements for the handling of personally identifiable information, that is, information that can be associated with a particular person. Such information can of course be generated by IoT devices directly. However, the existence and metadata of IoT devices (the kind of data stored in a Thing Description) can also contain or be used to infer personally identifiable information. This information can be as simple as the fact that a certain person owns a certain type of device, which can lead to additional inferences about that person.

Mitigation:
Treat a Thing Description associated with a personal device as if it contained personally identifiable information. As an example application of this principle, consider how to obtain user consent. Consent for usage of personally identifiable data generated by a Thing is often obtained when a Thing is paired with system consuming the data, which is frequently also when the Thing Description is registered with a local directory or the system consuming the Thing Description in order to access the device. In this case consent for using data from a Thing can be combined with consent for accessing the Thing's Thing Description. As a second example, if we consider a TD to contain personally identifiable information, then it should not be retained indefinitely or used for purposes other than those for which consent was given.

A. JSON Schema for TD Instance Validation

Below is a JSON Schema [ JSON-SCHEMA-VALIDATION ] for syntactically validating Thing Description instances serialized in JSON-LD 1.1.
Editor's note

This schema is known to be too permissive. This issue will be resolved in the next release of this document.

{
  "title": "WoT TD Schema for Bundang Plug Fest",
  "description": "JSON Schema representation of the TD serialization format.",
  "$schema ": "http://json-schema.org/draft-06/schema#",
  "type": "object",
  "properties": {
    "base": {
      "$ref": "#/definitions/url"
    },
    "@type": {
      "$ref": "#/definitions/type_declaration"
    },
    "@context": {
      "$ref": "#/definitions/context"
    },
    "name": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },

    "title": "WoT TD Schema - December 2018",
    "description": "JSON Schema representation of the TD serialisation format.",
    "$schema ": "http://json-schema.org/draft-06/schema#",
    "type": "object",

    "properties": {
      "type": "object",
      "items": {
        "$ref": "#/definitions/properties"
      }
    },
    "actions": {
      "type": "object",
      "items": {
        "$ref": "#/definitions/actions"
      }
    },
    "events": {
      "type": "object",
      "items": {
        "$ref": "#/definitions/events"
      }
    },
    "links": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/links"
      }
    },
    "support": {
      "type": "string"
    },
    "security": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/securityScheme"
      }
    }
  },
  "required": [
    "name",
    "id"
  ],
  "additionalProperties": true,
  "definitions": {
    "context": {
      "oneOf": [
        {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "$ref": "#/definitions/url"
              },
              {
                "type": "object"
              }
            ]
          },
          "contains": {
            "type": "string",
            "enum": [
              "https://w3c.github.io/wot-thing-description/context/td-context.jsonld",
              "http://www.w3.org/ns/td"
            ]
          }

        "base": {
            "$ref": "#/definitions/url"

        },
        {
          "type": "string",
          "enum": [
            "https://w3c.github.io/wot-thing-description/context/td-context.jsonld",
            "http://www.w3.org/ns/td"
          ]
        }
      ]
    },
    "type_declaration": {
      "oneOf": [
        {
          "type": "string"

        "@type": {
            "$ref": "#/definitions/type_declaration"

        },
        {
          "type": "array"
        }
      ]
    },
    "form_declaration": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/form_element"
      }
    },
    "form_element": {
      "type": "object",
      "properties": {
        "href": {
          "$ref": "#/definitions/url"

        "@context": {
            "$ref": "#/definitions/context"

        },
        "rel": {
          "type": "string"

        "name": {
            "type": "string"

        },
        "mediaType": {
          "type": "string"

        "id": {
            "type": "string"

        },
        "subProtocol": {
          "type": "string"

        "description": {
            "type": "string"

        },
        "security": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/securityScheme"
          }

        "descriptions": {
            "$ref": "#/definitions/descriptions"

        },
        "scopes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "href"
      ],
      "additionalProperties": true
    },
    "properties": {
      "additionalProperties": {
        "type": "object",
        "items": {
          "$ref": "#/definitions/property_element"
        }
      }
    },
    "actions": {
      "additionalProperties": {
        "type": "object",
        "items": {
          "$ref": "#/definitions/action_element"
        }
      }
    },
    "events": {
      "additionalProperties": {
        "type": "object",
        "items": {
          "$ref": "#/definitions/event_element"
        }
      }
    },
    "property_element": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"

        "properties": {
            "type":"object",
            "additionalProperties": {
                "$ref": "#/definitions/property_element"
            }

        },
        "@type": {
          "$ref": "#/definitions/type_declaration"

        "actions": {
            "type": "object",
            "additionalProperties": {
                "$ref": "#/definitions/action_element"
            }

        },
        "label": {
          "type": "string"

        "events": {
            "type": "object",
            "additionalProperties": {
                "$ref": "#/definitions/event_element"
            }

        },
        "writable": {
          "type": "boolean"

        "links": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/link_element"
            }

        },
        "observable": {
          "type": "boolean"

        "support": {
            "$ref": "#/definitions/url"

        },
        "forms": {
          "$ref": "#/definitions/form_declaration"

        "securityDefinitions": {
            "type": "object",
            "additionalProperties": {
                "$ref": "#/definitions/securityScheme"
            }

        },
        "security": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/securityScheme"
          }

            "type": "array",
            "items": {
                "type": "string"
            }

        },
        "scopes": {
          "type": "array",
          "items": {

        "created": {

            "type": "string"
          }

        },
        "lastModified": {
            "type": "string"
        },
        "version": {
            "type": "object",
            "properties": {
                "instance": {
                    "type": "string"
                }
            },
            "required": [
                "instance"
            ]

        }
      },
      "required": [],
      "additionalProperties": true

    },
    "action_element": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "@type": {
          "$ref": "#/definitions/type_declaration"

    "required": [
        "name",
        "id",
        "security"
    ],
    "additionalProperties": true,
    "definitions": {
        "context": {
            "oneOf": [{
                    "type": "array",
                    "items": {
                        "anyOf": [{
                                "$ref": "#/definitions/url"
                            },
                            {
                                "type": "object"
                            }
                        ]
                    },
                    "contains": {
                        "type": "string",
                        "enum": [
                            "http://www.w3.org/ns/td"
                        ]
                    }
                },
                {
                    "type": "string",
                    "enum": [
                        "http://www.w3.org/ns/td"
                    ]
                }
            ]

        },
        "label": {
          "type": "string"

        "type_declaration": {
            "oneOf": [{
                    "type": "string"
                },
                {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            ]

        },
        "forms": {
          "$ref": "#/definitions/form_declaration"

        "form_element": {
            "type": "object",
            "properties": {
                "href": {
                    "$ref": "#/definitions/url"
                },
                "op": {
                    "oneOf": [{
                            "type": "string",
                            "enum": [
                                "readproperty",
                                "writeproperty",
                                "observeproperty",
                                "invokeaction",
                                "subscribeevent",
                                "unsubscribeevent"
                            ]
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "enum": [
                                    "readproperty",
                                    "writeproperty",
                                    "observeproperty",
                                    "invokeaction",
                                    "subscribeevent",
                                    "unsubscribeevent"
                                ]
                            }
                        }
                    ]
                },
                "contentType": {
                    "type": "string"
                },
                "security": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "scopes": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "subProtocol": {
                    "type": "string",
                    "enum": [
                        "longpoll"
                    ]
                },
                "response": {
                    "type": "object",
                    "properties": {
                        "contentType": {
                            "type": "string"
                        }
                    }
                }
            },
            "required": [
                "href",
                "contentType"
            ],
            "additionalProperties": true

        },
        "input": {
          "$ref": "#/definitions/data"

        "property_element": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "descriptions": {
                    "$ref": "#/definitions/descriptions"
                },
                "title": {
                    "type": "string"
                },
                "titles": {
                    "$ref": "#/definitions/titles"
                },
                "uriVariables": {
                    "$ref": "#/definitions/dataSchema"
                },
                "@type": {
                    "$ref": "#/definitions/type_declaration"
                },
                "observable": {
                    "type": "boolean"
                },
                "forms": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/form_element"
                    }
                },
                "scopes": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "security": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "enum": {
                    "type": "array",
                    "minItems": 1,
                    "uniqueItems": true
                },
                "const": {},
                "type": {
                    "type": "string",
                    "enum": [
                        "boolean",
                        "integer",
                        "number",
                        "string",
                        "object",
                        "array",
                        "null"
                    ]
                },
                "writeOnly": {
                    "type": "boolean"
                },
                "readOnly": {
                    "type": "boolean"
                },
                "oneOf": {
                    "$ref": "#/definitions/dataSchema"
                },
                "unit": {
                    "$ref": "#/definitions/dataSchema"
                }
            },
            "required": [
                "forms"
            ],
            "additionalProperties": true

        },
        "output": {
          "$ref": "#/definitions/data"

        "action_element": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "descriptions": {
                    "$ref": "#/definitions/descriptions"
                },
                "title": {
                    "type": "string"
                },
                "titles": {
                    "$ref": "#/definitions/titles"
                },
                "uriVariables": {
                    "$ref": "#/definitions/dataSchema"
                },
                "@type": {
                    "$ref": "#/definitions/type_declaration"
                },
                "forms": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/form_element"
                    }
                },
                "input": {
                    "$ref": "#/definitions/dataSchema"
                },
                "output": {
                    "$ref": "#/definitions/dataSchema"
                },
                "safe": {
                    "type": "boolean"
                },
                "idempotent": {
                    "type": "boolean"
                },
                "scopes": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "security": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            },
            "required": [
                "forms"
            ],
            "additionalProperties": true

        },
        "security": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/securityScheme"
          }

        "event_element": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "descriptions": {
                    "$ref": "#/definitions/descriptions"
                },
                "titles": {
                    "$ref": "#/definitions/titles"
                },
                "uriVariables": {
                    "$ref": "#/definitions/dataSchema"
                },
                "title": {
                    "type": "string"
                },
                "@type": {
                    "$ref": "#/definitions/type_declaration"
                },
                "forms": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/form_element"
                    }
                },
                "scopes": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "security": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "subscription": {
                    "$ref": "#/definitions/dataSchema"
                },
                "data": {
                    "$ref": "#/definitions/dataSchema"
                },
                "cancellation": {
                    "$ref": "#/definitions/dataSchema"
                },
                "type": {
                    "not": {}
                },
                "enum": {
                    "not": {}
                },
                "const": {
                    "not": {}
                }
            },
            "required": [
                "forms"
            ],
            "additionalProperties": true

        },
        "scopes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [],
      "additionalProperties": true
    },
    "event_element": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"

        "dataSchema": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "title": {
                    "type": "string"
                },
                "enum": {
                    "type": "array",
                    "minItems": 1,
                    "uniqueItems": true
                },
                "const": {},
                "type": {
                    "type": "string",
                    "enum": [
                        "boolean",
                        "integer",
                        "number",
                        "string",
                        "object",
                        "array",
                        "null"
                    ]
                },
                "descriptions": {
                    "$ref": "#/definitions/descriptions"
                },
                "titles": {
                    "$ref": "#/definitions/titles"
                },
                "writeOnly": {
                    "type": "boolean"
                },
                "readOnly": {
                    "type": "boolean"
                },
                "oneOf": {
                    "$ref": "#/definitions/dataSchema"
                },
                "unit": {
                    "$ref": "#/definitions/dataSchema"
                }
            }

        },
        "@type": {
          "$ref": "#/definitions/type_declaration"

        "link_element": {
            "type": "object",
            "properties": {
                "anchor": {
                    "$ref": "#/definitions/url"
                },
                "href": {
                    "$ref": "#/definitions/url"
                },
                "rel": {
                    "type": "string"
                },
                "type": {
                    "type": "string"
                }
            },
            "required": [
                "href"
            ],
            "additionalProperties": true

        },
        "label": {
          "type": "string"

        "securityScheme": {
            "oneOf": [{
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "nosec"
                            ]
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "basic"
                            ]
                        },
                        "in": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "cert"
                            ]
                        },
                        "identity": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "digest"
                            ]
                        },
                        "qop": {
                            "type": "string"
                        },
                        "in": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "bearer"
                            ]
                        },
                        "authorization": {
                            "$ref": "#/definitions/url"
                        },
                        "alg": {
                            "type": "string"
                        },
                        "format": {
                            "type": "string"
                        },
                        "in": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "psk"
                            ]
                        },
                        "identity": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "public"
                            ]
                        },
                        "identity": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "oath2"
                            ]
                        },
                        "authorization": {
                            "$ref": "#/definitions/url"
                        },
                        "token": {
                            "$ref": "#/definitions/url"
                        },
                        "refresh": {
                            "$ref": "#/definitions/url"
                        },
                        "scopes": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        },
                        "flow": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "apikey"
                            ]
                        },
                        "in": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                },
                {
                    "type": "object",
                    "properties": {
                        "description": {
                            "type": "string"
                        },
                        "proxy": {
                            "$ref": "#/definitions/url"
                        },
                        "scheme": {
                            "type": "string",
                            "enum": [
                                "pop"
                            ]
                        },
                        "authorization": {
                            "$ref": "#/definitions/url"
                        },
                        "format": {
                            "type": "string"
                        },
                        "alg": {
                            "type": "string"
                        },
                        "in": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "scheme"
                    ]
                }
            ]

        },
        "forms": {
          "$ref": "#/definitions/form_declaration"

        "url": {
            "type": "string",
            "format": "uri",
            "pattern": "(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(([^#]*))?(#(.*))?"

        },
        "security": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/securityScheme"
          }

        "descriptions": {
            "type": "object"

        },
        "scopes": {
          "type": "array",
          "items": {
            "type": "string"
          }

        "titles": {
            "type": "object"

        }
      },
      "required": [],
      "additionalProperties": true
    },
    "links": {
      "type": "object",
      "properties": {
        "anchor": {
          "$ref": "#/definitions/url"
        },
        "href": {
          "$ref": "#/definitions/url"
        },
        "rel": {
          "type": "string"
        },
        "mediatype": {
          "type": "string"

    }
}

B. Thing Templates

A Thing Template is a description for a class of devices or things. It describes the properties, actions, events and common metadata that are shared for an entire group of things, to enable the common handling of thousands of devices by a cloud server, which is not practical on a per-thing basis. The Thing Template uses the same core vocabulary and information model from section 5.

The Thing Template enables:

The Thing Template is a logical description of the interface and possible interaction with devices (properties, actions and events), however it does not contain device-specific information, such as a serial number, GPS location, security information or concrete protocol endpoints.

Since a Thing Template does not contain a protocol binding to specific endpoints and does not define a specific security mechanism, the forms and securityDefinitions and security keys must not be present.

The same Thing Template can be implemented by things from multiple vendors, a thing can implement multiple thing templates, define additional metadata (vendor, location, security) and define bindings to concrete protocols. To avoid conflicts between properties, actions and events from different thing templates that are combined into a common thing, all thse identifiers must be unique within a thing.

A common Thing Template for a class of devices enables writing applications across vendors and creates a more attractive market for application developers. A concrete Thing Description can implement multiple Thing Templates and thus can aggregate function blocks into a combined device.

The business models of cloud vendors are typically built on managing thousands of identical devices. All devices with the same Thing Template can be managed in the same way by cloud applications. It is easy to create multiple simulated devices, if the interface and the instance are treated separately.

Since a Thing Template is a Thing Description, where some optional parts are not present, it can be serialized in the same way and into the same formats as a thing description.

B.1 Thing Template Examples

This section defines a Thing Template for a lamp and a Thing Template for a a buzzer. The combined thing BuzzerLamp includes both thing templates.

B.1.1 Thing Template: Lamp

Example 33 : MyLampThingTemplate serialized in JSON
{    "@context": [
"hljs-string">"http://www.w3.org/ns/td"], 
    "@type" : 
"hljs-string">"ThingTemplate",
    "id": 
"hljs-string">"urn:dev:wot:com:example:servient:lamp:model",
    "name": 
"hljs-string">"Lamp Thing Template",
    "description" : 
"hljs-string">"Lamp Thing Template",
    "properties": {        "status": {            
"hljs-attr">"description" : "current status of the lamp (on|off)",
            "type": 
"hljs-string">"string",
            "readOnly": 
"hljs-literal">true

        }
      },
      "required": [
        "href"
      ],
      "additionalProperties": true

    },
    "securityScheme": {
      "type": "object"
    },
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(([^#]*))?(#(.*))?"
    },
    "jsonld_url": {
      "type": "string",
      "format": "uri",
      "pattern": "http://[^/?#]*|https://[^/?#]*"

    "actions": {
        "toggle": {
            "hljs-attr">"description" : "Turn the lamp on or off"
        }

    },
    "data": {
      "title": "Data type",
      "anyOf": [
        {
          "description": "URI of an XSD built-in type",
          "type": "string"

    "events": {
        "overheating": {
            "hljs-attr">"description" : "Lamp reaches a critical temperature (overheating)",
            "data": {
"hljs-attr">"type": "string"}
        }
    }
}

B.1.2 Thing Template: Buzzer

Example 34 : MyLampThingTemplate serialized in JSON
{    "@context": [
"hljs-string">"http://www.w3.org/ns/td"], 
    "@type" : 
"hljs-string">"ThingTemplate",
    "id": 
"hljs-string">"urn:dev:wot:com:example:servient:buzzer:template",
    "name": 
"hljs-string">"Buzzer Thing Template",
    "description" : 
"hljs-string">"Thing template of a buzzer that makes noise for 10 seconds",
     "actions": {        "buzz": {            
"hljs-attr">"description" : "buzz for 10 seconds"
        }
     }
}

B.1.3 Combined Thing: Lamp + Buzzer

The following example illustrates how a combined thing can be defined using two different thing templates.

Example 35 : Combined Thing: Lamp + Buzzer (JSON-LD1.1 serialisation)
{   "@context": [
"hljs-string">"http://www.w3.org/ns/td"], 
   "@type" : [        "Thing",        
"hljs-string">"urn:dev:wot:com:example:servient:lamp:template",
        
"hljs-string">"urn:dev:wot:com:example:servient:buzzer:template"
    ],
    "id": 
"hljs-string">"urn:dev:wot:com:example:servient:combinedBuzzerLamp1",
    "name": 
"hljs-string">"My Buzzing Lamp Thing",
    "description" : 
"hljs-string">"A lamp that can issue an alert",
    "security": [{
"hljs-string">"scheme": "basic"}],
    {
        "id": 
"hljs-string">"urn:dev:wot:com:example:servient:lamp:template",
        "name": 
"hljs-string">"Lamp Thing Template",
        
"hljs-string">"description" : "Thing Template for a lamp",
        "properties": {            "status": {                
"hljs-string">"description" : "current status of the lamp (on|off)",
                
"hljs-string">"type": "string",
                
"hljs-string">"readOnly": true,
                "forms": [{                
"hljs-string">"href": "coaps://buzzlamp.example.com/status",
                
"hljs-string">"contentType": "application/json"
                }]
            }

        },
        {
          "description": "URI and media type for a complex type (XSD, SenML...)",
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "href": {
              "type": "string"
            },
            "mediatype": {
              "type": "string"

        "actions": {
            "toggle": {
                "hljs-string">"description" : "Turn on or off the lamp",
                "forms": [{                    
"hljs-string">"href": "coaps://buzzlamp.example.com/toggle",
                    
"hljs-string">"contentType": "application/json"
                }]

            }
          },
          "required": [
            "name",
            "href",
            "mediatype"
          ]

        },
        {
          "$ref": "http://json-schema.org/draft-06/schema#"

        "events": {
            "overheating": {
                "hljs-string">"@type" : "iot:TemperatureAlarm",
                
"hljs-string">"description" : "Lamp reaches a critical temperature (overheating)",
                
"hljs-string">"data": {"type": "string"},
                "forms": [{                    
"hljs-string">"href": "coaps://buzzlamp.example.com/oh",
                    
"hljs-string">"contentType": "application/json"
                }]
            }

        }
      ]

    },
    "dataSchema": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "enum": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "boolean"
              },
              {
                "type": "object"
              },
              {
                "type": "number"
              },
              {
                "type": "array"
              }
            ]
          }
        },
        "type": {
          "type": "string",
          "enum": [
            "string",
            "boolean",
            "object",
            "number",
            "array"
          ]
        }
      }

    {
        "id": 
"hljs-string">"urn:dev:wot:com:example:servient:buzzer:template",
        "name": 
"hljs-string">"Buzzer Thing Template",
        
"hljs-string">"description" : "Thing Template of a buzzer that makes noise for 10 seconds",
         "actions": {            "buzz": {                
"hljs-string">"description" : "buzz for 10 seconds",
                "forms": [{                    
"hljs-string">"href": "coaps://buzzlamp.example.com/buzz",
                    
"hljs-string">"contentType": "application/json"
                }]
            }
         }

    }
  }

}

B. C. Recent Specification Changes

C.1 Changes from Second Third Public Working Draft

C.2 Changes from First Second Public Working Draft

Changes from First Second Public Working Draft are described in the Second Third Public Working Draft

C. D. Acknowledgments Acknowledgements

The editors would like to thank Dave Raggett, Matthias Kovatsch, Michael McCool, Michael Koster, Victor Charpenay, Kawaguchi Toru, Michael Lagally, Kazuyuki Ashimura, María Poveda, Daniel Peintner, Ben Francis for their contributions, comments, and guidance.

D. E. References

D.1 E.1 Normative references

[BCP47]
Tags for Identifying Languages . A. Phillips; M. Davis. IETF. 2009. Request for Comments. URL: https://tools.ietf.org/html/bcp47
[MEDIATYPES]
Media Types . IANA. URL: https://www.iana.org/assignments/media-types/media-types.xhtml
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels . S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax . T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[RFC6570]
URI Template . J. Gregorio; R. Fielding; M. Hadley; M. Nottingham; D. Orchard. IETF. March 2012. Proposed Standard. URL: https://tools.ietf.org/html/rfc6570
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format . T. Bray, Ed.. IETF. December 2017. Internet Standard. URL: https://tools.ietf.org/html/rfc8259
[WOT-ARCHITECTURE]
Web of Things Architecture . Kazuo Kajimoto; Matthias Kovatsch; Uday Davuluru. W3C. 20 August 2017. URL: https://w3c.github.io/wot-architecture/
[WOT-PROTOCOL-BINDING]
Web of Things Protocol Binding Templates . Michael Koster. W3C. 12 January 2018. URL: https://w3c.github.io/wot-binding-templates/
[WOT-SECURITY-BEST-PRACTICES]
Web of Things Security and Privacy Best Practices (WIP) . ; Michael McCool; Elena Reshetova. W3C. WIP. URL: https://github.com/w3c/wot-security/blob/master/wot-security-best-practices.md
[WOT-SECURITY-CONSIDERATIONS]
Web of Things Security and Privacy Considerations . ; Michael McCool; Elena Reshetova. W3C. 28 August 2017. URL: https://w3c.github.io/wot-security/

D.2 E.2 Informative references

[JSON-SCHEMA-VALIDATION]
JSON Schema Validation: A Vocabulary for Structural Validation of JSON . Austin Wright; Henry Andrews; Geraint Luff. IETF. Internet-Draft. URL: https://tools.ietf.org/html/draft-handrews-json-schema-validation-00
[OPENAPI]
OpenAPI Specification: Version 3.0.1 . Darrel Miller; Jason Harmon; Jeremy Whitlock; Kris Hahn; Marsh Gardiner; Mike Ralphson; Rob Dolin; Ron Ratovsky; Tony Tam. OpenAPI Initiative, Linux Foundation. 7 December 2017. URL: https://swagger.io/specification/
[SemVer]
Semantic Versioning 2.0.0 . Tom Preston-Werner.26 December 2017. URL: https://semver.org/