Permissions and Access Control Revamp¶
General Overview¶
To allow precise segmentation of all things (as requested multiple times, in #7718 for example) 2 new concepts are introduced:
Workspaces
Profiles
These can be seen as extensions of the existing concepts of Project Codes and Groups (in their usage for permission scoping).
New Concepts¶
Workspaces¶
Workspaces can be thought of similar to organizations in GitHub, Groups in GitLab or Organizational Units in Active Directory. They borrow some names/ideas from these concepts, but are tailored to the needs of InvenTree and are not a superset.
Workspace Business Rules¶
Workspaces support tree-like nesting, similar to part categories
Workspaces have attributes to make navigating and organisation for the user easier. Each must have a name and slug and can have a short name, description, icon and color, an owner (user or group) and a responsible (user or group). The later two might be used for targeting notifications
There is the default workspace “Default” (always pk 1, can not be deleted), which will be the default workspace for all models supporting workspaces
Each object supporting workspaces is assigned to exactly one workspace
Users can be a member of multiple workspaces
A user can only work in one workspace at a time / API call and can only create interactions between objects in that workspace or global objects (not assignable to any workspace)
Plugins can ship models that support workspaces or chose to stay global (available in all workspaces) - which is the default
API paths for all models/objects/actions that support workspaces will be optionally extended by a workspace identifier, so that all queries are scoped to the required workspace. If no workspace is provided for a workspace-scoped endpoint, the “Default” workspace is assumed.
Usage of the workspace feature can be enabled in a global system setting; disabling it will hide all UI features related to workspaces. Internally, workspaces will still be assigned to all new/manipulated objects with the “Default” workspace. Existing workspace assignments will be preserved, but ignored.
Disabling the workspace feature after it has been used would hide all objects not assigned to the “Default” workspace - therefore, I am considering adding a wizard to the Admin Center that would allow re-assigning all objects to the “Default” workspace before disabling the feature.
Workspaces would be implemented as a single workspace model and by adding a generic foreign key to all models that support workspaces.
Workspace Usage¶
Workspaces might be organized like this:
- Default (default : 1)
- My Space Adventure (msa : 2)
- Suits (msa/suit : 3)
- First Eval Generation ( msa/suit/first : 4)
- Andromda Generation (msa/suit/andromeda : 5)
- Mars and Beyond Generation (msa/suit/mars : 6)
- Rockets ( msa/rocket : 7)
- Habitats ( msa/habitat : 8)
- Special Project X (spx : 9)
Being assigned access to “My Space Adventure” would give access to workspaces 2,3,4,5,6,7,8 Working in workspace 5 “msa/suit/andromeda” would only show objects to workspace 5 Working in workspace 2 “msa” would only show objects assigned to workspaces 2
Profiles¶
Profiles are a way to represent a certain configuration area of InvenTree, there can be a number of different profiles types, but every object is only assigned to one profile per profile type at a time.
Profile Business Rules¶
Profile types are defined globally
Plugins can define new profile types
Profiles are instances of a single profile type
Profiles can have attributes, depending on their profile type
Each object can only be assigned to one profile per profile type
Default Profiles can be inherited (details to be defined) - so behavior can be defined at a higher level (e.g. part category) and inherited by all child objects unless overridden
Profiles can be “owned” by a user or group to allow controlling configuration of certain profile types
Model structure:
ProfileType
name
description
source (core, plugin, unknown)
plugin (nullable FK to Plugin model)
Profile
profile_type (FK to ProfileType)
name
description
settings (JSONField for profile specific settings)
owner (nullable FK to User or Group)
ProfileAssignment
profile (FK to Profile)
content_type (Generic FK to any model supporting profiles)
object_id (Generic FK to any model supporting profiles)
inherited (bool, if the assignment is inherited from a parent object, e.g. part category)
inheritance_source (nullable Generic FK to the object the profile is inherited from)
Profile Usage¶
Profiles might be used for:
Setting behavioral options for certain models (e.g. Part behavior profile, Supplier behavior profile)
Access control (e.g. defining which actions are allowed on a model for users assigned to a certain profile)
UI configuration (e.g. defining which fields are visible/editable for a model for users)
Required parameters
In the first iteration, I plan to use ProfileAssigments as a lookup target for permission checks, making a gradual transition from classic Django permissions to Profile based permission scoping possible.
Changes current things¶
Existing Roles¶
The role system would be preserved as is for reverse compatibility, but definitions of roles would move to the individual models / apps where possible to remove the coupling between users / and the apps (parts, stock, etc) as much as possible.
New Roles model?¶
I think it could make sense to have a new Roles model that defines roles as a model and that would make it usable by plugins as well.
Expand permission information in the API schema¶
The API schema would be expanded to include information about which permissions are required for each endpoint. I did a small prototype of this in #10628.
Extending docs / adding a best practices guide¶
The documentation should be extended to include information about how the permission system works and how to use it effectively. A best practices guide could be added to help users understand how to set up permissions in a way that is secure and is intended by the developers.
Things I want to avoid / think might cause a problem¶
Moving project codes into workspaces - project codes were introduces with another stated purpose and I want to avoid confusion
Using project codes as a way to segment permissions - projects codes are very simple objects and would need far reaching changes to be used for permission scoping, bluring the line to workspaces
Sharing stock items between workspaces - this would make the API more complex
Using any dynamic scoping that is not pre-defined - I want to avoid having to calculate permissions on the fly as much as possible for performance and audit logging (#9996) reasons
The ability for users to easily move objects between workspaces - this should be a deliberate action that requires admin access and is not done lightly (also because it is probably api-expensive)
Definitions¶
Global¶
Something system wide, there is only one value / setting / instance for or of it. Can not be segmented any further. Example: System Settings, Users, Groups
User¶
A human actor interacting with the InvenTree system, represented by a User object, typically using the frontend
Actor¶
An entity that interacts with the system. This can be a user, automated system, workarea access station
Model¶
A Django model
Object¶
An instance of a Django model
Action¶
An operation that can be performed via the API. Either on an object, a collection of objects, a model or against the global system