Elasticsearchのインデックスに対するアクセス制御(API経由での動作確認)

BLOG

はじめに

Elasticsearchのインデックスに対するアクセス制御(Kibana上での動作確認) では、Kibana にログインしたユーザーで各インデックスに対するアクセス権を確認しました。

今回は、Python などから API 経由で操作する場合の設定方法について説明します。

なお、本ブログで動かすサンプルアプリケーションは、下記で公開しています。

https://github.com/sios-elastic-tech/blogs/tree/main/2025-06-rbac

対象者

  • Elasticsearch 熟練度 : 初級者~中級者
  • Elasticsearch License : Basic 以上
  • Elasticsearch Version : 筆者は、8.15.5 で動作確認

できるようになること

  • Elasticsearch で API 経由でインデックス単位でのアクセス制御を行える。

前提条件

Elasticsearchのインデックスに対するアクセス制御(Kibana上での動作確認) に記載した以下の作業を行っておく必要があります。

  • sales_data_2024, sales_data_2025, hr_data_2024, hr_data_2025 のインデックスを作成しておくこと。
  • 上記のインデックスにドキュメントを登録しておくこと。
  • sales_data エイリアスを作成しておくこと。
  • hr_data エイリアスを作成しておくこと。

接続方法

Elasticsearch で、Python などから接続する場合、主に2つの方法があります。

  • user / password を渡して認証する方法
  • API Key を渡して認証する方法

今回は、後者の API Key を渡して認証する方法を採用します。

API Key を渡す方法のメリットとデメリットです。

  • メリット
    • 細やかな権限設定を行える。
    • API Key の有効期限を設定できる。
  • デメリット
    • 利用するための API Key を事前に発行しておく必要がある。

サンプルプログラムのソースコードの取得

https://github.com/sios-elastic-tech/blogs の [<> Code] の Download ZIP を選択します。

blogs-main.zip ファイルがダウンロードされるので、これを展開します。

2025-06-rbac フォルダへ移動します。

cd 2025-06-rbac

※準備作業として必要なリクエストもこの中に含まれています。

相対ファイルパス説明
es_requests/1_create_index.mdインデックスの作成リクエスト
es_requests/2_create_index_mapping.mdインデックスのフィールド作成リクエスト
es_requests/3_create_alias.mdエイリアスの作成リクエスト
es_requests/4_post_doc.mdドキュメントの登録リクエスト

Elasticsearch の Endpoint URL の取得

Elastic の Kibana にログインし、アクセス先となる Endpoint URL を取得します。

取得した URL を app/config.yaml の elasticsearch.endpoint に転記します。

app/config.yaml

elasticsearch:
  endpoint: http://host.docker.internal:9200/
cookie:
  expiry_days: 1
  key: some_signature_key
  name: some_cookie_name
credentials:
  usernames:
    sales_user:
      name: sales_user
      password: sales_user
      api_key: xxx==
    hr_user:
      name: hr_user
      password: hr_user
      api_key: xxx==
    sales_and_hr_user:
      name: sales_and_hr_user
      password: sales_and_hr_user
      api_key: xxx==

※このサンプルでは、Docker 内のコンテナ上で動作している Elasticsearch にアクセスするようにしています。

※各ユーザーの password は、Streamlit 上で動作するアプリへのログインパスワードです。 適宜、適切なパスワードに置き換えてください。

API Key の作成

API Key を利用して認証を行う場合、事前に API Key を発行しておく必要があります。(*脚注1)1

Elastic の Kibana にログインし、DevTools の Console から、下記のリクエストを発行します。

(es_requests/5_create_api_key.md にも記載しています。)

POST /_security/api_key
{
  "name": "sales_user_20250616",
  "expiration": "10d",
  "role_descriptors": {
    "sales_data_read": {
      "cluster": ["all"],
      "indices": [
        {
          "names": ["sales_data*"],
          "privileges": ["read"]
        }
      ]
    }
  }
}

※”sales_data”で始まるインデックスおよびエイリアスへの読み取り権限を与えます。 有効期限は、10日間としています。(*脚注2)2

成功すると、次のようなレスポンスが返却されます。

{
  "id": ""*****************",
  "name": "sales_user_20250616",
  "expiration": 1750916489855,
  "api_key": "*****************",
  "encoded": "**************************************=="
}

ここで重要な値は、最後の encoded です。 一度しか表示されないので、app/config.yaml の sales_user の api_key に copy & paste しておきます。

同様に、hr_user 用の API Key も生成します。

リクエスト

