-
-
Notifications
You must be signed in to change notification settings - Fork 29
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
AuthZ/permissions -- restrict data access to tree namespace user or device is in #268
Comments
NATS Leaf nodes may be applicable. However, it is not clear if leaf/nodes accounts have a completely separate subject namespace, or if a leaf node/account can access a portion of the subject namespace. |
NATS accounts gives you true multi-tenancy, where everything is isolated. Users can have permission maps that restrict a user to specific subject space. It seems we want simple users, not accounts. |
Node topology looks something like this: thinking of arranging the subjects by node IDs: on device #1, if I publish to devices may be located anywhere in the tree, ex: so user the idea is devices or users can access parent node and all sibling nodes/descendants. |
NATS accounts allows remapping using from/to: https://docs.nats.io/nats-server/configuration/securing_nats/accounts#import-configuration-map Seems like that has potential. |
seems just plan users/authz makes sense for initial implementation: https://docs.nats.io/nats-server/configuration/securing_nats/authorization accounts/leaf nodes seems too complex for this application where the NATS api is relatively small, so manually prefixing upstream traffic is not a big deal. |
Apparently the restriction of using not using wildcards in mapping account services has been lifted in recent versions of nats-server, from slack: https://natsio.slack.com/archives/C069GSYFP/p1632331335086300 Will need to think about this some more ... |
Thanks. should clarify that the current GUI tends to make it look like the server is doing authz because of the tree but it’s only doing auth ? |
correct, the current UI simply fetches and displays the nodes and trees the user is child of, but there is nothing to prevent the frontend from fetching all nodes. So we only display what the user has access to, but don't prevent him from accessing everything. Works for now as I focus on features, but is not production grade. |
Makes sense . thanks for confirming. |
My own 2 cents on this. What if you just did not use any of the NATS authz aspects and enforced all authz above nats ? Basically we have to wrap nats in general. It is already wrapped by the SIOT admin gui using rest or WS. Good
Bad
Example of how to do it: Cerbos for example is a Authz policy system. It can work with anything. Its very simple to use. https://github.com/cerbos/demo-rest/blob/main/service/service.go#L222 shows exactly how you use it. Policies can be anywhere. File, memory, db. Does not matter. Here is the ones for the example: https://github.com/cerbos/demo-rest/blob/main/cerbos/policies/order_resource.yaml I have tried this out and was able to get it working. Can be used for HTTP, WS, NATS, Anything to wrap access control so all we would need to do is write a siot gui control to express how cervix policies work to the degree we need and then enforce them in the backend based out the route . And we could do them at the WS Layer. |
Very interesting projects -- amazing all the stuff out there. For devices, we don't have to wrap NATS -- they currently speak native NATs. It seems we must do auth at the NATs level. Devices will subscribe/post to a NATS topic:
If Adding an auth mechanism on top of NATs (would require wrapping NATs) would be possible, but then we loose most of the benefits of using NATS in the first place:
I'm trying to avoid another mechanism for configuring Auth -- I want the location in the node tree to specify permissions explicitly. This saves a ton of overhead and complexity as a programmer and user. That all said, my use case (very distributed systems) may be different than yours, so I don't want to discourage experimentation. A simple node tree may not provide enough dimensions for some use cases. The approach I've taken with SIOT is to focus on solving real world problems. I still need to write up articles on some of the applications I've implemented using SIOT recently. It is easy for me to get deep in the weeds of implementing cool architectures, but what really helps me pull things forward is solving real world problems. This is why I've not worried about authZ until now -- I did not have a need in the projects I was working on. It might help to share some details on the type of problems you are trying to solve with SIOT. Feel free to email me directly. Another nagging concern with wrapping NATS is seems we really need to prove the NATS auth model is inadequate first before justifying adding another layer of abstraction and complexity. Lets try to solve the immediate problems we have now and see what does not work. Again, I don't want to discourage exploration, but I also want to be make sure our visions are aligned. It is easier to sort this out now vs after working together for 6mo and discover we are heading in different directions.. |
Yes thats what i also assumed... and you raise a good point. SO yes if you use Cerbos, how will you secure the IOT endpoints ? I was thinking of wrapping the NATS connection on the IOT devices. Just like we wrap the GUI with WS. I naturally lean towards wrapping NATS.. Its great but if NATS just does not quite do what you want later, your going to wish you wrapped it. And its not hard because the wrapper does not need to hold state. Sure it needs to hold a connection, but as soon as state goes across the wire, it just pushes it into NATS on the server.
THis sort of gets to my point. If we dont use NATS authz, then all these questions above become Moot.
Very distributed is exactly what i like about SIOT. Its a really neat approach.. Wrapping genjo with NATS is something i was thinking about for a few years and you went and did it :) I think that SIOT's usefulness is not apparent unless you have been through the wars of running other complex systems... I have been through some of those wars :)
my Bucketlist of what SIOT is good for:
This is also what i am worried about. NATS Auth has its own way of working ( its like configuring a Enterprise router in many ways, but i don't want to digress right now ), and anything that it cant do will cause friction. the old 80/20 rule. This is why i suggested holding all the Auth and Autz in Genji, and then apply the Guard / Checking just above NATS. Cerbos can use the file system of badgerDB, and so holding the Open Policy rules inside genji would be very easy.
I totally agree that Both approaches should be looked at NATS and Cerbos... |
Another possibility is that each nats client that connects authenticates and is given a random secure message space that it can subscribe/publish to. The server keeps a map of node hierarchy locations and can then map messages to it. If the node is moved around on the server, then this would need to update dynamically, but the client would not have to know anything. Advantage of this is the client does not need to know anything about the server node hierarchy other than its node ID, or user/auth credentials. This may allow us to bypass the entire NATS auth mechanism. cc: @bminer |
another scheme might be that a user or device do everything in their own Where the remote user/device only has permission to read/write to The leading Any time a point is received, it travels up the tree. If we encounter users or devices, we re-broadcast the message to the One challenge with this is we now have multiple subjects to keep track of, so we need to be sure not to send the message back to the remote client that sent it. Perhaps when we receive a point, we keep track of who it came from and then as we walk up the graph, we never re-transmit back to that device/user. |
Or just add an origin meta field, and check it each time you are about to send a message. |
This is kind of related : https://github.com/aperturerobotics/controllerbus it’s multi protocol way of doing distributed messaging and can run inside a browser or not. If can use NATS too. mit can also do golang wasm to golang communication. You could simulate a huge network of IOT devices in the böse with each device being a web worker and file system and db backing it too. See hack-pad/hackpad#11 and the hackpadfs repo |
I like this idea. Long term, we'll need to track who modified each point anyway for config change auditing, so I think adding an origin field to the point data structure makes sense. Perhaps for if the point originated from the node owning the point, we could leave this field blank to save on data bandwidth for sensor data, which will be most of the data in the system, and if its blank, we assume the owning node is the author. Anything else, we set the origin. Having an audit trail of who changed what is important in these systems -- even just for debugging rules -- which rule last changed this point ... cc: @bminer |
The way the auth spec is currently designed basically uses JWT tokens to restrict how NATS clients can publish and subscribe to various subjects. Anonymous NATS clients can only publish to The |
sounds good to me. I think with the addition of the Origin Point field to prevent echos, the idea of a custom subject namespace for each authenticated user (downstream device, client, user, etc). will work pretty well. We could still have an echo if a user on a downstream node updates a point. NATS messages can also have headers, which could be the ID of the instance that sent the message (downstream device, client process, browser, etc). This is side channel information that is not stored as part of the message content. This needs more thought, but I think we have some good options to make this all work. The fundamental difference between SIOT and most streaming/event systems is we offer strong support for multiple actors to modify a single piece of data with CRDT properties -- data can flow in any direction. Most event/streaming are structured for data always flowing the same direction. |
Updated https://docs.simpleiot.org/docs/ref/client.html#message-echo with some thoughts on echo problem. |
I think that, in general, echo would be desired. What do you think? EDIT: In other words, perhaps it is something each NATS client should deal with. |
sketched a few things out to think through this -- I think it will be simpler than I imagined as the "Mux client" can have NoEcho set, and that should prevent any echo problems when muxing (is there a better name) messages between the main NATS subject The Mux/Store Client is responsible for storing everything in the database and based on the node graph, replicating messages on upstream nodes (that rules, etc) may subscribe to as well as auth subject namespaces for authenticated clients. I'd like to get to the point eventually where no processing happens in the store other than muxing messages, storing the points changes in the DB, and responding to NATS DB requests such as node, and child node requests. |
NATS by example has some interesting auth examples with private inbox: |
I was going to suggest the same example :) |
right now, any user or device can access any point data in the system. Would be nice to if a user/device could only access data for the segment of the tree they are in.
The text was updated successfully, but these errors were encountered: