Model access control

You can use the Security plugin with ML Commons to manage access to specific models for non-admin users. For example, one department in an organization might want to restrict users in other departments from accessing their models.

To accomplish this, users are assigned one or more backend roles. Rather than assign individual roles to individual users during user configuration, backend roles provide a way to map a set of users to a role by assigning the backend role to users when they log in. For example, users may be assigned an IT backend role that includes the ml_full_access role and have full access to all ML Commons features. Alternatively, other users may be assigned an HR backend role that includes the ml_readonly_access role and be limited to read-only access to machine learning (ML) features. Given this flexibility, backend roles can provide finer-grained access to models and make it easier to assign multiple users to a role rather than mapping a user and role individually.

Model groups

For access control, models are organized into model groups—collections of versions of a particular model. Like users, model groups can be assigned one or more backend roles. All versions of the same model share the same model name and have the same backend role or roles.

You are considered a model owner when you create a new model group. You remain the owner of the model and all its versions even if another user registers a model to this model group. When a model owner creates a model group, the owner can specify one of the following access modes for this model group:

  • 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.

An admin can access all model groups in the cluster regardless of their access mode.

Model access control prerequisites

Before using model access control, you must satisfy the following prerequisites:

  1. Enable the Security plugin on your cluster. For more information, see Security in OpenSearch.
  2. For restricted model groups, ensure that an admin has assigned backend roles to users.
  3. Enable model access control on your cluster.

If any of the prerequisites are not met, all models in the cluster are public and can be accessed by any user who has access to the cluster.

Assigning backend roles to users

Create the appropriate backend roles and assign those roles to users. Backend roles usually come from an LDAP server or SAML provider, but if you use the internal user database, you can use the REST API to add them manually.

Only admin users can assign backend roles to users.

When assigning backend roles, consider the following example of two users: alice and bob.

The following request assigns the user alice the analyst backend role:

  1. PUT _plugins/_security/api/internalusers/alice
  2. {
  3. "password": "alice",
  4. "backend_roles": [
  5. "analyst"
  6. ],
  7. "attributes": {}
  8. }

The next request assigns the user bob the human-resources backend role:

  1. PUT _plugins/_security/api/internalusers/bob
  2. {
  3. "password": "bob",
  4. "backend_roles": [
  5. "human-resources"
  6. ],
  7. "attributes": {}
  8. }

Finally, the last request assigns both alice and bob the role that gives them full access to ML Commons:

  1. PUT _plugins/_security/api/rolesmapping/ml_full_access
  2. {
  3. "backend_roles": [],
  4. "hosts": [],
  5. "users": [
  6. "alice",
  7. "bob"
  8. ]
  9. }

If alice creates a model group and assigns it the analyst backend role, bob cannot access this model.

Enabling model access control

You can enable model access control dynamically as follows:

  1. PUT _cluster/settings
  2. {
  3. "transient": {
  4. "plugins.ml_commons.model_access_control_enabled": "true"
  5. }
  6. }

copy

Registering a model group

To register a model group, send a POST request to the _register endpoint. You can register a model group in public, private, or restricted access mode.

Each model group name in the cluster must be globally unique.

Path and HTTP method

  1. POST /_plugins/_ml/model_groups/_register

Request fields

The following table lists the available request fields.

FieldData typeDescription
nameStringThe model group name. Required.
descriptionStringThe model group description. Optional.
access_modeStringThe access mode for this model. Valid values are public, private, and restricted. When this parameter is set to restricted, you must specify either backend_roles or add_all_backend_roles, but not both. Optional. If you specify none of the security parameters (access_mode, backend_roles, and add_all_backend_roles), the default access_mode is private.
backend_rolesArrayA list of the model owner’s backend roles to add to the model. Can be specified only if access_mode is restricted. Cannot be specified at the same time as add_all_backend_roles. Optional.
add_all_backend_rolesBooleanIf 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.

Example request

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "test_model_group_public",
  4. "description": "This is a public model group",
  5. "access_mode": "public"
  6. }

copy

Example response

  1. {
  2. "model_group_id": "GDNmQ4gBYW0Qyy5ZcBcg",
  3. "status": "CREATED"
  4. }

Response fields

The following table lists the available response fields.

FieldData typeDescription
model_group_idStringThe model group ID that you can use to access this model group.
statusStringThe operation status.

Registering a public model group

If you register a model group with a public access mode, any model in this model group will be accessible to any user with access to the cluster. The following request registers a public model group:

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "test_model_group_public",
  4. "description": "This is a public model group",
  5. "access_mode": "public"
  6. }

copy

Registering a restricted model group

To limit access by backend role, you must register a model group with the restricted access mode.