POST /_security/api_key
{
  "name": "hr_user_20250616",
  "expiration": "10d",
  "role_descriptors": {
    "hr_data_read": {
      "cluster": ["all"],
      "indices": [
        {
          "names": ["hr_data*"],
          "privileges": ["read"]
        }
      ]
    }
  }
}

レスポンス

{
  "id": ""*******************",
  "name": "hr_user_20250616",
  "expiration": 1750917110752,
  "api_key": "*******************",
  "encoded": "********************************=="
}

encoded に表示された値を、app/config.yaml の hr_user の api_key に copy & paste しておきます。

最後に、sales と hr 両方の読み取り用 API Key を発行します。

リクエスト

POST /_security/api_key
{
  "name": "sales_and_hr_user_20250616",
  "expiration": "10d",
  "role_descriptors": {
    "sales_and_hr_data_read": {
      "cluster": ["all"],
      "indices": [
        {
          "names": ["sales_data*", "hr_data*"],
          "privileges": ["read"]
        }
      ]
    }
  }
}

レスポンス

{
  "id": """**********************",
  "name": "sales_and_hr_user_20250616",
  "expiration": 1750917246202,
  "api_key": ""**********************",
  "encoded": "********************************************=="
}

encoded に表示された値を、app/config.yaml の sales_and_hr_user の api_key に copy & paste しておきます。

ビルド~ コンテナとの接続

ビルド

docker-compose.yml があるディレクトリへ移動します。

cd app

docker-compose.yml があるディレクトリで下記を実行します。

docker compose build

コンテナの起動

docker compose up -d

コンテナとの接続

docker exec -it rbac_sample_202506 /bin/bash

(“rbac_sample_202506″はコンテナ名)

サンプルプログラムの実行

ログイン画面の表示

rbac_sample_202506 コンテナ上の bash から次のコマンドを実行します。

streamlit run src/app.py

Web ブラウザから http://localhost:8501/ にアクセスします。

ユーザーごとの動作の確認

  1. sales_user

まず、sales_user でログインします。 パスワードは config.yaml に記載したものを入力します。

成功すると、検索画面へ遷移します。

[search sales_data] ボタンを押します。

sales_data* インデックスへの読み取り権があるので、成功します。

続いて [search hr_data] ボタンを押します。

hr_data* インデックスへの読み取り権がないため、エラーとなります。

この動きを図式化すると以下のような図になります。

動作確認が終わったら、[Logout] ボタンを押してログアウトします。

2. hr_user

同様に hr_user でも動作確認します。

hr_user でログインします。 パスワードは config.yaml に記載したものを入力します。

成功すると、検索画面へ遷移します。

[search sales_data] ボタンを押します。

sales_data* インデックスへの読み取り権がないため、エラーとなります。

続いて [search hr_data] ボタンを押します。

hr_data* インデックスへの読み取り権があるので、成功します。

[Logout] ボタンを押してログアウトします。

3. sales_and_hr_user

最後に sales_and_hr_user で動作確認します。

sales_and_hr_user でログインします。 パスワードは config.yaml に記載したものを入力します。

成功すると、検索画面へ遷移します。

[search sales_data] ボタンを押してみます。

sales_data* インデックスへの読み取り権があるので、成功します。

続いて [search hr_data] ボタンを押します。

hr_data* インデックスへの読み取り権があるので、成功します。

[Logout] ボタンを押してログアウトします。

※停止ボタンは用意していないので、停止させたい場合は Ctrl+C を押すなどの処置を行ってください。

まとめ

Python などのプログラムからアクセスする場合に、適切な権限を設定した API Key を使って接続することにより、 インデックスごとの権限を考慮したアクセスができることを紹介しました。

今回は、インデックスごとのアクセス権限の制御の方法について紹介しましたが、 ドキュメントごとのアクセス権限を制御する方法もあります。

こちらについては、日をあらためて紹介したいと思います。


  1. 今回は簡易なサンプルなので、あらかじめ Dev Tools の Console で 上記リクエストを発行し、API Key を作成していますが、 ログインするたびにAPI Key を生成するリクエストを発行し、有効期限が短い API Key を生成する方法も考えられます。
    ただし、そのような仕組みにしようとすると、本ブログで説明するには複雑な構成になってしまうため、 ここでは簡易的な仕組みとしています。

    ※API Key を発行するためには、API Key を発行する権限(manage_api_key)を持ったユーザーをあらかじめ作成しておく必要があります。 また、そのユーザーに接続するには API Key ではなく user / password による認証が必要です。
    ↩︎
  2. 有効期限を過ぎた API Key は、invalidated: true となり使用できなくなります。その後、おおよそ24時間後に削除されます。
    https://www.elastic.co/docs/reference/elasticsearch/configuration-reference/security-settings
    ↩︎