-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Implement multi-tenancy access controls: restrict users to specific areas of interest #554
Comments
One way to acheive this is per-object permissions, maybe based on Django-Rules (https://github.com/dfunckt/django-rules) or similar |
I know this was mentioned on #323 but I'd like to add my voice. I just setup NetBox and found it is 100% what my org needs, however not having permissions at the site level is a deal breaker. With 30+ national sites we don't want to give everyone that needs to change IP prefixes at their site the ability to change prefixes across the country. Either way, awesome job Jeremy, this is an impressive and well thought out tool. |
This would be (if I understood aright) a useful feature to allow IT sub teams the management e.g. of their own site(s)/IP space. |
Hi all. I also strongly support this feature. This is one of the most important feature since it is about cloisoning et security. |
I'd love to bring this up again. I'm wanting to deploy NetBox within my organization, but a requirement from my higher ups is that there must be a way for our customers to see their components in our datacenter/network. |
We too are planning to give our customers access to their own racks in our datacenter spaces. I'd very much like this feature to be implemented. As it is now, we'd have to run one netbox instance per customer. It would be great if it would be possible to give user account access to one or more tenants. BTW, great job! |
Implementing this would allow me to use Netbox to replace teampass along with IPAM and Racktables. I need to control access to secrets along side the devices they pertain to but I don't want other groups to have access to an secrets but their own. |
Hey @jeremystretch I have a rough implementation of this feature but would like your opinion and some direction.
|
I'd find this useful as well! @icaro with the more generic models (like DeviceType), have you made the Tenant a Many-to-Many? There are cases where I'd like to grant access at the TenantGroup level. Have you given any thought to that? In my case I have: TenantGroup: Business Unit A (My ideal would be to have Tenants nestable and ignore TenantGroups...) |
Hello @i1caro , do you still working on that? That is a very critical feature. I'd love to see it implemented. Right now I'm forced to keep a legacy system for a few prefixes that I need to give write access for internal teams. Just waiting for this feature to finally get rid of the legacy system. |
FYI I won't accept any sponsorship or merge any sponsored work on the project. Anyone who wishes to do so will need to maintain their own fork. |
I just meant if folks need this at work then maybe |
Can you specify what a 'sponsorship' means in this context? When something is contributed in company time or when $company wants it's name/sponsorship included in some kind of 'wall-of-fame' somewhere? |
I've made a lot of progress on this feature recently, visible in the At a high level, object-based permission assignment is done by crafting one or more ObjectPermission objects mapping users and/or groups to object types. Each instance has four boolean fields indicating the type(s) of action it permits; some set of view, add, change, and delete. Each instance also has a JSON representation of Django query filters, and therein lies the magic. Say, for example, you want to allow a user to view and edit only devices assigned to a specific tenant. You would assign the ObjectPermission to the Device model and enter the following attribute to identify the tenant by slug:
Maybe we want to further restrict the user to only devices of particular roles:
As you can see, this approach is very flexible. All attributes within a single ObjectPermission are combined using a logical AND. To OR multiple attributes, simply create multiple ObjectPermissions. These parameters are enforced whenever a user retrieves objects from NetBox. For example, when viewing the devices list, the user will only see devices matching the specified parameters. These parameters are similarly applied when modifying or deleting an object: the action will be permitted only if the resulting object matches the specified parameters. The evaluation of object-level permissions is deferential to the model-level permissions currently provided by NetBox (and built-into the Django framework). That is to say, if a user has the |
Awesome work!
Would these 'ObjectPermission' objects only be mapped 1:1 to Users/Groups, or could this be implemented on some sort of session level ObjectPermission as well? The scenario I'm thinking about is more of a view filter then strict user based permission. ^^^ the above might be solvable with a plugin that changes a user's mapping to the ObjectPermission as well? Or dynamic group membership even, but I think this requires a re-logon. Curious to your thoughts about this scenario. |
All permissions are assigned based on users and groups. There is no mechanism to support what you describe. |
Awesome work!
|
I've deleted the "," in line 2, just like |
In utility views, the object permission working well, but in home view as follow
the counts are still the counts of all the objects of a model. So, firstly, in home view, it should get all the counts of objects of models which the user has permission to view. change and so on, is it right? |
This is a work in progress. It is currently broken in many places. Tomorrow, it will be broken in different places. Please do not attempt to troubleshoot. |
Have we tried PyCasbin? It supports RBAC with tenant model, which I think fulfilled our goal well. |
OK |
Closes #554: Implement object-based permissions
This has been implemented in PR #4705. There is almost certain to be further testing and mild development to be done, however the functionality is in place. |
FYI v2.9-beta1 has been released. The community's support in testing this implementation will be crucial to its success. https://github.com/netbox-community/netbox/releases/tag/v2.9-beta1 |
Excellent, this feature could make my life much easier. |
I'm testing it currently and as far as I see it works with LDAP groups. |
It helps to recognize authentication and authorization as two discrete aspects: The former entails proving the identify of a user and the groups to which he or she belongs, whereas the later determines what actions the user is permitted to take. As far as NetBox is concerned, LDAP handles the first part, authenticating a user's credentials and (optionally) assigning the user to one or more groups. NetBox's permissions system handles the mapping of users and groups to permitted actions. So, as long as the authentication system is successful in assigning a user to a group, the permissions system can take it from there. |
Agreed. I am not familiar at all with the Django authentication/authorization system - which seems to be not clearly separated (at least in NetBox). For example the configuration only talks about authentication. I wish there would be clear separate authentication and authorization so that I could authenticate with RemoteUserBackend and still use django-auth-ldap for authorization (which specifically says that group mirroring does not work together with RemoteUserBackend - but still talks about authorizing together with RemoteUserBackend). Will need to do more reading and testing... This is now strongly straying to the "support" direction which I tried to avoid. |
I played around with it the last few days. Overall its really solid. For example: I think (if possible) view permissions on components should be inherited from the parent device. So if I have permissions to device A and device B I only should see the components from these devices. |
You can create a new permission for all device component types with the constraint |
Thank you! That seems to do exactly what I wanted. I´ve said nothing! |
I mean, it's a valid point: shouldn't permitted devices "automatically" include child objects? There are two issues with the potential implementation though:
|
It would be really cool to have something like this. But since i really have no clue about how django works I can`t say more than this. Your provided solution works fine for me. Another thing I came across. While playing around with the "Create" permission I noticed that there is no easy way to limit an user to only create addresses in a specific prefix. (Maybe I`m missing something again) The solution I came up with is with regex: Anyway, thank you very much for this feature! |
Honestly I'm just behind on the documentation for this (said every developer ever, right?). Prefixes and IP addresses do have filters available for stuff like this, but you have to dig a bit to find them. For example, if you want to restrict IP addresses to 192.168.0.0/24:
The |
That looks good! I'll have a look tomorrow. And no problem, your documentation is on the better end of documentations. 😉 |
Thanks for this! This is a huge step forward and waiting on this has been a blocker to me merging two NetBox instances in to one. I've played briefly with a dev instance I've just thrown up (docker using develop-2.9 so forgive me if I'm some commits behind). There are a couple of things that strike me as potentially painful or a bit odd. Firstly, the method of granting permissions - one assumes the majority use case for this will be to limit tenants to their own 'stuff'. I started out creating three devices, one of which was assigned tenant 'tenant-A'. I created a group for 'tenant-a' and added user 'bob'. I then granted filtered permissions for devices to tenant-a using {"tenant__slug": "tenant-a"}. So far so good. I then came across the challenges noted above for components of the devices so added additional permissions for {"device__tenant__slug": "tenant-a"} on things like interfaces, console ports, power ports, etc. It occurred to me at this point that while this is awesomely powerful, it would be painful to scale. When I inevitably have to create a tenant-B, I already need to replicate and modify two rules for group 'tenant-b' etc. Would it be possible to consider applying permissions through the group create/edit page or provide a means to duplicate permissions or duplicate a group with all existing permissions that I can then tweak for the amended slugs? Would permissions be able to be OR'd? i.e. be able to specify [{"tenant__slug": "tenant-a"}, {"device__tenant__slug": "tenant-a}] and when applied to have NetBox ignore those rules which make no sense - I see it currently throws an error for filters that don't exist for a given object type hence the need for multiple distinct rules. Secondly, having granted read permissions to all racks, 'bob' can now see details for devices they have no permissions over. I get that showing empty rack would be misleading, but could perhaps devices be rendered in a similar way to rack reservations to indicate that the space is used, but permissions don't grant access to know what by? As a result of this, clicking on a device in the rack elevation view that I don't have permissions over results in a 404 error. Would a 403 forbidden be possible? Even better, could that redirect to the login page to make it clear permissions are not granted? Of course, if the devices/rack units were not clickable, the problem would go away anyway. |
@cpmills1975 thanks for the feedback, but there's a lot to unpack in your comments above. Please consider opening separate issues for each topic so that we can have a more organized conversation around each. |
In fact, I'm going to lock the conversation here just to ensure that additional new commentary doesn't get lost at the bottom of a four-year-old issue. For any bugs or improvements concerning this feature in the v2.9 beta, please open a new issue. Thanks! |
I've read #446 and thought that it would be nice to have a more general and finer access control with an ability to restrict users (user groups) to view / edit / create objects only in specific Tenants, Tenant Groups, or Sites. And such access control should be enforced in UI as well as in API access.
That way one could give some limited access for the tenants' engineers themselves, or set some internal access boundaries (for the security-conscious).
The text was updated successfully, but these errors were encountered: