﻿---
title: Create API keys for Elastic Agent Builder
description: Create API keys with the privileges required to access Agent Builder APIs, MCP clients, and A2A clients.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/explore-analyze/ai-features/agent-builder/api-keys
products:
  - Elastic Cloud Serverless
  - Elastic Observability
  - Elastic Security
  - Elasticsearch
  - Kibana
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available since 9.3, Preview in 9.2
---

# Create API keys for Elastic Agent Builder
Use an API key to authenticate applications that call Elastic Agent Builder programmatically, including custom clients, scripts that use `curl`, [MCP clients](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/explore-analyze/ai-features/agent-builder/mcp-server), and [A2A clients](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/explore-analyze/ai-features/agent-builder/a2a-server).
API keys use the same Kibana feature privileges as roles. The role management UI displays names such as **Agent Builder: Read**, while an API key role descriptor uses the corresponding application privilege name, such as `feature_agentBuilder.read`.

## Before you begin

Before creating an API key:
- Make sure the user creating the key has the `manage_api_key` or `manage_own_api_key` cluster privilege.
- Create the key as a user, not by authenticating the request with another API key. An API key can create only a derived key with no privileges.
- Make sure the user creating the key has every privilege that you assign to the key. An API key cannot grant more privileges than its owner has.
- Identify the Kibana [space](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/deploy-manage/manage-spaces) that the client will access. The examples use the default space.
- Identify the index patterns that agents and tools need to query. Replace `customer-*` in the examples with your own patterns.
- Determine whether agents use Elasticsearch inference endpoints, Kibana connectors, or workflows. These features require additional privileges.
- Refer to the [privilege reference](/elastic/docs-content/pull/7388/explore-analyze/ai-features/agent-builder/permissions#privilege-reference) for the exact privilege names to use in a role descriptor.
- If you're using `curl`, set the Elasticsearch URL, Kibana URL, and username:
  ```bash
  export ELASTICSEARCH_URL="https://<elasticsearch-host>" 
  export KIBANA_URL="https://<kibana-host>" 
  export ELASTIC_USERNAME="<username>" 
  ```


## Create a read-only client key

The following example creates a key for a client that can use agents and view Elastic Agent Builder components, but cannot create, update, or delete them. The key can read data only from indices matching `customer-*`.
<tab-set>
  <tab-item title="Console">
    Run the following request in [Console](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/explore-analyze/query-filter/tools/console). The key is owned by the user who is signed in to Kibana:
    ```json

    {
      "name": "agent-builder-read-only",
      "expiration": "30d",
      "role_descriptors": {
        "agent-builder-read-only": {
          "cluster": ["monitor_inference"], <1>
          "indices": [
            {
              "names": ["customer-*"], <2>
              "privileges": ["read", "view_index_metadata"]
            }
          ],
          "applications": [
            {
              "application": "kibana-.kibana", <3>
              "privileges": [
                "feature_agentBuilder.read", <4>
                "feature_actions.read",
                "feature_workflowsManagement.read"
              ],
              "resources": ["space:default"] <5>
            }
          ]
        }
      }
    }
    ```
  </tab-item>

  <tab-item title="curl">
    ```bash
    curl --user "${ELASTIC_USERNAME}" \
      -X POST "${ELASTICSEARCH_URL}/_security/api_key" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "agent-builder-read-only",
        "expiration": "30d",
        "role_descriptors": {
          "agent-builder-read-only": {
            "cluster": ["monitor_inference"], 
            "indices": [
              {
                "names": ["customer-*"], 
                "privileges": ["read", "view_index_metadata"]
              }
            ],
            "applications": [
              {
                "application": "kibana-.kibana", 
                "privileges": [
                  "feature_agentBuilder.read", 
                  "feature_actions.read",
                  "feature_workflowsManagement.read"
                ],
                "resources": ["space:default"] 
              }
            ]
          }
        }
      }'
    ```
  </tab-item>

  <tab-item title="API keys UI">
    1. Open the **API keys** management page and select **Create API key**.
    2. Enter a name and expiration for the key.
    3. Enable **Control security privileges**.
    4. Paste the following role descriptor into the editor, then create the key:

    ```json
    {
      "agent-builder-read-only": {
        "cluster": ["monitor_inference"], 
        "indices": [
          {
            "names": ["customer-*"], 
            "privileges": ["read", "view_index_metadata"]
          }
        ],
        "applications": [
          {
            "application": "kibana-.kibana", 
            "privileges": [
              "feature_agentBuilder.read", 
              "feature_actions.read",
              "feature_workflowsManagement.read"
            ],
            "resources": ["space:default"] 
          }
        ]
      }
    }
    ```
  </tab-item>
</tab-set>

Remove privileges that the client does not need:
- Remove `feature_actions.read` if agents do not use Kibana connectors.
- Remove `feature_workflowsManagement.read` if agents do not interact with workflows.
- Remove `monitor_inference` if agents and tools do not call the Elasticsearch Inference API.


## Create a key that can manage agents, tools, skills, and workflows

The following example allows a client to manage Elastic Agent Builder components and workflows while keeping the underlying index access read-only.
<tab-set>
  <tab-item title="Console">
    ```json

    {
      "name": "agent-builder-management",
      "expiration": "30d",
      "role_descriptors": {
        "agent-builder-management": {
          "cluster": ["monitor_inference"], <1>
          "indices": [
            {
              "names": ["customer-*"], <2>
              "privileges": ["read", "view_index_metadata"]
            }
          ],
          "applications": [
            {
              "application": "kibana-.kibana", <3>
              "privileges": [
                "feature_agentBuilder.all", <4>
                "feature_actions.read",
                "feature_workflowsManagement.all"
              ],
              "resources": ["space:default"] <5>
            }
          ]
        }
      }
    }
    ```
  </tab-item>

  <tab-item title="curl">
    ```bash
    curl --user "${ELASTIC_USERNAME}" \
      -X POST "${ELASTICSEARCH_URL}/_security/api_key" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "agent-builder-management",
        "expiration": "30d",
        "role_descriptors": {
          "agent-builder-management": {
            "cluster": ["monitor_inference"], 
            "indices": [
              {
                "names": ["customer-*"], 
                "privileges": ["read", "view_index_metadata"]
              }
            ],
            "applications": [
              {
                "application": "kibana-.kibana", 
                "privileges": [
                  "feature_agentBuilder.all", 
                  "feature_actions.read",
                  "feature_workflowsManagement.all"
                ],
                "resources": ["space:default"] 
              }
            ]
          }
        }
      }'
    ```
  </tab-item>

  <tab-item title="API keys UI">
    Enable **Control security privileges** and paste the following role descriptor into the editor:
    ```json
    {
      "agent-builder-management": {
        "cluster": ["monitor_inference"], 
        "indices": [
          {
            "names": ["customer-*"], 
            "privileges": ["read", "view_index_metadata"]
          }
        ],
        "applications": [
          {
            "application": "kibana-.kibana", 
            "privileges": [
              "feature_agentBuilder.all", 
              "feature_actions.read",
              "feature_workflowsManagement.all"
            ],
            "resources": ["space:default"] 
          }
        ]
      }
    }
    ```
  </tab-item>
</tab-set>

The `feature_agentBuilder.all` application privilege does not grant write access to indices. Tools continue to run with only the `read` and `view_index_metadata` index privileges assigned to the key.

## Create an unrestricted development key

<warning>
  An unrestricted key can access everything its owner can access. Use this approach only for development or trusted administrative automation. Before using a key in production, replace it with a restricted key that grants only the required spaces, indices, and features.
</warning>

For short-lived development or administrative automation, you can create a key without role descriptors:
<tab-set>
  <tab-item title="Console">
    ```json

    {
      "name": "agent-builder-development",
      "expiration": "1d"
    }
    ```
  </tab-item>

  <tab-item title="curl">
    ```bash
    curl --user "${ELASTIC_USERNAME}" \
      -X POST "${ELASTICSEARCH_URL}/_security/api_key" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "agent-builder-development",
        "expiration": "1d"
      }'
    ```
  </tab-item>

  <tab-item title="API keys UI">
    Enter a name and expiration for the key, leave **Control security privileges** disabled, and create the key.
  </tab-item>
</tab-set>

The key inherits a point-in-time snapshot of the privileges of the user who creates it. It is an administrator key only when the owner has administrator privileges.

## Use the API key

The create API returns an `encoded` value. Store that value securely and send it in the `Authorization` header:
```bash
export API_KEY="<encoded-api-key>" 

curl -X GET "${KIBANA_URL}/api/agent_builder/tools" \
  -H "Authorization: ApiKey ${API_KEY}"
```

For a non-default space, include the space in the request URL and make sure it matches the application privilege resource:
```bash
curl -X GET "${KIBANA_URL}/s/production/api/agent_builder/tools" \ 
  -H "Authorization: ApiKey ${API_KEY}"
```


## Troubleshoot API keys

The following list pairs common API key symptoms with checks or changes that can resolve them.
<definitions>
  <definition term="401 Unauthorized">
    Make sure the header uses the `encoded` value returned by the create API, not the separate `id` or `api_key` fields.
  </definition>
  <definition term="403 Forbidden">
    Check that the key has the required Kibana application privilege and that the space in the URL matches the `resources` value. Also make sure the key owner had the privilege when the key was created.
  </definition>
  <definition term="An agent or tool cannot find data">
    Check the index patterns and make sure the key has both `read` and `view_index_metadata` for the required indices.
  </definition>
  <definition term="Connector or model requests fail">
    Add `feature_actions.read` for Kibana connectors. Add `monitor_inference` for Elasticsearch inference endpoints and tools that use the Elasticsearch Inference API.
  </definition>
  <definition term="Workflow requests fail">
    Add `feature_workflowsManagement.read` to read workflows, `feature_workflowsManagement.workflow_execute` to run them, or `feature_workflowsManagement.all` to manage them.
  </definition>
  <definition term="The create API rejects the role descriptor for a derived key">
    Authenticate the create request as a user. When the request is authenticated with an API key, Elasticsearch requires an explicit role descriptor with no privileges.
  </definition>
</definitions>

Learn more about [Elasticsearch API keys](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/deploy-manage/api-keys/elasticsearch-api-keys) and [Elastic Agent Builder permissions](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7388/explore-analyze/ai-features/agent-builder/permissions).