CptSnuggles
CptSnuggles

Reputation: 137

API Key Authentication in Elasticsearch with python

I was hoping to find an answer to my problem with the elasticsearch python framework. Maybe I'm completely blind or doing something absolutely wrong, but I'm very confused right now and can't find an adequate answer.

I'm currently trying to establish a connection to my elastic search API using the elasticsearch python framework, my code looks like this:

from elasticsearch import Elasticsearch

def create_es_connection(host: str, port: int, api_key_id: str, api_key: str, user: str, pw: str) -> Elasticsearch:
    return Elasticsearch([f"https://{user}:{pw}@{host}:{port}"])

This is working fine. I then created an API key for my testuser, which I'm giving to the function above as well. I am now trying to do something similar like this: Elasticsearch([f"https://{api_key_id}:{api_key}@{host}:{port}"]) so, I want to leave out the user and password completely, because in regards to the greater project behind this snippet, I'm not feeling very well in saving the user/password credentials in my project (and maybe even pushing it to our git server). Sooner or later, these credentials have to be entered somewhere and I was thinking that only saving the API key and to authenticate with that could be more safe. Unfortunately, this isn't working out like I planned and I couldn't find anything about how to authenticate with the API key only.

What am I doing wrong? In fact, I found so little about this, that I'm questioning my fundamental understanding here. Thank you for your replies!

Upvotes: 5

Views: 16582

Answers (2)

yamamoto92
yamamoto92

Reputation: 91

working configuration for me was :

es = Elasticsearch(['localhost:9200'], api_key=('DuSkVm8BZ5TMcIF99zOC','2rs8yN26QSC_uPr31R1KJg'))

Upvotes: 9

Andreas
Andreas

Reputation: 8029

Elasticsearch's documentation shows how to generate and use (at the bottom of the page) an API key: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html

curl -H "Authorization: ApiKey ..." http://localhost:9200/_cluster/health

-H means "header", so to do the same in Python you will need to set this header. Rummaging through the elasticsearch module source code tells me that you might just be able to do the following:

Elasticsearch([f'http://{host}:{port}'], api_key=api_key)

The reason for this is that **kwargs of the Elasticsearch.__init__ method are passed to Transport.__init__, the **kwargs of that are passed to Connection.__init__, which takes an api_key arg which is then used in _get_api_key_header_val to construct the appropriate header.

The following code shows that the api key header gets added to the HTTP headers of the request:

import elasticsearch, logging, http.client
http.client.HTTPConnection.debuglevel = 5
logging.basicConfig(level=logging.DEBUG)
c = elasticsearch.Elasticsearch(['localhost'], api_key='TestApiKey')
print(c.cluster.health(wait_for_status='green'))

This is definitely something that should be added to Elasticsearch's docs.

Upvotes: 5

Related Questions