w3c / wot-thing-description

Web of Things (WoT) Thing Description
http://w3c.github.io/wot-thing-description/
Other
131 stars 63 forks source link

Reconsider security & securityDefinitions being mandatory #757

Open benfrancis opened 5 years ago

benfrancis commented 5 years ago

Previously discussed in https://github.com/w3c/wot-thing-description/issues/165 and https://github.com/w3c/wot-thing-description/issues/230

The main rationale for making the security member mandatory seems to be using the verbose nature of defining "no security" in every Thing Description as a source of irritation for web thing developers to encourage them to instead provide some kind of security for their device/gateway/service.

Example of defining "no security":

{
  "securityDefinitions": {
    "none": {"scheme": "nosec" }
  },
  "security": ["none"]
}

To be honest this seems a bit of a misguided approach to improving security (!) and there may actually be legitimate reasons for not including the security metadata in the Thing Description.

Use case 1 For example, in Mozilla's WebThings Gateway implementation access to the gateway's REST API (which includes all the Thing Descriptions and the Things Resource which enumerates all the Thing Descriptions) is authenticated using JSON Web Tokens over HTTPS. All the Thing Descriptions use the same security scheme and in order to download a Thing Description you need to already be authenticated (this is intentional, the Thing Descriptions are not public for privacy reasons). Third party apps and services can then request access to the gateway using OAuth and the user decides which devices that app/service has read or write access to, which is then stored in an access control list which the user can change or revoke at any time.

This actually makes including security metadata in the Thing Description entirely redundant because in order to read the metadata a client needs to already have that information.

Use case 2 Web things implemented using Mozilla's WebThings Framework may choose to be unauthenticated and discoverable on a local network, with the WebThings Gateway used to safely proxy them to the Internet, with the gateway handling the authentication scheme separately from the device itself.

Use case 3 Web things in public places (e.g. vending machines, parking meters, interactive exhibits in museums) may intentionally be unauthenticated (though may still use an encrypted connection) because they are designed for public access.

Finally, the security metadata in the Thing Description is really just advisory metadata as far as a client is concerned. There's no guarantee that a device actually implements the security scheme it says it does, or that if it says there is no security that there actually is no security. So making it mandatory seems like a bit of an empty gesture because actual security is independent of the Thing Description.

In order to remove this unnecessary (and currently quite verbose) boilerplate in every Thing Description, I suggest that there should instead be a default of "no security" or "undefined security".

P.S. @mmccool mentioned he has some ideas to make this less verbose, which I'd also be interested to learn more about.

mmccool commented 5 years ago

The issue of this being mandatory or not aside, here is how this can be made less verbose: allow "anonymous" SecurityScheme objects to be included inside security tags. This avoids the need for a separate securityDefinition and simplifies things in the common case where the same security scheme is used globally. Basically we would have to allow either strings (referring to previous definitions) or SecurityScheme objects inside "security" lists.

If this were added, then the minimum "nosec" definition would look like

"security": {"scheme": "nosec"},

