Bulk create or update roles API

edit

Bulk create or update roles API

edit

This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.

Bulk adds and updates roles in the native realm.

Request

edit

POST /_security/role/

Prerequisites

edit
  • To use this API, you must have at least the manage_security cluster privilege.

Description

edit

The role management APIs are generally the preferred way to manage roles, rather than using file-based role management. The bulk create or update roles API cannot update roles that are defined in roles files.

Path parameters

edit
refresh
Optional setting of the refresh policy for the write request. Defaults to Immediate.

Request body

edit

The following parameters can be specified in the body of a POST request and pertain to adding a set of roles:

roles
(object) The roles to add as a role name to role map.
<role_name> (required)
(string) The role name.
applications

(list) A list of application privilege entries.

application (required)
(string) The name of the application to which this entry applies.
privileges
(list) A list of strings, where each element is the name of an application privilege or action.
resources
(list) A list resources to which the privileges are applied.
cluster
(list) A list of cluster privileges. These privileges define the cluster level actions that users with this role are able to execute.
global
(object) An object defining global privileges. A global privilege is a form of cluster privilege that is request-aware. Support for global privileges is currently limited to the management of application privileges.
indices

(list) A list of indices permissions entries.

field_security
(object) The document fields that the owners of the role have read access to. For more information, see Setting up field and document level security.
names (required)
(list) A list of indices (or index name patterns) to which the permissions in this entry apply.
privileges(required)
(list) The index level privileges that the owners of the role have on the specified indices.
query
A search query that defines the documents the owners of the role have read access to. A document within the specified indices must match this query in order for it to be accessible by the owners of the role.
metadata
(object) Optional meta-data. Within the metadata object, keys that begin with _ are reserved for system usage.
run_as
(list) A list of users that the owners of this role can impersonate. For more information, see Submitting requests on behalf of other users.
remote_indices

[beta] This functionality is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features. (list) A list of remote indices permissions entries.

Remote indices are effective for remote clusters configured with the API key based model. They have no effect for remote clusters configured with the certificate based model.

clusters (required)
(list) A list of cluster aliases to which the permissions in this entry apply.
field_security
(object) The document fields that the owners of the role have read access to. For more information, see Setting up field and document level security.
names (required)
(list) A list of indices (or index name patterns) on the remote clusters (specified with clusters) to which the permissions in this entry apply.
privileges(required)
(list) The index level privileges that the owners of the role have on the specified indices.
query
A search query that defines the documents the owners of the role have read access to. A document within the specified indices must match this query in order for it to be accessible by the owners of the role.

For more information, see Defining roles.

Examples

edit

The following example adds the roles called my_admin_role and my_user_role:

resp = client.security.bulk_put_role(
    roles={
        "my_admin_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1",
                        "index2"
                    ],
                    "privileges": [
                        "all"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        },
        "my_user_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1"
                    ],
                    "privileges": [
                        "read"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        }
    },
)
print(resp)
const response = await client.security.bulkPutRole({
  roles: {
    my_admin_role: {
      cluster: ["all"],
      indices: [
        {
          names: ["index1", "index2"],
          privileges: ["all"],
          field_security: {
            grant: ["title", "body"],
          },
          query: '{"match": {"title": "foo"}}',
        },
      ],
      applications: [
        {
          application: "myapp",
          privileges: ["admin", "read"],
          resources: ["*"],
        },
      ],
      run_as: ["other_user"],
      metadata: {
        version: 1,
      },
    },
    my_user_role: {
      cluster: ["all"],
      indices: [
        {
          names: ["index1"],
          privileges: ["read"],
          field_security: {
            grant: ["title", "body"],
          },
          query: '{"match": {"title": "foo"}}',
        },
      ],
      applications: [
        {
          application: "myapp",
          privileges: ["admin", "read"],
          resources: ["*"],
        },
      ],
      run_as: ["other_user"],
      metadata: {
        version: 1,
      },
    },
  },
});
console.log(response);
POST /_security/role
{
    "roles": {
        "my_admin_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1",
                        "index2"
                    ],
                    "privileges": [
                        "all"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        },
        "my_user_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1"
                    ],
                    "privileges": [
                        "read"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        }
    }
}

A successful call returns a JSON structure that shows whether the role has been created, updated, or had no changes made.

{
    "created": [ 
        "my_admin_role", 
        "my_user_role"
    ]
}

Result type, one of created, updated, noop, errors.

A list of the roles that were created.

Because errors are handled individually for each role create or update, the API allows partial success.

The following query would throw an error for my_admin_role because the privilege bad_cluster_privilege doesn’t exist, but would be successful for the my_user_role.

resp = client.security.bulk_put_role(
    roles={
        "my_admin_role": {
            "cluster": [
                "bad_cluster_privilege"
            ],
            "indices": [
                {
                    "names": [
                        "index1",
                        "index2"
                    ],
                    "privileges": [
                        "all"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        },
        "my_user_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1"
                    ],
                    "privileges": [
                        "read"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        }
    },
)
print(resp)
const response = await client.security.bulkPutRole({
  roles: {
    my_admin_role: {
      cluster: ["bad_cluster_privilege"],
      indices: [
        {
          names: ["index1", "index2"],
          privileges: ["all"],
          field_security: {
            grant: ["title", "body"],
          },
          query: '{"match": {"title": "foo"}}',
        },
      ],
      applications: [
        {
          application: "myapp",
          privileges: ["admin", "read"],
          resources: ["*"],
        },
      ],
      run_as: ["other_user"],
      metadata: {
        version: 1,
      },
    },
    my_user_role: {
      cluster: ["all"],
      indices: [
        {
          names: ["index1"],
          privileges: ["read"],
          field_security: {
            grant: ["title", "body"],
          },
          query: '{"match": {"title": "foo"}}',
        },
      ],
      applications: [
        {
          application: "myapp",
          privileges: ["admin", "read"],
          resources: ["*"],
        },
      ],
      run_as: ["other_user"],
      metadata: {
        version: 1,
      },
    },
  },
});
console.log(response);
POST /_security/role
{
    "roles": {
        "my_admin_role": {
            "cluster": [
                "bad_cluster_privilege"
            ],
            "indices": [
                {
                    "names": [
                        "index1",
                        "index2"
                    ],
                    "privileges": ["all"],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        },
        "my_user_role": {
            "cluster": [
                "all"
            ],
            "indices": [
                {
                    "names": [
                        "index1"
                    ],
                    "privileges": [
                        "read"
                    ],
                    "field_security": {
                        "grant": [
                            "title",
                            "body"
                        ]
                    },
                    "query": "{\"match\": {\"title\": \"foo\"}}"
                }
            ],
            "applications": [
                {
                    "application": "myapp",
                    "privileges": [
                        "admin",
                        "read"
                    ],
                    "resources": [
                        "*"
                    ]
                }
            ],
            "run_as": [
                "other_user"
            ],
            "metadata": {
                "version": 1
            }
        }
    }
}

The result would then have the errors field set to true and hold the error for the my_admin_role update.

{
    "created": [
        "my_user_role" 
    ],
    "errors": { 
        "count": 1, 
        "details": {
            "my_admin_role": { 
                "type": "action_request_validation_exception",
                "reason": "Validation Failed: 1: unknown cluster privilege [bad_cluster_privilege]. a privilege must be either one of the predefined cluster privilege names [manage_own_api_key,manage_data_stream_global_retention,monitor_data_stream_global_retention,none,cancel_task,cross_cluster_replication,cross_cluster_search,delegate_pki,grant_api_key,manage_autoscaling,manage_index_templates,manage_logstash_pipelines,manage_oidc,manage_saml,manage_search_application,manage_search_query_rules,manage_search_synonyms,manage_service_account,manage_token,manage_user_profile,monitor_connector,monitor_enrich,monitor_inference,monitor_ml,monitor_rollup,monitor_snapshot,monitor_text_structure,monitor_watcher,post_behavioral_analytics_event,read_ccr,read_connector_secrets,read_fleet_secrets,read_ilm,read_pipeline,read_security,read_slm,transport_client,write_connector_secrets,write_fleet_secrets,create_snapshot,manage_behavioral_analytics,manage_ccr,manage_connector,manage_enrich,manage_ilm,manage_inference,manage_ml,manage_rollup,manage_slm,manage_watcher,monitor_data_frame_transforms,monitor_transform,manage_api_key,manage_ingest_pipelines,manage_pipeline,manage_data_frame_transforms,manage_transform,manage_security,monitor,manage,all] or a pattern over one of the available cluster actions;"
            }
        }
    }
}

The successfully created role.

The errors encountered.

The number of put role requests that resulted in an error.

The error keyed by role name.