In my previous post “Elastic: Using Postman to access Elastic Stack” I showed you how to access Elasticsearch in your application. There, we used Basic Basic Authentication to access Elasticsearch. The downside of this approach is that all requests from each user are authenticated the same: the Base64 encoding of the same username and password is used. In today’s article, we’ll show you how to create an API key to provide access to Elasticsearch. With this approach, a user can dynamically generate access to countless API keys. Official documentation can be found at the link.

Create an API key interface to access Elasticsearch

interface

Its interface is very simple:

POST /_security/api_key
PUT /_security/api_key
Copy the code

The API Key is created by the Elasticsearch API Key service, which is automatically enabled when you configure TLS on the HTTP interface. See Encrypting HTTP client communication. Alternatively, you can explicitly enable the xpack.security.authc.API_key. enabled setting. When running in production mode, boot checks prevent you from enabling the API key service unless you also enable TLS on the HTTP interface.

The SUCCESSFUL API key creation API call returns a JSON structure containing the API key, its unique ID, and name. It also returns the expiration of the API key in milliseconds, if applicable.

One caveat: by default, API keys never expire. You can specify expiration information when creating the API key.

 

Request for example

The following example creates an API key:

POST /_security/api_key
{
  "name": "my-api-key",
  "expiration": "1d", 
  "role_descriptors": { 
    "role-a": {
      "cluster": ["all"],
      "index": [
        {
          "names": ["index-a*"],
          "privileges": ["read"]
        }
      ]
    },
    "role-b": {
      "cluster": ["all"],
      "index": [
        {
          "names": ["index-b*"],
          "privileges": ["all"]
        }
      ]
    }
  }
}
Copy the code

Note that the expiration and role_descriptors fields above are optional. If you do not select it, it means it is always valid and applies to all roles.

Next, let’s demonstrate this functionality with a concrete example.

 

The installation

For this test, see my previous article “Elastic: Enabling HTTPS Access for Elasticsearch” for the configuration that requires us to enable TLS. In that article, I detailed how to configure to enable TLS. If your configuration is successful, our Elasticsearch will now run on port https://localhost:9200. I won’t bother here.

 

test

Let’s first open Kibana and type the following command:

POST /_security/api_key
{
  "name": "liuxg-api-key",
  "expiration": "1d"
}
Copy the code

In this case, we set the API key to expire for 1 day. We also gave a name liuxg-apI-key. After executing the above command, we can see the following response:

{
  "id" : "gBcXKHMB53qZFLAQ52-j",
  "name" : "liuxg-api-key",
  "expiration" : 1594191922072,
  "api_key" : "sJYv3VMLRaaeaoUec2XfsA"
}
Copy the code

Here, expiration is expressed as a value. It represents the second counted from 1970-01-01 00:00:00 UTC. See the article for detailed descriptions.

We can produce this ApiKey in two ways:

Method one:

What we care most about is the id and api_key returned. These two values are not directly available to us. We open the website: www.base64encode.org/ and separate the id from the API_key with a semicolon:

Please pay attention to the value returned Z0JjWEtITUI1M3FaRkxBUTUyLWo6c0pZdjNWTUxSYWFlYW9VZWMyWGZzQQ = =. This will be the final ApiKey we need to access Elasticsearch.

Method 2:

We open a terminal and create the following file called Response, which has the following contents:

{
  "id" : "gBcXKHMB53qZFLAQ52-j",
  "name" : "liuxg-api-key",
  "expiration" : 1594191922072,
  "api_key" : "sJYv3VMLRaaeaoUec2XfsA"
}
Copy the code
$ cat response 
{
  "id" : "gBcXKHMB53qZFLAQ52-j",
  "name" : "liuxg-api-key",
  "expiration" : 1594191922072,
  "api_key" : "sJYv3VMLRaaeaoUec2XfsA"
}
Copy the code

Then we type the following command in the path of the response file:

$ echo -n $(cat response | jq -r .id):$(cat response | jq -r .api_key) | base64
Copy the code

The command above shows the result:

$ ls response 
response
liuxg:tmp liuxg$ echo -n $(cat response | jq -r .id):$(cat response | jq -r .api_key) | base64
Z0JjWEtITUI1M3FaRkxBUTUyLWo6c0pZdjNWTUxSYWFlYW9VZWMyWGZzQQ==
Copy the code

With this method, we can see the same effect as method 1.

 

Using ApiKey

An example of the interface we used to access Elasticsearch is:

curl -k -H “Authorization: ApiKey Z0JjWEtITUI1M3FaRkxBUTUyLWo6c0pZdjNWTUxSYWFlYW9VZWMyWGZzQQ==” https://localhost:9200/_cluster/health

Run the command above:

Let’s run another example:

curl -k -H “Authorization: ApiKey Z0JjWEtITUI1M3FaRkxBUTUyLWo6c0pZdjNWTUxSYWFlYW9VZWMyWGZzQQ==” https://localhost:9200/_cat/indices? pretty