at the top level (note we also can use a single element in place of an array of one element.

I'm actually annoyed with myself that I did not get this into the current spec, it was my original intention. I fully intend to include this in 1.1, so when we talk about making "security" non-mandatory, we ultimately should consider whether people need to add the single line above, or not.

mmccool commented 5 years ago

Another option for making "nosec" definitions shorter would be to have a predefined "nosec" definition as a built-in vocabulary term. Then the minimum would look like

"security": "nosec",

This would specifically make "nosec" less verbose but would not make other schemes that need parameters less verbose. We could certainly use both of these approaches (eg anonymous SecurityScheme objects and predefined common security definitions). The anonymous objects would then allow "short" definitions for security schemes that need parameters but are used in all forms, e.g. when declared at the top level. Then you would only have to use securityDefinitions in the relatively rare case where you have a Thing implemented with forms using different security schemes, AND you want to avoid redundantly providing a bunch of parameters. This use case does not arise when you have a single gateway, but does arise in "hybrid" things that use different protocols for different purposes (eg http for request-response and mqtt for events) or have multiple access paths (eg. local and remote via the cloud). For example, you might have basic auth (or nosec) for local access and use OAuth2 for cloud access.

mmccool commented 5 years ago

To clarify a few other points:

mlagally commented 5 years ago

I think the security scheme "security": "nosec", is descriptive enough and I would prefer it, however also "security": {"scheme": "nosec"}, is an improvement.

mmccool commented 5 years ago

My point is that we can make the security definitions less verbose and easier to use in the common case... but can still make them mandatory. We can return to this in the next charter, and I am going to mark this issue that way, but I'd just like to close by saying that the pre-defined string and the anonymous scheme are useful in different ways. The predefined string for "nosec" makes the mandatory declaration as short as possible when there is no security. The anonymous scheme (the second approach) however is also useful and simplifies things when only one scheme is used for the entire TD, which is another common case. So it would be my preference to implement both.

mkovatsc commented 5 years ago

@benfrancis What you describe actually calls for correctly describing your security mechanism in your TDs. At the moment you basically break interoperability and force all Consumers to learn the Mozilla implementation...

benfrancis commented 5 years ago

The anonymous definitions and pre-defined nosec scheme would definitely help to make this less verbose.

@mkovatsc wrote:

@benfrancis What you describe actually calls for correctly describing your security mechanism in your TDs. At the moment you basically break interoperability and force all Consumers to learn the Mozilla implementation...

We have actually now implemented securityDefinitions and security members in the Thing Descriptions exposed by our gateway implementation, and it makes exactly zero difference to interoperability. Because Thing Descriptions themselves are authenticated (as is apparently recommended, and we have no intention of changing for privacy reasons), you can't get the information defined in the security definition unless you already have the information defined in the security definition. It is entirely redundant.

The only way we can think of for securityDefinitions/security to be useful in this use case is if we served an unauthenticated version of the Thing Description which only contains security metadata and nothing else. The client would then get the rest of the metadata once it has authenticated. One concern with this is that title is currently mandatory, which means that you'd still be able to get a public list of the names of all the smart home devices in a user's home.

Firstly, I don't think title should be mandatory either. But another way of improving this situation would actually be to have the gateway itself have its own Thing Description which provides security metadata, and only once you have authenticated with the gateway can you get the list of devices that gateway is hosting. This could also be the beginning of a solution to the Thing Directory problem, where a Thing Description for a gateway with a @type of "Gateway" could provide a list of Thing Descriptions (maybe a "things" member or links with a special link relation) of its things.

draggett commented 5 years ago

I believe we agree that where privacy is a concern, the TD should only be accessible to those who have agreed to respect the owner's privacy. This merits further discussion on the ideas of ownership and agreements between owners and clients in respect to privacy, terms and conditions on the use of data, liability and so forth. This could be called out as something for the WoT IG to consider as it will need considerable thought. I recommend that we involve the W3C Privacy experts to frame the challenge.

In respect to title. In my implementation, a "name" field is used when exposing the thing as a basis for the URL path for the TD. This is used as the default for "title" if title is not explicitly provided by the developer for the exposed thing. My understanding is that title is a human name as you would write in a report, e.g. it could contain spaces, e.g. "My large table lamp" vs "lamp23".

In my case, the web hub automatically generates the security and form fields, along with defaults for id and title. The developer for and exposed thing doesn't need to do anything for these.

mmccool commented 5 years ago

The use of name vs title is a whole other discussion. The reason there is title is due to internationalization requirements, and it allows us to reuse the MultiLanguage class and titles/descriptions fields we had already defined elsewhere. The intent of title is that it is to be used to identify a device in a human-readable way, eg on a web dashboard. Internationalization requires such uses to be localizable, ie customizable (by the user) to one of several languages. Therefore a title is not unique or immutable; but one connotation of the word “name” is that it has these properties... Anyhow, id satisfies the unique/(semi...)immutable properties, and is used for tracking a device internally (eg in a database). Title is used to identify a device to a human user. And finally, base is used to access the device (or rather, to simplify URLs when they have a common base, which is not always the case!)

sebastiankb commented 3 years ago

In introducing this option in TD 1.1 would lead to backward compatible problems with TD 1.0. Therefore this topic should be covered in TD 2.0.

egekorkan commented 8 months ago

To be considered together with #300