When registering a model group, you must attach one or more of your backend roles to the model using one but not both of the following methods: - Provide a list of backend roles in the backend_roles parameter. - Set the add_all_backend_roles parameter to true to add all your backend roles to the model group. This option is not available to admin users.

Any user who shares a backend role with the model group can access any model in this model group. This grants the user the permissions included with the user role that is mapped to the backend role.

An admin user can access all model groups regardless of their access mode.

Example request: A list of backend roles

The following request registers a restricted model group, which can be accessed only by users with the IT backend role:

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "model_group_test",
  4. "description": "This is an example description",
  5. "access_mode": "restricted",
  6. "backend_roles" : ["IT"]
  7. }

copy

Example request: All backend roles

The following request registers a restricted model group, adding all backend roles of the user to the model group:

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "model_group_test",
  4. "description": "This is an example description",
  5. "access_mode": "restricted",
  6. "add_all_backend_roles": "true"
  7. }

copy

Registering a private model group

If you register a model group with a private access mode, any model in this model group will be accessible only to you and the admin users. The following request registers a private model group:

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "model_group_test",
  4. "description": "This is an example description",
  5. "access_mode": "private"
  6. }

copy

If you don’t specify any of the access_mode, backend_roles, or add_all_backend_roles, the model will have a private access mode:

  1. POST /_plugins/_ml/model_groups/_register
  2. {
  3. "name": "model_group_test",
  4. "description": "This is an example description"
  5. }

copy

Registering a model group in a cluster where model access control is disabled

If model access control is disabled on your cluster (one of the prerequisites is not met), you 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). By default, in such a cluster, all model groups are public.

Updating a model group

To update a model group, send a PUT request to the model_groups endpoint and provide the ID of the model group you want to update.

When updating a model group, the following restrictions apply:

  • The model owner or an admin user can update all fields. Any user who shares one or more backend roles with the model group can update the name and description fields only.
  • When updating the access_mode to restricted, you must specify either backend_roles or add_all_backend_roles but not both.
  • When updating the name, ensure the name is globally unique in the cluster.

Path and HTTP method

  1. PUT /_plugins/_ml/model_groups/<model_group_id>

Request fields

Refer to Request fields for request field descriptions.

Example request

  1. PUT /_plugins/_ml/model_groups/<model_group_id>
  2. {
  3. "name": "model_group_test",
  4. "description": "This is the updated description",
  5. "add_all_backend_roles": true
  6. }

copy

Updating a model group in a cluster where model access control is disabled

If model access control is disabled on your cluster (one of the prerequisites is not met), you can update only the name and description of a model group but cannot update any of the access parameters (model_access_name, backend_roles, or add_backend_roles).

Searching for a model group

When you search for a model group, only those model groups to which you have access will be returned. For example, for a match all query, model groups that will be returned are:

  • All public model groups in the index
  • Private model groups for which you are the owner
  • Model groups that share at least one of the backend_roles with you

Path and HTTP method

  1. POST /_plugins/_ml/model_groups/_search
  2. GET /_plugins/_ml/model_groups/_search

Example request: Match all

The following request is sent by user1 who has the IT and HR roles:

  1. POST /_plugins/_ml/model_groups/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "size": 1000
  7. }

copy

Example response

  1. {
  2. "took": 31,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 7,
  13. "relation": "eq"
  14. },
  15. "max_score": 1,
  16. "hits": [
  17. {
  18. "_index": ".plugins-ml-model-group",
  19. "_id": "TRqZfYgBD7s2oEFdvrQj",
  20. "_version": 1,
  21. "_seq_no": 2,
  22. "_primary_term": 1,
  23. "_score": 1,
  24. "_source": {
  25. "backend_roles": [
  26. "HR",
  27. "IT"
  28. ],
  29. "owner": {
  30. "backend_roles": [
  31. "HR",
  32. "IT"
  33. ],
  34. "custom_attribute_names": [],
  35. "roles": [
  36. "ml_full_access",
  37. "own_index",
  38. "test_ml"
  39. ],
  40. "name": "user1",
  41. "user_requested_tenant": "__user__"
  42. },
  43. "created_time": 1685734407714,
  44. "access": "restricted",
  45. "latest_version": 0,
  46. "last_updated_time": 1685734407714,
  47. "name": "model_group_test",
  48. "description": "This is an example description"
  49. }
  50. },
  51. {
  52. "_index": ".plugins-ml-model-group",
  53. "_id": "URqZfYgBD7s2oEFdyLTm",
  54. "_version": 1,
  55. "_seq_no": 3,
  56. "_primary_term": 1,
  57. "_score": 1,
  58. "_source": {
  59. "backend_roles": [
  60. "IT"
  61. ],
  62. "owner": {
  63. "backend_roles": [
  64. "HR",
  65. "IT"
  66. ],
  67. "custom_attribute_names": [],
  68. "roles": [
  69. "ml_full_access",
  70. "own_index",
  71. "test_ml"
  72. ],
  73. "name": "user1",
  74. "user_requested_tenant": "__user__"
  75. },
  76. "created_time": 1685734410470,
  77. "access": "restricted",
  78. "latest_version": 0,
  79. "last_updated_time": 1685734410470,
  80. "name": "model_group_test",
  81. "description": "This is an example description"
  82. }
  83. },
  84. ...
  85. ]
  86. }
  87. }

