From 06d58f26df2f8e1c2a4e595c20d15489ac0233ea Mon Sep 17 00:00:00 2001 From: Bhavana Ramaram Date: Thu, 8 Jun 2023 17:18:32 -0700 Subject: [PATCH] documentation corrections Signed-off-by: Bhavana Ramaram --- docs/model_access_control.md | 229 +++++++++++++++++++++++------------ 1 file changed, 154 insertions(+), 75 deletions(-) diff --git a/docs/model_access_control.md b/docs/model_access_control.md index 7495590fb8..fb80b49e96 100644 --- a/docs/model_access_control.md +++ b/docs/model_access_control.md @@ -1,6 +1,6 @@ # Model Access Control -In the present setting, on a security enabled OpenSearch cluster, we can limit users to certain actions by mapping them to relevant permissions and permission roles. For example, we may want some users to only search and view ml models while allow others to register and deploy them. +In the present setting, on a security enabled OpenSearch cluster, admin can limit users to certain actions by mapping them to relevant permissions and permission roles. For example, admin may want some users to only search and view ml models while allow others to register and deploy them. Currently, ml-commons has two pre-defined roles to manage permissions. For descriptions of each, see [Permissions](https://opensearch.org/docs/latest/ml-commons-plugin/index/#permissions). Users can also mix and match individual ml permissions to suit their use case, if these roles don’t meet their needs. Each action corresponds to an operation in the REST API. For example, the `cluster:admin/opensearch/ml/models/delete` permission lets the user delete models. @@ -10,7 +10,7 @@ So far, the ml-commons plugin did not have the concept of ownership. For example We have implemented backend role-based access in which members of the same back-end roles will be able to access each other’s resources. This is similar to alerting and anomaly detection plugin [backend role based access](https://opensearch.org/docs/latest/observing-your-data/alerting/security/#advanced-limit-access-by-backend-role). Additionally we also let users define an ml resource as public or private. This advanced security access is available only on a cluster with [Security plugin](https://opensearch.org/docs/latest/security/index/). Note: -- Model access control is experimental feature. If you see any bug or have any suggestion, feel free to cut Github issue. +- Model access control is an experimental feature. If you see any bug or have any suggestion, feel free to cut Github issue. @@ -49,11 +49,11 @@ When creating a model group, user should also specify the access mode to it. Dep If a user tries to register/deploy/undeploy/predict/delete/search/get model versions, first we check if the user has access to the model. Otherwise, we throw exception saying user does not have access to the model specified. -A user is considered a model _owner_ when he/she creates a new model group and register its first version. When a model owner creates a model group, the owner can specify one of the following _access modes_ for this model group: +The user who creates a model group will be considered the _model_owner_ of that group and all model versions in it, irrespective of who registers them to the model group. When a model owner creates a model group, the owner can specify one of the following _access modes_ for this model group which will be applied to all its versions: - `public`: All users who have access to the cluster can access this model group. - `private`: Only the model owner or an admin user can access this model group. -- `restricted`: The owner, an admin user, or any user who shares one of the model group's backend roles can access any model in this model group. When creating a `restricted` model group, the owner must attach one or more of the owner's backend roles to the model. For a user to be able to access a model group, one of the user's backend roles must match one of the model group's backend roles. This grants the user permissions associated with the user role to which that backend role is mapped. For example, if the backend role is mapped to the `ml_full_access` user role, users with this role can use the Register, Deploy, Predict, Delete, Search and Get Model APIs on any model in this model group. +- `restricted`: The owner, an admin user, or any user who shares one of the model group's backend roles can access any model in this model group. When creating a `restricted` model group, the owner must attach one or more of the owner's backend roles to the model. For a user to be able to access a model group, one of the user's backend roles must match one of the model group's backend roles. An admin can access all model groups in the cluster regardless of their access mode. @@ -61,7 +61,7 @@ An admin can access all model groups in the cluster regardless of their access m ## Registering a model group: -User should use the `_register` endpoint to register a model group. User can register a model group with a `public`, `private`, or `restricted` access mode. +User should use the `_register` API endpoint to register a model group. User can register a model group with a `public`, `private`, or `restricted` access mode. ### Path and HTTP method @@ -78,12 +78,12 @@ The following table lists the available request fields. | `name` | String | The model group name. Required. | | `description` | String | The model group description. Optional. | | `model_access_mode` | String | The access mode for this model. Valid values are `public`, `private`, and `restricted`. When this parameter is set to `restricted`, user must specify either `backend_roles` or `add_all_backend_roles`, but not both. Optional. Default is `restricted`. | -| `backend_roles` | Array | A list of the model owner's backend roles to add to the model. Can be specified only if the `model_access_mode` is `restricted`. Cannot be specified at the same time as `add_all_backend_roles`. Optional. | +| `backend_roles` | Array | A list of the model owner's backend roles to add to the model. Required only if the `model_access_mode` is `restricted`. Cannot be specified at the same time as `add_all_backend_roles`. Optional. | | `add_all_backend_roles` | Boolean | If `true`, all backend roles of the model owner are added to the model group. Default is `false`. Cannot be specified at the same time as `backend_roles`. Admin users cannot set this parameter to `true`. Optional. | ### Response fields -The following table lists the available request fields. +The following table lists the available response fields. | Field | Data type | Description | |:-----------------|:----------|:-----------------------------------------------------------------| @@ -111,9 +111,9 @@ POST /_plugins/_ml/model_groups/_register } ``` -- To create a restrcited Model Group: User should set `model_access_mode` field to `restricted` +- To create a restricted Model Group: User should set `model_access_mode` field to `restricted` -When registering a restricted model group, user must attach one or more of their backend roles to the model group using one but not both of the following methods: +When registering a restricted model group, user must attach one or more of their backend roles to the model group using one but not both of the following ways: 1. Provide a list of backend roles in the `backend_roles` parameter. 2. Set the `add_all_backend_roles` parameter to `true` to add all the backend roles of the user to the model group. This option is not available to admin users. @@ -121,8 +121,11 @@ Any user who shares one of the model group's backend roles can access any model An admin user can access all model groups regardless of their access mode. + ``` -POST /_plugins/_ml/model_groups/_register +//registering model group with backend_roles field + +POST /_plugins/_ml/model_groups/_register { "name": "model_group_test", "description": "This is an example description", @@ -132,6 +135,7 @@ POST /_plugins/_ml/model_groups/_register ``` ``` +//registering model group with add_all_backend_roles field POST /_plugins/_ml/model_groups/_register { "name": "model_group_test", @@ -153,24 +157,17 @@ POST /_plugins/_ml/model_groups/_register } ``` -### Exception cases - -- When a user is trying to specify more than one field of `addAllBackendRoles` or `backend_roles` fields to _public/private_ access mode like below, an exception will be thrown saying `You can specify backend roles only for a model group with the restricted access mode.` - -- When the user is _admin_ and specified `add_all_backend_roles` to true, there’ll be an exception: `Admin users cannot add all backend roles to a model group.` - -- When a user doesn’t have any backend roles and specified `add_all_backend_roles to true` and model_access_mode to _restricted_, there’ll be an exception: `You must have at least one backend role to register a restricted model group.` - -- When a user doesn’t specify either of `add_all_backend_roles` or `backend_roles` fields and set model_access_mode to _restricted_, there’ll be an exception: `You must specify one or more backend roles or add all backend roles to register a restricted model group.` - -- When a user specified both `add_all_backend_roles` and `backend_roles` and set model_access_mode to _restricted_, there’ll be an exception: `You cannot specify backend roles and add all backend roles at the same time` - -- When a user specified `backend_roles` and set model_access_mode to _restricted_, but the user doesn’t have all the backend_roles specified, there’ll be an exception: `You cannot specify backend roles and add all backend roles at the same time` - ### Note -- If security or `model_access_control_enabled` setting is disabled in the cluster, every user is null and by default, in such cluster, all model groups are public. User can register a model group with a `name` and `description` but cannot specify any of the access parameters (`model_access_name`, `backend_roles`, or `add_backend_roles`). An exception will be thrown if the request has any access control related fields in the input: `You cannot specify model access control parameters because Security plugin or model access control is disabled on your cluster.` - +- If security or `model_access_control_enabled` setting is disabled in the cluster, every user is null and by default, in such cluster, all model groups are public. User can register a model group with a `name` and `description` but cannot specify any of the access parameters (`model_access_name`, `backend_roles`, or `add_backend_roles`). +#### Sample request +``` +POST /_plugins/_ml/model_groups/_register +{ + "name": "model_group_test", + "description": "This is an example description" +} +``` ## Updating a model group @@ -181,26 +178,20 @@ Updating a model group request is very similar to register model group request. ### Path and HTTP method ``` -PUT /_plugins/_ml/model_groups/_update +PUT /_plugins/_ml/model_groups//_update ``` -* A user can make updates to a model group to which he/she has access which is determined by the access mode of the model group. -* In a model_access_control enabled cluster, the model group owner or an admin user can update all fields. Whereas, any other user who shares one or more backend roles with the model group can update the `name` and `description` fields only. -* In a security/model_access_control disabled cluster, any user can make updates to any model group but cannot specify any of the access fields. +A user can make updates to a model group to which he/she has access which is determined by the access mode of the model group. + +On a _model_access_control_ enabled cluster, the model group owner or an admin user can update all fields. Whereas, any other user who shares one or more backend roles with the model group can update the `name` and `description` fields only. + +On a security/model_access_control disabled cluster, any user can make updates to any model group but cannot specify any of the access fields. + +For example, * Consider a model group created by User1 with IT backend_role set to it. Since user1 is the owner, he/she will be able to update all the fields of the model group. * If User2 tries to send update request to the same model group, only name, and description will be allowed to be updated but not other fields because user2 has access to the model group but is not the owner/admin. * If User3 tries to send update request, exception will be thrown because user3 has no matching backend_roles of the model group and therefore has no access to it at all. -Similar to registering, there are other checks for updating a model group. - -* When model_access_mode is set to _restricted/null_ and admin user specified `add_all_backend_roles` to true, there’ll be an exception: `Admin users cannot add all backend roles to a model group.` -* When model_access_mode is set to _public/private_ and user specified `backend_roles` or set `add_all_backend_roles` to true, there’ll be an exception: `You can specify backend roles only for a model group with restricted access mode.` -* When model_access_mode is set to _restricted/null_ and `add_all_backend_roles` to true but the user doesn’t have any backend roles, there’ll be an exception: `You don’t have any backend roles.` -* When model_access_mode is set to _restricted/null_ and set `add_all_backend_roles` to false but did not specify `backend_roles` field, there’ll be an exception: `You must specify at least one backend role to update a restricted model group.` -* When model_access_mode is set to _restricted/null_ and set `add_all_backend_roles` to true and also specified `backend_roles`, there’ll be an exception: `You cannot specify backend roles and add all backend roles at the same time.` -* When model_access_mode is set to _restricted/null_ and specified `backend_roles` that do not belong to this user, there’ll be an exception: `You don't have the backend roles specified.` -* When owner’s backend roles changed and the owner doesn’t have any backend roles specified in the model’s backend_roles, and when the owner attempting to update the model, there’ll be an exception: `You don’t have the backend role to perform this operation. For more information, contact your administrator.` - Sample request allowed by admin/owner @@ -239,8 +230,6 @@ PUT /_plugins/_ml/model_groups//_update ``` - - ## Searching for a model group When user searches for a model group, only those model groups to which user has access will be returned. For example, for a match all query, model groups that will be returned are: @@ -521,10 +510,7 @@ GET /_plugins/_ml/model_groups/_search "latest_version": 2, "last_updated_time": 1684362571300, "name": "model_group_test", - "description": "This is an example description", - "tags": { - "key1": "value1", - "key2": "value2" + "description": "This is an example description" } } } @@ -537,12 +523,12 @@ GET /_plugins/_ml/model_groups/_search ## Deleting a model group -A user can only delete model group if it does not have any model versions in it. Otherwise an exception will be thrown: `Cannot delete the model group when it has associated model versions` +A user can only delete model group if it does not have any model versions in it. * On a model_access_control enabled cluster, only owner or users with matching backend roles can delete a restricted model group. * Users can also delete any public model group if they have delete model_group API permission. -* For a private model group, only owner or the admin can delete them. -* Admin can delete any model group +* For a private model group, only owner or the admin can delete it. +* Admin can delete any model group in the cluster. * On a security/model_access_control disabled cluster, a user with delete model_group API permission can delete any model group @@ -574,11 +560,15 @@ DELETE _plugins/_ml/model_groups/ ## Registering a model version to a model group: -Register model version will have same old path and all the old fields. Additionally, user should specify the `model_group_id` for registering a new version to a model group. If the model group id is null, an exception will be thrown +Register model version API would have same old path and all the old fields. For information on register version API, please refer: [Registering a model] (https://opensearch.org/docs/latest/ml-commons-plugin/api/#registering-a-model) + +Additionally, user should specify the `model_group_id` for registering a new version to a model group. If the model group id is null, an exception will be thrown. + +Everytime a new model is registered to a model group, it is assigned a new version number automatically. Hence, user need not specify the version field while registering a model version. On a model_access_control enabled cluster: -* only owner or users who have atleast one of their backend roles matching with that of a model group's can register a new version to a restricted model group. -* users can also register a version to any public model group if they have register model permission. +* To register a new version to a restricted model group, only owner or users with atleast one of their backend roles matching with that of the model group will be allowed. +* For a public model group, any user can register a new version if they have register model permission. * For a private model group, only the owner or the admin can register a new version. * Admin can register model versions to any model group @@ -586,30 +576,19 @@ On a security/model_access_control disabled cluster, * a user with register model permission can register a new version to any model group. For example: -* For a model group created by User1 with IT backend_role, only user1, user2, and admin can register new versions. If user3 and user4 try to register, an exception will be thrown: `You don't have permissions to perform this operation on this model.` +* For a model group created by User1 with IT backend_role, only User1, User2, and admin can register new versions. User3 and User4 cannot register/access versions of this model group * For a private model group of User1, only User1 or admin will be able to create new versions. For any other user, above exception will be thrown. -* For a public model group of User1, any user can access register a version. +* For a public model group of User1, any user can register a version. -#### Example Request: Registering a model version via URL +#### Example Request: Registering a model version using a pre-trained model ``` POST /_plugins/_ml/models/_register - { - "name": "all-MiniLM-L6-v2", - "version": "1.0.0", - "description": "test model", - "model_format": "TORCH_SCRIPT", - "model_group_id": "FTNlQ4gBYW0Qyy5ZoxfR", - "model_content_hash_value": "9376c2ebd7c83f99ec2526323786c348d2382e6d86576f750c89ea544d6bbb14", - "model_config": { - "model_type": "bert", - "embedding_dimension": 384, - "framework_type": "sentence_transformers", - "all_config": "{\"_name_or_path\":\"nreimers/MiniLM-L6-H384-uncased\",\"architectures\":[\"BertModel\"],\"attention_probs_dropout_prob\":0.1,\"gradient_checkpointing\":false,\"hidden_act\":\"gelu\",\"hidden_dropout_prob\":0.1,\"hidden_size\":384,\"initializer_range\":0.02,\"intermediate_size\":1536,\"layer_norm_eps\":1e-12,\"max_position_embeddings\":512,\"model_type\":\"bert\",\"num_attention_heads\":12,\"num_hidden_layers\":6,\"pad_token_id\":0,\"position_embedding_type\":\"absolute\",\"transformers_version\":\"4.8.2\",\"type_vocab_size\":2,\"use_cache\":true,\"vocab_size\":30522}" - }, - "url": "https://github.com/ylwu-amzn/ml-commons/blob/2.x_custom_m_helper/ml-algorithms/src/test/resources/org/opensearch/ml/engine/algorithms/text_embedding/all-MiniLM-L6-v2_torchscript_sentence-transformer.zip?raw=true" + "name": "huggingface/sentence-transformers/all-MiniLM-L12-v2" + "model_format": "TORCH_SCRIPT", + "model_group_id": "FTNlQ4gBYW0Qyy5ZoxfR", } ``` @@ -625,8 +604,10 @@ POST /_plugins/_ml/models/_register ## Deploy/Undeploy/Predict/Delete/Get model version +No change to these API requests. User would send the same old requests to perform deploy/undeploy/predict/delete/get actions. For information on these APIs, please refer: https://opensearch.org/docs/latest/ml-commons-plugin/api/ + On a model_access_control enabled cluster: -* only owner or users who have atleast one of their backend roles matching with that of a model version can perform deploy/undeploy/predict/delete/get actions on it. +* For the versions in a restricted model group, only owner or users with atleast one of their backend roles matching with that of the model group can perform deploy/undeploy/predict/delete/get actions. * users can also perform the said actions on any version that belongs to a public model group. * For a private model version, only its owner or the admin can perform these actions. * Admin can perform all these actions on any model version in the cluster @@ -634,11 +615,6 @@ On a model_access_control enabled cluster: On a security/model_access_control disabled cluster, * a user can perform the actions to which they have permissions to on any model version. -For example: -* For model versions registered in a model group created by User1 with IT backend_role, only user1, user2 and admin can perform the above actions. If user3 and user4 try to send a request, an exception will be thrown: `You don't have permissions to perform this operation on this model.` -* For model versions registered in a private model group of User1, only User1 or admin will be able to perform the above actions on its versions. For any other user, above exception will be thrown. -* For a public model group of User1, any user can perform the said actions its versions. - @@ -650,3 +626,106 @@ For eg, for a match all query, model versions that will be returned are those fr * private model groups of the user sending the request, and * model groups with atleast one of the backend_roles of the user sending the request. +#### Example request: Searching model versions of a model group + +``` +GET /_plugins/_ml/models/_search +GET /_plugins/_ml/model_groups/_search +{ + "query": { + "bool": { + "must": [ + { + "terms": { + "model_group_id": [ + "yWvOnIgBKIpucFbpn7v5" + ] + } + } + ] + } + } +} +``` + +``` +# Response +{ + "took": 5, + "timed_out": false, + "_shards": { + "total": 1, + "successful": 1, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": { + "value": 2, + "relation": "eq" + }, + "max_score": 2, + "hits": [ + { + "_index": ".plugins-ml-model", + "_id": "zmvOnIgBKIpucFbp6bva", + "_version": 2, + "_seq_no": 10, + "_primary_term": 1, + "_score": 2, + "_source": { + "model_version": "1", + "created_time": 1686257985929, + "model_format": "TORCH_SCRIPT", + "description": "test model", + "model_state": "REGISTERED", + "total_chunks": 9, + "model_content_hash_value": "9376c2ebd7c83f99ec2526323786c348d2382e6d86576f750c89ea544d6bbb14", + "model_config": { + "all_config": """{"_name_or_path":"nreimers/MiniLM-L6-H384-uncased","architectures":["BertModel"],"attention_probs_dropout_prob":0.1,"gradient_checkpointing":false,"hidden_act":"gelu","hidden_dropout_prob":0.1,"hidden_size":384,"initializer_range":0.02,"intermediate_size":1536,"layer_norm_eps":1e-12,"max_position_embeddings":512,"model_type":"bert","num_attention_heads":12,"num_hidden_layers":6,"pad_token_id":0,"position_embedding_type":"absolute","transformers_version":"4.8.2","type_vocab_size":2,"use_cache":true,"vocab_size":30522}""", + "model_type": "bert", + "embedding_dimension": 384, + "framework_type": "SENTENCE_TRANSFORMERS" + }, + "last_updated_time": 1686257992344, + "last_registered_time": 1686257992336, + "name": "all-MiniLM-L6-v2", + "model_group_id": "yWvOnIgBKIpucFbpn7v5", + "model_content_size_in_bytes": 83408741, + "algorithm": "TEXT_EMBEDDING" + } + }, + { + "_index": ".plugins-ml-model", + "_id": "2WvPnIgBKIpucFbpnbtt", + "_version": 2, + "_seq_no": 21, + "_primary_term": 1, + "_score": 2, + "_source": { + "model_version": "2", + "created_time": 1686258031981, + "model_format": "TORCH_SCRIPT", + "description": "test model", + "model_state": "REGISTERED", + "total_chunks": 9, + "model_content_hash_value": "9376c2ebd7c83f99ec2526323786c348d2382e6d86576f750c89ea544d6bbb14", + "model_config": { + "all_config": """{"_name_or_path":"nreimers/MiniLM-L6-H384-uncased","architectures":["BertModel"],"attention_probs_dropout_prob":0.1,"gradient_checkpointing":false,"hidden_act":"gelu","hidden_dropout_prob":0.1,"hidden_size":384,"initializer_range":0.02,"intermediate_size":1536,"layer_norm_eps":1e-12,"max_position_embeddings":512,"model_type":"bert","num_attention_heads":12,"num_hidden_layers":6,"pad_token_id":0,"position_embedding_type":"absolute","transformers_version":"4.8.2","type_vocab_size":2,"use_cache":true,"vocab_size":30522}""", + "model_type": "bert", + "embedding_dimension": 384, + "framework_type": "SENTENCE_TRANSFORMERS" + }, + "last_updated_time": 1686258035386, + "last_registered_time": 1686258035385, + "name": "all-MiniLM-L6-v2", + "model_group_id": "yWvOnIgBKIpucFbpn7v5", + "model_content_size_in_bytes": 83408741, + "algorithm": "TEXT_EMBEDDING" + } + } + ] + } +} +``` +