-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chose a particular security schema for an ExposedThing #299
Comments
In the In practice, much of that could go to the scripting runtime, but in the ExposedThing case, the script is part of that runtime. Currently we have ExposedThing as a conformance class inside the WoT Scripting API, but we could also make a separate API for it, to emphasize the different permissions and different place in the solution stack. That would mean splitting the API along the conformance classes (consumed, discovery, exposed) to completely independent APIs. Would that clarify these? |
From the architectural description of a servient, it seems that the scripts run in a sandboxed environment. As such, in principle, Splitting API is a valid approach but I'd prefer to add a new API endpoint. Something like
|
ConsumedThing scripts do run in a sandbox. |
From the perspective of a script developer it would be ideal if the script itself can register security schemes (and the according checks) for exposed things just like it can register handlers for reading/writing properties and all the other interactions. Having said that, I doubt this can be properly achieved ... or what's your opinion on that? |
The diagram above was defined by us, to reflect the best known intention. However, there is no uniform implementation of this, so at the moment it is not normative. The Scripting API, being an optional module in WoT, just provides convenience to develop code for discovering, consuming, and on the other hand, exposing Things. By default, exposing Things is close-to-native territory. It has two main parts:
The first one can be included in libraries like node-wot. This can be standardized, even though the TD spec doesn't provide standard ways to generate a TD. The second one is not defined and not standardized yet, and this is where we have most divergence and confusion. It involves the following:
There are more or less standard JS libraries for the first two categories. We can take as much as we want to implement from the above in a standardized library, and define/standardize a SW interface to interact with. But this would involve standardizing a whole platform, which has not been successful to this date, and it has not been the objective of the WoT exercise. So I would say the safest/most generic assumption is that the ExposedThing API belongs to system level. Whatever convenience functionality is carved out through interfaces from this blob will be a subject to standardization later. |
Btw this discussion is related to #298. |
To simplify things a bit, let's consider an analogy: let's separate treating ConsumedThing scripts and ExposedThing scripts like if they were run in containers (which is one possible implementation policy). So, let's assume a developer writes and runs a script that calls wot.consume() in a given environment, let's assume it's a container. From there, remote things can be accessed and operated. The container protects the platform from those things and vice versa, keeps the data contained. Of course, a new exposed thing can be done in any ways, for instance written in assembly and run as an executable in the current environment or in a new container, whatever.
Steps 5 is the tricky one, since the script will contain local system API calls, and they need system level permissions. Which is the reason we need step 4, i.e. run the exposed thing in another container with more permissions. My point is that all of this can (and should) be encapsulated by the implementation. The developer only needs general knowledge about typical security definitions on that platform. I don't like the idea of a reflection API in this case: I am not sure if from security point of view is a wise thing to provide ways to elevate the current container to more powerful permissions, i.e. you should never give permissions to yourself. That should run through the usual ways to externally vet a new container. [edit] Note that the original script can consume the new Thing without any issues, by first fetching/discovering the TD served by the other container (either directly or via a directory). [/edit] Of course, the container analogy was just analogy, but also a possible implementation policy. What am I missing? |
I think that the key point is:
How am I supposed to provide security definitions if I can't know which one would be supported by the platform? What happens if I choose a not supported schema? Since those definitions are just hints I would imagine this scenario: developers just put every possible schema hoping that one of them is supported by the underlying platform. My take on this issue is either we provide a way to choose the security scheme or we don't let developers to chose the security scheme 😃. Sincerely, I think the issue went a little bit out of topic bringing up more profound issues (which are actually really important and interesting) but maybe they should be addressed separately. |
The assumed developer position is to develop an exposed thing for a given platform, where the things mentioned here are available and known by the developer. If the TD init contains a security definition that is not supported, it will be ignored unless it is referenced, in which case it will trigger an error. |
To move it forward, we could start developing a So in this issue the need was
In other words, move to programmatic space the current declarative way to specify security schemes in the init dictionary. Though there are also advantages in the declarative approach - more discussion is needed. Then, we need to provision those schemes, which is one deeper/lower layer of API, like |
Just to be sure are you referring to this when you're talking about things that are known/available?
I would say that it is a reasonable assumption, but are we really sure that it is always the case? I mean the developer should be also the platform deployer/manager to know ahead of time which configuration will be used for its platform. Therefore, possibly as you suggested today the platform and the application should be treated as a single entity -> no runtime. I would love to keep the runtime in our design for the reasons that I explained today. But I also understand your concerns about the fact that we still do have a consistent implementation and it might end up being a task greater than us. |
But we can extend the discussion to system level APIs like accessing GPIO, PWM, Generic Sensors, etc. In order to figure out what makes sense to standardize and what can be left open for dependency resolution (available in Node.js), at the beginning let's just start with coding through a full ExposedThing solution, figure out what external libraries can we use for different functionality, what is common, what makes sense to standardize etc. It is quite clear we do need to standardize some names/vocabulary, which is needed both for the declarative and programmatic way to initialize az ExposedThing, but that is quite close to being standardized. |
Yup at least in the lastest period we are discussing a lot about this, thanks also to the ThingModel. I think we could achieve a standardized approach soon. I'll try to provide a concrete piece of code using this newly proposed method. So let's assume these two hypothesis:
let partialTD = {
properties: {
temperature: {/* definitions */}
}
};
/*
wot.runtime.securityDefintions returns an Array with
the "preaviously" configured securityDefinitions. For example:
[
{
"scheme" : "oauth2"
....
},
{
"scheme" : "basic"
ao Da
},
]
*/
const oAuth2Supported = wot.runtime.securityDefinitions.filter(
scheme -> scheme.name === "oauth2");
const bearerSupported = wot.runtime.securityDefinitions.filter(
scheme -> scheme.name === "bearer");
if(!oAuth2Supported && !bearerSupported){
throw new Error("Sorry no security schema matches my standards")
}
if(oAuth2Supported){
partialTD.securityDefinitions = {
"oauth2_sec" : oAuth2Supported
}
partialTD.security = "oauth2_sec"
}else{
partialTD.securityDefinitions = {
"bearer_sec" : bearerSupported
}
partialTD.security = "bearer_sec"
}
let thing1 = await WOT.produce(partialTD);
// initialize Properties
await thing1.writeProperty("temperature", 0);
// add service handlers
thing1.setPropertyReadHandler("temperature", () => {
return readLocalTemperatureSensor(); // Promise
});
// start serving requests
await thing1.expose(); We could start from here and improve. I think to assign the |
Thanks, this is helpful, now we are talking in a more clear way. :) This can be done in the way presented above, which is using programmatic API for fetching the security descriptions (and tied to more powerful permissions and API entry point), and a declarative API to tell them to the ExposedThing implementation. Another (theoretical) approach could be a programmatic API at ExposedThing level as well, like it is done with request handlers: I also like the API design for (optional) filtering. I guess the getter would provide a full list. If it has to be an async API, we could use chaining. To be discussed. We could also use the to be agreed filtering scheme with discovery as well. Also related to other issues, the question is where should we place this API. We should re-discuss splitting the WoT API into API objects/namespaces and permission levels. Please check out the Permission API. Today I would use the following grouping, requiring more and more powerful permissions:
These could be used from the same script, but requiring different permissions. |
As referred in #289 (comment):
This issue keeps track of how it would be possible to choose a particular scheme at the application level. One possible solution would be the definition of a proper function that lists all the possible
SecurityScheme
supported by a particular protocol binding and the runtime.Where
Protocol
could be the protocol URI scheme (i.e., HTTP,mqtt, ... )However, I'm sure if it might have some security implications (fingerprinting?).
The text was updated successfully, but these errors were encountered: