Kendraのアクセスコントロール設定をEntra IDのOpen ID Connectを用いて有効化してみた

2024.02.16

こんにちは、つくぼしです!

先日KendraのデータソースとしてSharepointを使用する方法について、以下のブログで紹介しました。

こちらのブログでは、Sharepointのアクセス制限設定を反映するためのアクセスコントロール設定として、簡単に設定できるJSONを使用しました。

しかしながら公式ドキュメントにて、JSONトークンはペイロードの検証がされていないとの記載があり、そのまま使用すると外部からKendraインデックスに対して不正アクセスされる恐れがあります。

JSON トークンは検証されていないペイロードです。これは、Amazon Kendra へのリクエストが信頼できるサーバーから送信され、ブラウザからのリクエストではない場合にのみ使用してください。

上記の通りJSONによるアクセスコントロール設定を安全に使用するには、別途ペイロード検証の仕組みを実装する必要がありますが、この仕組みの実装には多少手間がかかります。

そこで今回はJSONの代わりに、認証サーバとしてEntra IDのOpen ID Connect認証とKendraのJWT Public Keyによるアクセスコントロール設定を使用し、ペイロードを検証した上で特定のユーザー情報を用いて制限されたSharepointページにアクセスできるか試してみたいと思います!

前提条件

こちらは以下のブログをご参照ください。

なおEntra IDのOpen ID Connect認証に関する公式ドキュメントは以下になります。

またKendraのJWT Public Keyに関する公式ドキュメントは以下になります。

構築手順

Sharepoint サイトの準備/ユーザーの準備/エンタープライズアプリケーションの登録

こちらは以下のブログと同じ手順ですので、ご参照ください。

なお今回は、全ユーザーがアクセスできる共有ページと、テストユーザー2のみがアクセスできるユーザーページを、事前にSharepointページとして作成します。

エンタープライスアプリケーションのIDトークン有効化

今回は作成したエンタープライズアプリケーションに対してOpenID Connectを使用できるよう、以下を参考にMicrosoft Entra管理センターにてIDトークンを有効化します。

