Closed drasko closed 8 years ago
Great question and one that we have discussed several times. There are a few ways to address this scenario:
@chrismatthieu this is indeed very important question, as without this explained I do not see how Meshblu can be used as a cloud platform for a developer/producer to put his product on the market.
1. Your application could manage the controls of which properties the new lamp owner could modify.
I do not like really much this approach, because then every application would have to manage presentation to the user.
However - this would not prevent user to modify the Device representation in the database. As he receives his UUID/auth_token when he registers on Meshblu he can just make the curl calls over /devices
route (when he claimed the device he became the owner), independently of the app you provided.
2. You could transition away from owner (like we are doing) and manage all devices purely with whitelists and blacklists. This would allow you to give the new "owner" discover, send, and receive permissions but not configure.
This looks like the best solution to me and this is what I had in mind:
However, I still see two problems with this approach:
I am thinking about these potential solutions:
user
field alongside with owner
user
can have limited scope
inside device, as defined by the owner
user
can whitelist other users (even though not being whitelisted in config), who inherit his scope
, or some definable subset of his scope
This could potentially resolve both problems I mentioned. Do you see some problems in this thinking?
3. We have implemented a concept of virtual devices (not yet documented). This approach allows you to create a UUID for a virtual device that a user or groups of users can "own" that simply points to the actual device. This approach may give you more flexibility to managing and securing the actual device. We can elaborate more on this approach if it sounds interesting to you...
Yes, this sound interesting, but I still can not see the real value in this (lack of info). On the contrary, I am very afraid that this will potentially complicate the system. Imagine that practically all devices you have to duplicate with Virtual Device(s) - and in IoT we expect already millions and millions of devices... I suppose that this Virtual Device will have a separate auth_token - which is an additional thing to sell to developer, and it doubles the cost of the product (cloud wise).
But yes, please do tell me more about the concept - I can not completely understand it without further explications.
While I agree with you about virtual devices adding more complexity to your app, I believe that this option (#3) will meet your needs. I'll defer to someone else on the team that can explain virtual devices and how they can be used as groups better than me.
We've discussed virtual devices a lot amongst the team and implemented some prototypes. I'll write up something to explain it in detail.
@iamruinous thanks a lot. I think this thread is a good place to post a summary, I am very interested about the concept.
Can you please also comment on my idea of adding the user
and scope
fields to Device model?
Currently owner
imbues special access to the device placed in there, bypassing the whitelists. I'd like to see that removed. Whitelists should be the only thing that determine authorization. Owner should simply be metadata and have no special meaning.
Adding user
and scope
would lead to more special cases. The whitelists should provide the necessary mechanisms to build robust applications. If it can't be done with the current set (configure
, discover
, receive
, send
, configureAs
, discoverAs
, receiveAs
, sendAs
) then we should add more whitelists.
The more complicated permissions are, the larger the attack surface as well as greater likelihood of bugs.
Virtual Devices
are shadows of a "real" device. A user can have discover/configure rights to a "shadow", and never even know that the real device exists. Using Meshblu Config Forwarding it becomes easy to forward all changes the user makes to a service that can then verify the update. To the user they are manipulating a Meshblu device just like any other.
We are currently building something similar to this to allow group device management in Octoblu. Below is a rough, untested example to convey the basic idea.
Given these Meshblu devices:
Admin = {
uuid: "admin-uuid"
}
User = {
uuid: "user-uuid"
}
Device = {
uuid: "device-uuid",
configureWhitelist: ["admin-uuid"],
discoverWhitelist: ["admin-uuid"],
meshblu: {
configHooks: [
{
url:"http://device-service/original-update/device-uuid",
method: "POST"
}
]
}
}
VirtualDevice = {
uuid: "virtual-device-uuid",
parentDevice: "device-uuid",
configureWhitelist: [
"user-uuid",
"device-uuid"
],
discoverWhitelist: [
"user-uuid",
"device-uuid"
],
meshblu: {
configHooks: [
{
url:"http://device-service/virtual-update/virtual-device-uuid",
method: "POST"
}
]
}
}
The configHook specified in the VirtualDevice
will forward the config
event to any HTTP webhook.
// example express request handler, (untested psuedo-ish code)
var _ = require('lodash');
var MeshbluHttp = require('meshblu-http');
var OMITTED_FIELDS = ['uuid', 'meshblu', 'owner', 'token', 'sendWhitelist', 'receiveWhitelist', 'configureWhitelist', 'discoverWhitelist', 'sendBlacklist', 'receiveBlacklist', 'configureBlacklist', 'discoverBlacklist', 'sendAsWhitelist', 'receiveAsWhitelist', 'configureAsWhitelist', 'discoverAsWhitelist'];
function virtualUpdate(req, res) {
var meshbluConfig = {uuid: 'device-uuid', token: 'device-token'};
var meshbluHttp = new MeshbluHttp(meshbluConfig);
var id = req.params.id;
var update = _.omit(req.body, OMITTED_FIELDS);
meshbluHttp.update(id, update, function(error) {
if (error != null) {
res.status(422).send(error.message);
}
return res.status(204).end();
});
}
function deviceUpdate(req, res) {
var meshbluConfig = {uuid: 'device-uuid', token: 'device-token'};
var meshbluHttp = new MeshbluHttp(meshbluConfig);
var id = req.params.id;
var update = _.omit(req.body, OMITTED_FIELDS);
meshbluHttp.find({parentDevice: id}, function(error, devices){
_.each(devices, function(device){
meshbluHttp.update(device.uuid, update, function(error) {
...
});
})
});
}
I am wondering about production scenarios with Meshblu. Let's take this use-case:
/claimdevice/{uuid}
and his UUID is set now to be the ownerIs this how it is supposed to work?
I see several problems with this scenario:
How do we handle these issues and what is a correct procedure for this use-case - i.e. for making a connected product with Meshblu?