Example request: Search for model groups with an owner name

The following request to search for model groups of user is sent by user2 who has the IT backend role:

  1. GET /_plugins/_ml/model_groups/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "nested": {
  8. "query": {
  9. "term": {
  10. "owner.name.keyword": {
  11. "value": "user1",
  12. "boost": 1
  13. }
  14. }
  15. },
  16. "path": "owner",
  17. "ignore_unmapped": false,
  18. "score_mode": "none",
  19. "boost": 1
  20. }
  21. }
  22. ]
  23. }
  24. }
  25. }

copy

Example response

  1. {
  2. "took": 6,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 4,
  13. "relation": "eq"
  14. },
  15. "max_score": 0,
  16. "hits": [
  17. {
  18. "_index": ".plugins-ml-model-group",
  19. "_id": "TRqZfYgBD7s2oEFdvrQj",
  20. "_version": 1,
  21. "_seq_no": 2,
  22. "_primary_term": 1,
  23. "_score": 0,
  24. "_source": {
  25. "backend_roles": [
  26. "HR",
  27. "IT"
  28. ],
  29. "owner": {
  30. "backend_roles": [
  31. "HR",
  32. "IT"
  33. ],
  34. "custom_attribute_names": [],
  35. "roles": [
  36. "ml_full_access",
  37. "own_index",
  38. "test_ml"
  39. ],
  40. "name": "user1",
  41. "user_requested_tenant": "__user__"
  42. },
  43. "created_time": 1685734407714,
  44. "access": "restricted",
  45. "latest_version": 0,
  46. "last_updated_time": 1685734407714,
  47. "name": "model_group_test",
  48. "description": "This is an example description"
  49. }
  50. },
  51. ...
  52. ]
  53. }
  54. }

Example request: Search for model groups with a model group ID

  1. GET /_plugins/_ml/model_groups/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "terms": {
  8. "_id": [
  9. "HyPNK4gBwNxGowI0AtDk"
  10. ]
  11. }
  12. }
  13. ]
  14. }
  15. }
  16. }

copy

Example response

  1. {
  2. "took": 2,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 1,
  16. "hits": [
  17. {
  18. "_index": ".plugins-ml-model-group",
  19. "_id": "HyPNK4gBwNxGowI0AtDk",
  20. "_version": 3,
  21. "_seq_no": 16,
  22. "_primary_term": 5,
  23. "_score": 1,
  24. "_source": {
  25. "backend_roles": [
  26. "IT"
  27. ],
  28. "owner": {
  29. "backend_roles": [
  30. "",
  31. "HR",
  32. "IT"
  33. ],
  34. "custom_attribute_names": [],
  35. "roles": [
  36. "ml_full_access",
  37. "own_index",
  38. "test-ml"
  39. ],
  40. "name": "user1",
  41. "user_requested_tenant": null
  42. },
  43. "created_time": 1684362035938,
  44. "latest_version": 2,
  45. "last_updated_time": 1684362571300,
  46. "name": "model_group_test",
  47. "description": "This is an example description"
  48. }
  49. }
  50. ]
  51. }
  52. }

Deleting a model group

You can only delete a model group if it does not contain any model versions.

If model access control is enabled on your cluster, only the owner or users with matching backend roles can delete the model group. Any users can delete any public model group.

If model access control is disabled on your cluster, users with the delete model group API permission can delete any model group.

Admin users can delete any model group.

When you delete the last model version in a model group, that model group is automatically deleted from the index.

Example request

  1. DELETE _plugins/_ml/model_groups/<model_group_id>

copy

Example response

  1. {
  2. "_index": ".plugins-ml-model-group",
  3. "_id": "l8nnQogByXnLJ-QNpEk2",
  4. "_version": 5,
  5. "result": "deleted",
  6. "_shards": {
  7. "total": 2,
  8. "successful": 1,
  9. "failed": 0
  10. },
  11. "_seq_no": 70,
  12. "_primary_term": 23
  13. }