Description
Is your feature request related to a problem? Please describe.
This issue is a feature request. Workspace will be a new concept to organize saved objects. The saved objects under specific workspaces should be isolate. There are three key features need to be implement for the permission control logic.
- Create / update workspace with permission setting
Each workspace should be independent of each other. When calling the create workspace API, it should be able to set which users have permissions on the workspace. The user who calls the creation API should have the permission to modify the saved objects in the workspace and update the workspace by default. In addition, for the created workspace, it should be able to update the permission settings through the workspace update API.
- Find saved objects by ACL params
In Opensearch Dashboards, the find method in the saved objects client is generally used to search and filter saved objects. After adding permission control logic, the find method can only return data that the user has permission to access. Therefore, the find method should support querying saved objects through ACL to limit query returns in permission control logic.
- Add permission control for saved object client CRUD
In Opensearch Dashboards, saved objects client is generally used to operate saved objects. Operations on saved objects should follow the corresponding permission settings if permission control is turned on. For example, when creating a saved object, if the user specifies that it should be created in a specific workspace. Then when performing the creation operation, it should check whether the user has write permissions for the workspace. The above steps should be followed for all CRUD operations, and it is necessary to check whether the user has permissions for the corresponding workspace or saved objects.
Describe the solution you'd like
For the above three main features, we need to modify the code in OSD to implement them. Most of the code will be located in the workspaces plug-in, and only a small part that needs to modify the search dsl will be placed in the saved objects service. There are four kinds of permission modes. Here is a fully introduction about these permission modes.
All the permission control related features has been protected by savedObjects.permission.enabled
and workspace.enabled
flag. Need to set these two flags to true
to enable them.
- Create / update workspace with permission setting
To add permission settings to the workspace, you need to add the corresponding permission setting fields to the workspace creation and update methods. Then put the incoming permission settings into the corresponding saved objects client method call. This completes the creation and update of the workspace's permission settings.
- Find saved objects by ACL params
For the find method in the saved objects client, new ACLSearchParams
and workspaceSearchOperator
fields will be added. ACLSearchParams
is used to specify the user name, user group and corresponding permission information to be searched.
interface Principals {
users?: string[];
groups?: string[];
}
interface SavedObjectsFindOptions {
//...other fields
/** If specified, will only retrieve objects that are in the workspaces */
workspaces?: string[];
/** By default the operator will be 'AND' */
workspacesSearchOperator?: 'AND' | 'OR';
/**
* The params here will be combined with bool clause and is used for filtering with ACL structure.
*/
ACLSearchParams?: {
principals?: Principals;
permissionModes?: string[];
};
}
The workspaceSearchOperator
is used to specify the search method for the incoming workspaces. The value will be AND
by default, which means that the result data returned by the query will belong to the incoming workspaces. If it is OR
, which means that in addition to other ACL conditions, the data in the incoming workspaces will also be returned.
Here are some examples:
{
"workspaces": ["workspace-1"]
}
For this case, the result will only return saved objects belongs to workspace-1.
{
"workspaces": ["workspace-1"],
"workspacesSearchOperator": "OR"
"ACLSearchParams": [
{
"principals": {
"users": ["user-1"]
},
"permissionModes": ["read", "write"]
}
]
}
For this case, the result will return saved objects belongs to workspace-1 and all saved objects that user-1 has read and write permission.
- Add permission control for saved object client CRUD
The main solution of add permission validation logic is using saved objects client wrapper just like the workspace conflicts validation logic. The saved objects client related methods will be overwrite after adding client wrapper to the saved objects service. This client wrapper depends on permission control service. The permission control service provide methods to validate saved objects based permissions
attribute. It's using hasPermission
in ACL
to validate if saved object matched passed permission modes and principles. For CRUD methods in client wrapper, there are different validation rules for different methods.
- create / bulkCreate
Forcreate
method, it will check if haslibrary_write
permission to passed workspaces whenoptions.workspaces
was provided. It will throw permission error if doesn't have permission. Since thecreate
method can overwrite existing saved objects, it will validate permission ifoptions.overwrite
andoptions.id
passed. It will try to get existing saved objects, and validatelibrary_write
permission to its workspaces orwrite
permission to itself. It will throw permission error if not permitted. ThebulkCreate
permission validation logic was the very similar ascreate
. ThebulkCreate
will do these permission validation logic for all passed saved objects. - get / bulkGet
Forget
method, it will get saved object first. And then will check if haslibrary_read
orlibrary_write
permission to one of the saved object's workspaces. If it doesn't have permission, it will check theread
orwrite
permission on saved object. Then throw permission error if not permitted. ThebulkGet
method do the same thing for all passed saved objects. - find
Forfind
method, there are three different cases.
Thefind
method will check theoptions.type
first. This is the case 1, for findingworkspace
type saved objects. It will assign theprincipals
from request to theACLSearchParams.principals
and assignread
orwrite
to theACLSearchParams.permissionModes
too if not provided. This means find all workspace saved objects that user has read and write permission.
Ifoptions.type
was not provided, these are case 2 and case 3. For these two cases, need to get user permitted workspaces first.
Ifoptions.workspaces
provided, this is case 2. It will filter out not permitted workspaces inoptions.workspaces
. This means find all permitted saved objects under permitted workspaces.
Ifoptions.workspaces
was not provided, it's case 3. It will assign request principals tooptions.ACLSearchParams.principals
. Which means find all permitted saved objects based user passed permission modes. - update / bulkUpdate
Forupdate
method, it will get passed saved objects first. Then it will check if has one of thelibrary_write
permission to saved objects's workspace or if haswrite
permission to saved object itself. It will throw permission error if not permitted. ThebulkUpdate
methods do the same things. It will check the passed saved objects one by one. - delete
For delete method, it will get the delete saved object first. If the delete saved object hasworkspaces
attribute, it will check if havelibrary_write
permissions to delete saved object's workspaces. If the user doesn't havelibrary_write
permission to these workspaces, it will check thewrite
permission of delete saved object. It will throw permission error if not permitted. - deleteByWorkspace
For deleteByWorkspace method, it will validate if user haslibrary_write
permission to passed workspace. If the user doesn't have this permission, it will throw permission error. If user has related permission, all the saved objects belongs to the workspace will be deleted.
Describe alternatives you've considered
N/A
Additional context
#5083
#5163
#4615