-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Feature: Dynamic security control #1779
Comments
Added group priority. |
Users
|
I assume the repsonses to the commands will follow the Request/Response scheme as described in the MQTTv5 specification. The client will specify a Response Topic and may pass some Correlation Data. |
|
@ckrey There are few ways I've been thinking about dealing with responses. First off, I don't really want to restrict these features to MQTT v5 only so have to consider MQTT v3 as well. That implies that a default response topic is required. The two ways I was thinking about this are:
In both cases I'm a little bit nervous about letting the client define their own response topic because of the possibility of sending sensitive data to |
With respect to JWT, firstly, it is a solution for authorization and not authentication. Secondly, it is a tiny piece of JSON that is sent by the client as a set of 'claims'. These claims are verified by the server. The issuance of the JWT itself is typically handled by a different system e.g. Microsoft AD, Keycloak, etc. For a MQTT broker, couple of use cases could be as follows:
One related question. Are you basing the security construct on user name and password? Why not client identifier? Perhaps, alongside username password? I mention this because, the client identifier is mandatory as per the spec (which you know already. :D ) |
Just thinking... Should the configuration of security policy be via MQTT messages at all? I mean, how do we "police the police" given that, the entity publishing the configuration commands should also come under access control. Using a configuration file with 'hot' reload is not a bad option at all. (Although, I have no idea if it is possible). Better yet, have the configuration driven off of a access control solution e.g. Microsoft AD, Keycloak, etc. (Ok, the latter option is more enterprise suited.) |
That sounds great. I think its a good idea to rework mosquittos authentication. Projects such as https://github.com/iegomez/mosquitto-go-auth and https://github.com/jpmens/mosquitto-auth-plug seemingly filled some gap in the last years. For me, authentication and authorization typically invovles integration. Typically, mqtt is used in a distributed setups, that also involve some protocols. I'd suggest: Providing a clear separation between permissions, roles, users and groups. I think that this is vital, but I don't find it in your concept. Permissions define what somebody can do. Roles aggregate Permissions. Users (or accounts) are managed in some kind of repository, whereas Groups aggregate users: For instance: hsimpson is user in group sector-7g-employees, whereas subscribe-radiation-alert is a permission, that could be aggregated in a role called safety-inspector. Typically, users and groups are provided by 3rd party systems (or text files for KISS), whereas permissions and roles are defined in mosquitto. Mapping takes place. One can think of a lot: You can map permissions to users (e.g. Homer Simpson is allowed to subscribe to radiation alerts), group to permission (e.g. all employees in section 7g get radiation alerts), user to role (Homer Simpson is a safety inspector) and group to roles (all employees in group sector 7g play the role of safety inspectors) … poor Springfield. But… that’s quiet complex. IMHO, typically, it suffices to map groups to roles by names. E.g. that would require Homer Simpson to be member of a Group called safety-inspects as well. I guess that this kind of mapping suffices for mosquitto but some edge-case could require some explicit mappings. However, mapping permissions typically results in long and almost unreadable definitions. When integrating with JWT or SAML (or both) you could also map roles to claims or attribute-values. I think it's a good idea to rely on plugins for integrating 3rd party systems. Nevertheless, LDAP, SQL and JWT are really popular nowadays. Maybe, it could help to integrate some work from https://github.com/iegomez/mosquitto-go-auth. An plugin is then required to authenticate credentials of an arbitrary chosen format and to retrieve user as well as group information. This is then used by mosquitto (core) to apply permissions and roles. Edit: I really do like to model of: https://github.com/stffn/declarative_authorization - it's solely authorization, nevertheles. But the ACL is elegant. |
@chainhead Thank you for the JWT examples, those kind of capabilities are certainly appealing. Including the client id - yes absolutely if desired. The current system uses a file with reloadable values and has been cited to me as a reason not to use Mosquitto. |
@yanosz Thanks for your comments. You're right that the permissions part isn't as clear as it needs to be. With regards roles/users/groups, I would say that my "policy", which is a collection of permissions (and can include denials), is equivalent to a role. A group can have a policy attached to it, and likewise users can have policies attached to them. A user can be in multiple groups, which means multiple roles. I hadn't planned on having a user being able to have multiple policies attached to them directly, but this could be managed in the current draft by having the user in multiple groups, even if that group only has a single member. With regards integrations, they are definitely important and must be considered in the design, but I think the first iteration will be limited to being a standalone implementation. |
@ralight thanks for your feedback. Regarding:
I won't go for denials. I prefer to stick to either a 100% grant or 100% denial approach. Having both denial and grants can be a little bit confusing. I've to admit that policies looked to me like permissions in the first place. i guess, they are something in between.
IMHO it'd be helpful to maintain API compatibility with https://github.com/iegomez/mosquitto-go-auth, as long as the 3rd party integration is not complete. It would be ok to deprecate parts on the API in the first iteration, but I guess that many peoply rely on this code. |
I wonder why. Anyway, these are the options I see. BrokerDelegate all access control to enterprise solutionsBroker relies on a simple Pros
Cons
Delegate only life-cycle methods to enterprise solutionsThe mechanisms to on-board or off-board a principal and also maintain its access (resource and action) is left to the enterprise systems. Whereas, only the verification is done by Pros
Cons
Implement authn and authzThis is, of course, your proposal. Pros
Cons
ClientOn the client side, sending a token maybe seen as an overhead by some clients. |
I want to say that I love the idea of having a no-fuzz access control system available in mosquitto. Is simply a must in today's world, even for weekend projects. Still, when I think of what other users of mosquitto might like, I am not sure that they will love it that much.
One of the things I like about mosquitto is it's simplicity. Maybe by choice, maybe by accident, but it's the only broker I know that adheres to the UNIX philosophy of:
It is my humble opinion that adding the suggested changes, will make mosquitto leave a void in this category. And it will be painful for anyone keeping a "customized" version of the security implementation, as s/he will have to keep a customized version of the broker as a whole. Again, don't take me wrong, I use mosquitto in my hobby projects and having reinvented the ACL wheel a few times already, I would definitely love to have it OOB. I know that the original email said "without needing a separate plugin", but I would like to suggest a third option. If you look at other software packages like NGINX, they offload client authorization to a 3rd party, by making a subrequest (using the same HTTP protocol). I imagine it would be possible to do the same, but over MQTT (maybe over a different, isolated listener using UNIX domain sockets or something?). In case the overhead is an issue, maybe revisiting the plugin interface can be an alternative. Over the years I've used it and I think is adequate enough. It's only problem is being a second class citizen (or at least I feel it that way). I believe the API you suggested can be implemented in isolation, and provided to the community as a "reference" that actually does work (with full official support). Everything will still adhere to the "do one thing and do it well", and advanced users will still be able to morph it to their needs. I want to congratulate @ralight for starting this conversation, as I believe mosquitto can benefit a lot by having security available out of the box. Please count me in if you need help coding it. |
I find this all a bit concerning. Using topics to configure access control for topics feels a bit circular, even though I think it could be done correctly. The question about initial users who can set policy is excellent. Having mosquitto print a password does not seem reasonable. This all needs to work within the context of packaging systems and management schemes (e.g. ansible, but I broadly mean all such schemes including ad hoc ones). I would suggest that this is somewhat like postfresql's access model where a superuser is created from the command line and then sql is used, and it makes sense to look to that. So the user/password (or certificate) of the superuser needs to be put in a config file, or else there needs to be a program that can set that via e.g a priviliged socket. Another question is how all of this is stored. Unlike normal topics, it seems obvious that it must be persistent. While json is easy for some, it also seems that a command-line program to send the json must be provided so that one can do normal operations like 'create this user'. I can see the allure of dynamic changing of users, but that feels like it is reinventing radius and an authorization system. I personally really like it that I have a config file with all my users and passwords in them. It's easy to understand and easy to change (emacs is my automation system!). So I would lean to a file-based config - perhaps a separate authn/authz file - as the baseline, and allow plugins to be fancier. One would be a database of some kind, and that would then enable this publish-json mechanism. I would prefer to keep that off - if I don't have an articulated need for dynamic acls, then it's just one more thing to be sure about, and something Finally, I would suggest stepping back and writing requirements first. I'm not really sure what problem this is solving for who. If I did understand that I'd probably say something different. |
Thanks all for your comments, I haven't replied before because I've been on holiday and then dealing with other things. |
This is already possible with the current system, through a plugin. As you say, this has a low impact on Mosquitto itself and just needs implementing where desired. I would view that as a parallel solution to what I'm proposing here.
This approach has definite appeal to me. The most obvious way to add a JWT token is with a MQTT v5 user-property, which would limit where it could be used (no MQTT v3 clients), but for some situations this would be fine. There is no reason this couldn't be produced as another parallel solution, and I suspect that I will be looking at it in the future. |
Both of your replies highlight some aspects of where I haven't included enough of the things that are "obvious" to me in my head, and should have spelled out clearly. This is absolutely not a proposal to remove the existing security setup and replace it with a new setup. This is a new security mechanism which would sit alongside the existing file based security, and other plugins. As such, it would be entirely optional but hopefully become a popular way of administering users. @abiliojr - if I understand what you are saying correctly, your concerns are primarily that this would be a default replacement for what exists, and would prevent other security systems being developed. Is that correct? If so, I think I have addressed those points. When I said "without the need for a separate plugin", I meant without the need for a plugin separate to the project - a third party plugin. @gdt - it took me a long time to come around to using topics for configuration purposes. When a requirement is that it should work remotely, I think it is the best choice however, rather than implementing something entirely new for the same purpose. In terms of first setup, yes, having the broker print out admin details is not a good idea. Having a tool to add the first user would be a good plan, alternatively you could use mosquitto_passwd to create a user and then use an acl file to grant access, but that is not as nice. The setup provided by this must of course be persistent, and would be a json file. That could obviously be manipulated by hand, but essentially it would be owned by the broker process and so it wouldn't be recommended. The json messages shown here to control everything are just the interface. I'm not expecting anybody to type them in manually, there definitely needs to be an easy way of producing them. I intend to provide a command line tool, but haven't started thinking about it too much yet. Addressing requirements - a remotely configurable security mechanism that is self contained, allows on the fly updates to users, groups, and the rights that each of those have. Suitable for deployment in a similar amount of disk/memory overhead as a current Mosquitto installation |
Just to prove that this isn't an abstract idea, I am working on a commercial project which needs pretty much what is being discussed here. Without divulging anything which you can't find publicly about the LV-CAP project:
From our point of view, if we could re-configure the broker ACL by sending Mosquitto a JSON payload each time the Docker orchestrator runs up or stops a Docker container, this would be ideal. From this perspective:
For completeness, the issues using the existing file-and-reload scheme to change settings are:
In the details:
|
@richardash1981 Thanks for your comments, it's good to hear there are other people that would benefit from this. The systems you have sound quite capable compared to others I've been involved in :)
In this situation you could also have a pre-created copy of the json file the dynamic security would use for storing its config, and just copy that to the appropriate place on provisioning.
The current ACL files have |
I'm sorry for the late reply, life kept me away from this topic. Hope is not too late. @ralight, I think I have a clearer view of your idea. Am I getting it wrong, or part of this can be implemented using the plugin interface? (maybe with some extensions). Then, as a plus, this plugin could serve as a reference design for other people. If that's the case, can we improve the API in the process? (or leave space for future improvement). Here are some ideas, mostly based on (mis)beliefs and memories:
More important, an improved documentation of the API, telling what can be done with it and it's limitations. Most of the beliefs listed here come from the lack of an official source of truth other than swimming into the code. @ralight, how do I help? |
This was released as part of 2.0. |
Reading the thread here and the docs on Dynamic Security plugin, it appears that only username + password auth is possible for clients and not client certificates like is possible with an ACL? Or am I missing something in the docs? |
Mosquitto Dynamic Security
This document describes a topic based mechanism for controlling security in
Mosquitto. JSON commands are published to topics like
$CONTROL/<feature>/v1
Users
When a client connects to Mosquitto, it can optionally provide a username. The
username maps the client to a user on the broker, if it exists. Multiple
clients can make use of the same username, and hence the same broker user.
Groups
Broker users can be defined as belonging to zero or more broker groups.
Security Policies
Security policies can be applied to a user or a group, and define what that
user/group is allowed to do, for example what topics it may or may not publish
or subscribe to, or whether it is allowed to access different administrative
features.
If a user is in a group, and both the user and the group have separate policies
applied, then the user policy will override the group policy.
Users can have their groups assigned a priority. This means that if they are in multiple groups, the order in which policies are applied can be defined. Policy will be applied starting with the group with the lowest priority, moving to groups with higher priorities, and finally a user policy if defined.
If a user is not a member of any groups, and does not have a user policy, then all access will be denied.
Policy Features
Security policy management
Actions:
Topic:
$CONTROL/security-policy/v1
User/group management
Actions:
Topic:
$CONTROL/user-management/v1
Bridge control
Future
Listener control
Future
General preferences
Future, e.g.
max_keepalive
.Security policy management
Topic:
$CONTROL/security-policy/v1
Commands are JSON payloads as defined below. There can be any number of
commands in a single message. The below schema defines all of the available
commands.
User/group management
Topic:
$CONTROL/user-management/v1
Policy storage
How policies are stored on disk.
User and group storage
The text was updated successfully, but these errors were encountered: