---
type: api
title: Create or update roles
description: **All methods and paths for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch-serverless/operation/operation-security-put-role
resource: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch-serverless/operation/operation-security-put-role
products:
  - Elasticsearch Serverless
---

# Create or update roles


Availability:

## Paths

- `POST` (also `PUT`) `/_security/role/{name}`

- [Api key auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch-serverless/authentication#apikeyauth)

#### Path Parameters

- `name` (string Name)
  The name of the role that is being created or updated. On Elasticsearch Serverless, the role name must begin with a letter or digit and can only contain letters, digits and the characters '_', '-', and '.'. Each role must have a unique name, as this will serve as the identifier for that role.

## Description

The role management APIs are generally the preferred way to manage roles in the native realm, rather than using file-based role management.
The create or update roles API cannot update roles that are defined in roles files.
File-based role management is not available in Elastic Serverless.

## Required authorization

* Cluster privileges: `manage_security`

[More about defining roles](https://www.elastic.co/docs/deploy-manage/users-roles/cluster-or-deployment-auth/defining-roles)

## Query String Parameters

- `refresh` (enum Refresh)
  If `true` (the default) then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` then do nothing with refreshes.
  Values: `true`, `false`, `wait_for`

## Request Body

`application/json`

- `applications` ([] ApplicationPrivileges) — optional
  A list of application privilege entries.
  - `application` (string) — required
    The name of the application to which this entry applies.
  - `privileges` ([] string) — required
    A list of strings, where each element is the name of an application privilege or action.
  - `resources` ([] string) — required
    A list resources to which the privileges are applied.
- `cluster` ([] union ClusterPrivilege) — optional
  A list of cluster privileges. These privileges define the cluster-level actions for users with this role.
  Values: `all`, `cancel_task`, `manage`, `manage_api_key`, `manage_behavioral_analytics`, `manage_enrich`, `manage_esql`, `manage_index_templates`, `manage_inference`, `manage_ingest_pipelines`, `manage_logstash_pipelines`, `manage_ml`, `manage_own_api_key`, `manage_pipeline`, `manage_reindex`, `manage_search_application`, `manage_search_query_rules`, `manage_search_synonyms`, `manage_security`, `manage_transform`, `monitor`, `monitor_enrich`, `monitor_esql`, `monitor_inference`, `monitor_ml`, `monitor_reindex`, `monitor_transform`, `none`, `post_behavioral_analytics_event`, `read_pipeline`, `read_security`, `read_project_routing`, `manage_project_routing`
- `indices` ([] IndicesPrivileges) — optional
  A list of indices permissions entries.
  - `field_security` ({} FieldSecurity) — optional
    The document fields that the owners of the role have read access to.
    - `except` (string Fields) — optional
    - `grant` (string Fields) — optional
  - `names` (union IndexName | [] IndexName) — required
    A list of indices (or index name patterns) to which the permissions in this entry apply.
  - `privileges` ([] union IndexPrivilege) — required
    The index level privileges that owners of the role have on the specified indices.
    Values: `all`, `auto_configure`, `create`, `create_doc`, `create_index`, `create_view`, `delete`, `delete_index`, `delete_view`, `index`, `maintenance`, `manage`, `manage_data_stream_lifecycle`, `manage_view`, `monitor`, `none`, `read`, `read_view_metadata`, `view_index_metadata`, `write`
  - `query` (IndicesPrivilegesQuery) — optional
    A search query that defines the documents the owners of the role have access to. A document within the specified indices must match this query for it to be accessible by the owners of the role.
- `metadata` (Metadata) — optional
  Optional metadata. Within the metadata object, keys that begin with an underscore (`_`) are reserved for system use.
- `run_as` ([] string) — optional
  A list of users that the owners of this role can impersonate. *Note*: in Serverless, the run-as feature is disabled. For API compatibility, you can still specify an empty `run_as` field, but a non-empty list will be rejected.
- `description` (string) — optional
  Optional description of the role descriptor
- `transient_metadata` (map string to object) — optional
  Indicates roles that might be incompatible with the current cluster license, specifically roles with document and field level security. When the cluster license doesn’t allow certain features for a given role, this parameter is updated dynamically to list the incompatible features. If `enabled` is `false`, the role is ignored, but is still listed in the response from the authenticate API.

## Response

`application/json`

- `role` ({} CreatedStatus)
  When an existing role is updated, `created` is set to `false`.
  - `created` (boolean)
## Code Examples

#### Console

```console
POST /_security/role/my_admin_role
{
  "description": "Grants full access to all management features within the cluster.",
  "cluster": ["all"],
  "indices": [
    {
      "names": [ "index1", "index2" ],
      "privileges": ["all"],
      "field_security" : { // optional
        "grant" : [ "title", "body" ]
      },
      "query": "{\"match\": {\"title\": \"foo\"}}" // optional
    }
  ],
  "applications": [
    {
      "application": "myapp",
      "privileges": [ "admin", "read" ],
      "resources": [ "*" ]
    }
  ],
  "run_as": [ "other_user" ], // optional
  "metadata" : { // optional
    "version" : 1
  }
}
```

#### JavaScript

```javascript
const response = await client.security.putRole({
  name: "my_admin_role",
  description:
    "Grants full access to all management features within the cluster.",
  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,
  },
});
```

#### Python

```python
resp = client.security.put_role(
    name="my_admin_role",
    description="Grants full access to all management features within the cluster.",
    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
    },
)
```

#### curl

```curl
curl -X POST "$ELASTICSEARCH_URL/_security/role/my_admin_role" \
  -H "Authorization: ApiKey $ELASTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Grants full access to all management features within the cluster.",
    "cluster": [
      "all"
    ],
    "indices": [
      {
        "names": [
          "index1",
          "index2"
        ],
        "privileges": [
          "all"
        ],
        "field_security": {
          "grant": [
            "title",
            "body"
          ]
        },
        "query": "{\u0022match\u0022: {\u0022title\u0022: \u0022foo\u0022}}"
      }
    ],
    "applications": [
      {
        "application": "myapp",
        "privileges": [
          "admin",
          "read"
        ],
        "resources": [
          "*"
        ]
      }
    ],
    "run_as": [
      "other_user"
    ],
    "metadata": {
      "version": 1
    }
  }'
```

#### Java

```java
client.security().putRole(p -> p
    .applications(a -> a
        .application("myapp")
        .privileges(List.of("admin","read"))
        .resources("*")
    )
    .cluster("all")
    .description("Grants full access to all management features within the cluster.")
    .indices(i -> i
        .fieldSecurity(f -> f
            .grant(List.of("title","body"))
        )
        .names(List.of("index1","index2"))
        .privileges("all")
        .query(q -> q
            .match(m -> m
                .field("title")
                .query(FieldValue.of("foo"))
            )
        )
    )
    .metadata("version", JsonData.fromJson("1"))
    .name("my_admin_role")
    .runAs("other_user")
);
```

#### C#

```c#
var response = await client.Security
    .PutRoleAsync(name: "my_admin_role", d1 => d1
        .Applications(d2 => d2
            .Application("myapp")
            .Privileges("admin", "read")
            .Resources("*")
        )
        .Cluster(ClusterPrivilege.All)
        .Description("Grants full access to all management features within the cluster.")
        .Indices(d2 => d2
            .FieldSecurity(d3 => d3
                .Grant(x => x.Title, x => x.Body)
            )
            .Names(["index1", "index2"])
            .Privileges(IndexPrivilege.All)
            .Query("{\"match\": {\"title\": \"foo\"}}")
        )
        .Metadata(new Dictionary<string, object>()
        {
            { "version", 1 }
        })
        .RunAs("other_user")
    );
```

#### PHP

```php
$resp = $client->security()->putRole([
    "name" => "my_admin_role",
    "body" => [
        "description" => "Grants full access to all management features within the cluster.",
        "cluster" => array(
            "all",
        ),
        "indices" => array(
            [
                "names" => array(
                    "index1",
                    "index2",
                ),
                "privileges" => array(
                    "all",
                ),
                "field_security" => [
                    "grant" => array(
                        "title",
                        "body",
                    ),
                ],
                "query" => "{\"match\": {\"title\": \"foo\"}}",
            ],
        ),
        "applications" => array(
            [
                "application" => "myapp",
                "privileges" => array(
                    "admin",
                    "read",
                ),
                "resources" => array(
                    "*",
                ),
            ],
        ),
        "run_as" => array(
            "other_user",
        ),
        "metadata" => [
            "version" => 1,
        ],
    ],
]);
```

#### Ruby

```ruby
response = client.security.put_role(
  name: "my_admin_role",
  body: {
    "description": "Grants full access to all management features within the cluster.",
    "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
    }
  }
)
```

## Response Examples

#### Security put role response example1

A successful response from `POST /_security/role/my_admin_role`.

```json
{
  "role": {
    "created": true 
  }
}
```

