---
title: API keys for Elastic APM
description: When enabled, API keys are used to authorize requests to APM Server or the managed intake service. API keys are not applicable for APM agents running...
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/solutions/observability/apm/api-keys
products:
  - APM
  - Elastic Observability
---

# API keys for Elastic APM
<admonition title="APM Server vs managed intake service">
  In Elastic Cloud Hosted, the _APM Server_ receives data from Elastic APM agents and transforms it into Elasticsearch documents. In Elastic Cloud Serverless there is in fact no APM Server running, instead the _managed intake service_ receives and transforms data.
</admonition>

<important>
  API keys are sent as plain-text, so they only provide security when used in combination with [TLS](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/solutions/observability/apm/apm-agent-tls-communication).
</important>

When enabled, API keys are used to authorize requests to APM Server or the managed intake service. API keys are not applicable for APM agents running on clients, like the RUM agent, as there is no way to prevent them from being publicly exposed.
You can assign one or more unique privileges to each API key:
- **Agent configuration** (`config_agent:read`): Required for agents to read [Agent configuration remotely](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/solutions/observability/apm/apm-server/apm-agent-central-configuration).
- **Ingest** (`event:write`): Required for ingesting agent events.

To secure the communication between APM Agents and either APM Server or the managed intake service with API keys, make sure [TLS](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/solutions/observability/apm/apm-agent-tls-communication) is enabled, then complete these steps:
1. [Enable API keys](#apm-enable-api-key)
2. [Create an API key user](#apm-create-api-key-user)
3. [Create an API key in Kibana](#apm-create-an-api-key)
4. [Set the API key in your APM agents](#apm-agent-api-key)


## Enable API keys

<tab-set>
  <tab-item title="Fleet-managed">
    Enable API key authorization in the [API key authentication options](/elastic/docs-content/pull/4236/solutions/observability/apm/apm-server/apm-agent-authorization#apm-api-key-auth-settings). You should also set a limit on the number of unique API keys that APM Server allows per minute; this value should be the number of unique API keys configured in your monitored services.
  </tab-item>

  <tab-item title="APM Server binary">
    API keys are disabled by default. Enable and configure this feature in the `apm-server.auth.api_key` section of the `apm-server.yml` configuration file.At a minimum, you must enable API keys, and should set a limit on the number of unique API keys that APM Server allows per minute. Here’s an example `apm-server.auth.api_key` config using 50 unique API keys:
    ```yaml
    apm-server.auth.api_key.enabled: true 
    apm-server.auth.api_key.limit: 50 
    ```
  </tab-item>

  <tab-item title="Elastic Cloud Serverless">
    API keys are enabled by default.
  </tab-item>
</tab-set>


## Create an API key user in Kibana

API keys can only have the same or lower access rights than the user that creates them.
<tab-set>
  <tab-item title="Fleet-managed or APM Server binary">
    Instead of using a superuser account to create API keys, you can create a role with the minimum required privileges.The user creating an APM agent API key must have at least the `manage_own_api_key` cluster privilege and the APM application-level privileges that it wishes to grant. In addition, when creating an API key from the Applications UI, you’ll need the appropriate Kibana Space and Feature privileges.The example below uses the Kibana [role management API](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-roles) to create a role named `apm_agent_key_role`.
    ```js
    POST /_security/role/apm_agent_key_role
    {
       "cluster": [ "manage_own_api_key" ],
       "applications": [
          {
             "application":"apm",
             "privileges":[
                "event:write",
                "config_agent:read"
             ],
             "resources":[ "*" ]
          },
          {
             "application":"kibana-.kibana",
             "privileges":[ "feature_apm.all" ],
             "resources":[ "space:default" ] 
          }
       ]
    }
    ```
    Assign the newly created `apm_agent_key_role` role to any user that wishes to create APM agent API keys.
  </tab-item>

  <tab-item title="Elastic Cloud Serverless">
    **For Observability Serverless projects**, the Editor role or higher is required to create and manage API keys. To learn more, refer to [Assign user roles and privileges](/elastic/docs-content/pull/4236/deploy-manage/users-roles/cloud-organization/user-roles#general-assign-user-roles).
  </tab-item>
</tab-set>


## Create an API key in the Applications UI

The Applications UI has a built-in workflow that you can use to easily create and view APM agent API keys. Only API keys created in the Applications UI will show up here.
<tab-set>
  <tab-item title="Fleet-managed or APM Server binary">
    Using a superuser account, or a user with the role created in the previous step, In Kibana, find **Applications** in the main menu or use the [global search field](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/explore-analyze/find-and-organize/find-apps-and-objects). Go to **Settings** → **Agent keys**. Enter a name for your API key and select at least one privilege.For example, to create an API key that can be used to ingest APM events and read agent central configuration, select `config_agent:read` and `event:write`.Click **Create APM Agent key** and copy the Base64 encoded API key. You will need this for the next step, and you will not be able to view it again.
    ![Applications UI API key](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4236/solutions/images/observability-apm-ui-api-key.png)
  </tab-item>

  <tab-item title="Elastic Cloud Serverless">
    To create a new API key:
    1. In your Elastic Observability Serverless project, go to any Applications page.
    2. Click **Settings**.
    3. Select the **Agent keys** tab.
    4. Click **Create APM agent key**.
    5. Name the key and assign privileges to it.
    6. Click **Create APM agent key**.
    7. Copy the key now. You will not be able to see it again. API keys do not expire.
    To view all API keys for your project:
    1. Expand **Project settings**.
    2. Select **Management**.
    3. Select **API keys**.
  </tab-item>
</tab-set>


## Set the API key in your APM agents

You can now apply your newly created API keys in the configuration of each of your APM agents. See the relevant agent documentation for additional information:
- **Android**: [`apiKey`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-android/tree/main/reference/edot-android/configuration)
- **Go agent**: [`ELASTIC_APM_API_KEY`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-go/tree/main/reference/configuration#config-api-key)
- **.NET agent**: [`ApiKey`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-dotnet/tree/main/reference/config-reporter#config-api-key)
- **iOS**: [`withApiKey`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-ios/tree/main/reference/edot-ios/configuration#withapikey)
- **Java agent**: [`api_key`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-java/tree/main/reference/config-reporter#config-api-key)
- **Node.js agent**: [`apiKey`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-nodejs/tree/main/reference/configuration#api-key)
- **PHP agent**: [`api_key`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-php/tree/main/reference/configuration-reference#config-api-key)
- **Python agent**: [`api_key`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-python/tree/main/reference/configuration#config-api-key)
- **Ruby agent**: [`api_key`](https://docs-v3-preview.elastic.dev/elastic/apm-agent-ruby/tree/main/reference/configuration#config-api-key)


## Alternate API key creation method

```
stack: ga
serverless: unavailable
```

It is also possible to create API keys using the Elasticsearch [create API key API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-create-api-key).
This example creates an API key named `java-002`:
```bash
POST /_security/api_key
{
  "name": "java-002", 
  "expiration": "1d", 
  "role_descriptors": {
    "apm": {
      "applications": [
        {
          "application": "apm",
          "privileges": ["sourcemap:write", "event:write", "config_agent:read"], 
          "resources": ["*"]
        }
      ]
    }
  }
}
```

The response will look similar to this:
```json
{
  "id" : "GnrUT3QB7yZbSNxKET6d",
  "name" : "java-002",
  "expiration" : 1599153532262,
  "api_key" : "RhHKisTmQ1aPCHC_TPwOvw"
}
```

The `credential` string, which is what agents use to communicate with APM Server, is a base64 encoded representation of the API key’s `id:api_key`. It can be created like this:
```json
echo -n GnrUT3QB7yZbSNxKET6d:RhHKisTmQ1aPCHC_TPwOvw | base64
```

You can verify your API key has been base64-encoded correctly with the [Authenticate API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-authenticate):
```sh
curl -H "Authorization: ApiKey R0gzRWIzUUI3eVpiU054S3pYSy06bXQyQWl4TlZUeEcyUjd4cUZDS0NlUQ==" localhost:9200/_security/_authenticate
```

If the API key has been encoded correctly, you’ll see a response similar to the following:
```json
{
   "username":"1325298603",
   "roles":[],
   "full_name":null,
   "email":null,
   "metadata":{
      "saml_nameid_format":"urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
      "saml(http://saml.elastic-cloud.com/attributes/principal)":[
         "1325298603"
      ],
      "saml_roles":[
         "superuser"
      ],
      "saml_principal":[
         "1325298603"
      ],
      "saml_nameid":"_7b0ab93bbdbc21d825edf7dca9879bd8d44c0be2",
      "saml(http://saml.elastic-cloud.com/attributes/roles)":[
         "superuser"
      ]
   },
   "enabled":true,
   "authentication_realm":{
      "name":"_es_api_key",
      "type":"_es_api_key"
   },
   "lookup_realm":{
      "name":"_es_api_key",
      "type":"_es_api_key"
   }
}
```

You can then use the APM Server CLI to verify that the API key has the requested privileges:
```sh
apm-server apikey verify --credentials R25yVVQzUUI3eVpiU054S0VUNmQ6UmhIS2lzVG1RMWFQQ0hDX1RQd092dw==
```

If the API key has the requested privileges, the response will look similar to this:
```json
Authorized for privilege "config_agent:read"...:  Yes
Authorized for privilege "event:write"...:        Yes
Authorized for privilege "sourcemap:write"...:    Yes
```