リダイレクトURIには、今回はSharepointのサイトURL(https://yourdomain.sharepoint.com/sites/mysite)を指定します。

以下の通り、プラットフォームにリダイレクトURIが追加されていればOKです。

JWTキー情報の確認

続いてKendraインデックスのアクセスコントロール設定に必要なJWTキー情報を取得します。

まずはMicrosoft Entra管理センターの"アプリの登録"から対象のアプリを選択し、エンドポイントをクリックします。

表示されるエンドポイント一覧のうち、OpenID Connect メタデータ ドキュメントのURLにアクセスします。

なおOpenID Connect メタデータ ドキュメントのURLは、以下のような形式になります。

tenaitidは、エンタープライズアプリケーションで表示されている値に変更してください。

https://login.microsoftonline.com/{tenantid}/v2.0/.well-known/openid-configuration

上記URLにアクセスすると表示される内容の中に、jwks_uriに対して以下のようなの値が表示されるのでさらにこちらにアクセスします。

https://login.microsoftonline.com/{tenantid}/discovery/v2.0/keys

こちらにアクセスすると、kid/n/eといったJWTキー情報が表示されます。

このJWTキー情報をKendraのアクセスコントロール設定に使用するので、メモしておきます。

IDトークンの取得

さらにKendraの検索に必要となる、ユーザー毎のIDトークンを取得します。

トークンの取得方法としては、以下のブログを参照します。

まずは以下のURLにアクセスし、IDトークンを取得します。

tenaitidclientidは、エンタープライズアプリケーションで表示されている値に変更してください。

https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?client_id=${clientid}&response_type=id_token&response_mode=form_post&scope=openid+profile&state=12345&nonce=678910

このURLにアクセスすると、Entra IDへのサインイン画面が表示されます。

ここで以下のようにChrome開発者ツールを開き、Networkタブを選択した状態にしてください。

内容を確認し、トークンの取得が必要なユーザーで承諾を行うと、Sharepointサイトへリダイレクトされます。

その際にChrome開発者ツールを確認すると、Networkタブで指定したFQDN(今回はcm-kendra-datasource-sample)へリクエストが送信されており、フォームデータにid_tokenが設定されています。

こちらの値を、Kendraの検索で使用するのでメモしておきます。

今回はテストユーザー2及びテストユーザー3のIDトークンを使用するので、各々用意しておいてください。

Kendraインデックスの作成

必要な情報が揃ったので、Kendraのインデックスを作成します。

まずインデックスの名前とロール名を設定します。

次にアクセスコントロール設定を有効化します。

トークンタイプは今回JWT Public Keyを選択します。

Type of secretでNewを選択し、Secret Managerでシークレットを作成します。

Secret nameにはシークレット名を記入し、AlgorithmはRS256を選択します。

また以下の各々のパラメータに対して、対応するキーを確認し、先ほどメモしたJWTキー情報の値を設定します。

パラメータ JWTキー
Key ID kid
Modulus n
Exponent e

上記の設定が完了したら、Save Secretをクリックしてシークレットを作成してください。

さらに追加設定の箇所では、ユーザー名はpreferred_usernameに変更してください。

他はデフォルトのままで構いません。

最後にエディションについては、今回検証のためDeveloperを選択します。

設定内容に問題がなければ、インデックスを作成してください。

(2024/2/24追記) 今回アクセスしたJWTキー情報は通常3種類ありますが、JWT Public Keyを使用する場合は1種類しか指定しません。この場合、例えばJWTキーをローテーションした場合、Secrets Manager側も適宜修正する必要があるためご注意ください。もしこの現象を回避したい場合は、JWTキー情報に「"alg":"RS256"」の項目を加えてS3にアップロードして公開状態にした上で、インデックス作成時にToken TypeをOpen IDで指定しSinging Key URLに公開URLを入力すれば同じ内容を実現できます。

Kendraデータソースの作成

こちらは以下のブログと同じ手順ですので、ご参照ください。

検索テスト

最後にKendraのデータを同期し、想定通りユーザーコンテキストフィルタリングを用いて、ユーザー毎のアクセス権限に基づいてSharepointのサイトを検索できるか確認します。

まずSync nowボタンをクリックし、データソースの同期を実行します。

下記の通りデータ同期が成功し、Addedに同期されたデータの数が表示されていればOKです。

もし同期に失敗した場合や、同期されたデータの数が想定と異なる場合は、CloudWatch Logsの/aws/kendra/<KendraデータソースID>ロググループに出力されているエラーログを確認してください。

同期が完了したら、Search indexed contentより検索を実行します。

検索言語はJapaneseを選択します。

続いてApply tokenをクリックします。

Token IDに先ほどメモしたIDトークンを入力します。

初めにテストユーザー2で取得したIDトークンを用いて検索すると、共有ページ及びユーザーページの両方が表示される事が分かります。

続いてテストユーザー3で検索すると、共有ページのみ表示されるので、ユーザーのアクセス権限に基づいたドキュメント検索が実現できている事が分かりました!

なお実際の生成AIアプリケーション等からKendraにアクセスする場合は、リクエストヘッダーに今回指定したようなトークンIDを含めて渡す処理を実装する必要があるためご注意ください。

最後に

今回はEntra IDのOpen ID Connect認証とKendraのJWT Public Keyによるアクセスコントロール設定を使用し、ペイロードを検証した上で特定のユーザー情報を用いて制限されたSharepointページにアクセスしてみました。

JSONを用いたアクセスコントロール設定は認証サーバが不要なため便利な一方で、セキュリティリスクを顕現するためにペイロード検証の仕組みを検討する必要があります。

大きな手間をかけずにKendraのセキュアなアクセスコントロール設定を実現したい場合は、今回紹介させて頂いた認証サーバを使用する方法も検討して頂くのが良いかと思われます。

以上、つくぼし(tsukuboshi0755)でした!