Skip to content
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

[Workspace] Add permission control logic for saved objects #6051

Closed
wanglam opened this issue Mar 6, 2024 · 1 comment · Fixed by #6052
Closed

[Workspace] Add permission control logic for saved objects #6051

wanglam opened this issue Mar 6, 2024 · 1 comment · Fixed by #6052
Labels
enhancement New feature or request workspace

Comments

@wanglam
Copy link
Contributor

wanglam commented Mar 6, 2024

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
    For create method, it will check if has library_write permission to passed workspaces when options.workspaces was provided. It will throw permission error if doesn't have permission. Since the create method can overwrite existing saved objects, it will validate permission if options.overwrite and options.id passed. It will try to get existing saved objects, and validate library_write permission to its workspaces or write permission to itself. It will throw permission error if not permitted. The bulkCreate permission validation logic was the very similar as create. The bulkCreate will do these permission validation logic for all passed saved objects.
  • get / bulkGet
    For get method, it will get saved object first. And then will check if has library_read or library_write permission to one of the saved object's workspaces. If it doesn't have permission, it will check the read or write permission on saved object. Then throw permission error if not permitted. The bulkGet method do the same thing for all passed saved objects.
  • find
    For find method, there are three different cases.
    The find method will check the options.type first. This is the case 1, for finding workspace type saved objects. It will assign the principals from request to the ACLSearchParams.principals and assign read or write to the ACLSearchParams.permissionModes too if not provided. This means find all workspace saved objects that user has read and write permission.
    If options.type was not provided, these are case 2 and case 3. For these two cases, need to get user permitted workspaces first.
    If options.workspaces provided, this is case 2. It will filter out not permitted workspaces in options.workspaces. This means find all permitted saved objects under permitted workspaces.
    If options.workspaces was not provided, it's case 3. It will assign request principals to options.ACLSearchParams.principals. Which means find all permitted saved objects based user passed permission modes.
  • update / bulkUpdate
    For update method, it will get passed saved objects first. Then it will check if has one of the library_write permission to saved objects's workspace or if has write permission to saved object itself. It will throw permission error if not permitted. The bulkUpdate 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 has workspaces attribute, it will check if have library_write permissions to delete saved object's workspaces. If the user doesn't have library_write permission to these workspaces, it will check the write permission of delete saved object. It will throw permission error if not permitted.
  • deleteByWorkspace
    For deleteByWorkspace method, it will validate if user has library_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

@wanglam wanglam added the enhancement New feature or request label Mar 6, 2024
@wanglam
Copy link
Contributor Author

wanglam commented Mar 6, 2024

A part of #4944

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request workspace
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants