を使用したトークンの検証 AWS Lambda - AWS HealthLake

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

を使用したトークンの検証 AWS Lambda

FHIR 対応データストアで HealthLake SMART を作成する場合は、CreateFHIRDatastoreリクエストで AWS Lambda 関数の ARN を指定する必要があります。Lambda 関数の ARN は、 IdpLambdaArnパラメータを使用して IdentityProviderConfiguration オブジェクトで指定されます。

SMART on FHIR 対応データストアを作成する前に、Lambda 関数を作成する必要があります。データストアを作成すると、Lambda ARN を変更することはできません。データストアの作成時に指定した Lambda ARN を表示するには、 DescribeFHIRDatastore API アクションを使用します。

FHIR REST リクエストが SMART on FHIR 対応データストアで成功するには、Lambda 関数が以下を実行する必要があります。
  • HealthLake データストアエンドポイントに 1 秒未満でレスポンスを返します。

  • クライアントアプリケーションによって送信された REST API リクエストの認可ヘッダーで提供されるアクセストークンをデコードします。

  • FHIR REST API リクエストを実行するのに十分なアクセス許可を持つ IAM サービスロールを割り当てます。

  • FHIR REST API リクエストを完了するには、次のクレームが必要です。詳細については必須のクレームを参照してください。

    • nbf

    • exp

    • isAuthorized

    • aud

    • scope

Lambda を使用する場合は、Lambda 関数に加えて、実行ロールとリソースベースのポリシーを作成する必要があります。Lambda 関数の実行ロールは、実行時に必要な AWS のサービスおよびリソースにアクセスするためのアクセス許可を関数に付与する IAM ロールです。指定するリソースベースのポリシーでは、HealthLake がユーザーに代わって関数を呼び出すことを許可する必要があります。

このトピックのセクションでは、クライアントアプリケーションからのリクエスト例とデコードされたレスポンス、 AWS Lambda 関数の作成に必要なステップ、および HealthLake が引き受けることができるリソースベースのポリシーの作成方法について説明します。

AWS Lambda 関数の作成

このトピックで作成された Lambda 関数は、HealthLake が SMART on FHIR 対応データストアへのリクエストを受信するとトリガーされます。クライアントアプリケーションからのリクエストには、REST API コールと、アクセストークンを含む認可ヘッダーが含まれています。

GET https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/ Authorization: Bearer i8hweunweunweofiwweoijewiwe

このトピックの Lambda 関数の例では AWS Secrets Manager 、 を使用して認可サーバーに関連する認証情報を隠します。Lambda 関数で認可サーバーログインの詳細を直接提供しないことを強くお勧めします。

例 認可ベアラートークンを含む FHIR REST リクエストの検証

Lambda 関数の例は、SMART on FHIR 対応データストアに送信された FHIR REST リクエストを検証する方法を示しています。この Lambda 関数を実装する手順については、 step-by-steps 「」を参照してくださいを使用した Lambda 関数の作成 AWS マネジメントコンソール

FHIR REST API リクエストに有効なデータストアエンドポイント、アクセストークン、REST オペレーションが含まれていない場合、Lambda 関数は失敗します。必要な認可サーバー要素の詳細については、「」を参照してください必須のクレーム

import base64 import boto3 import logging import json import os from urllib import request, parse logger = logging.getLogger() logger.setLevel(logging.INFO) ## Uses Secrets manager to gain access to the access key ID and secret access key for the authorization server client = boto3.client('secretsmanager', region_name="region-of-datastore") response = client.get_secret_value(SecretId='name-specified-by-customer-in-secretsmanager') secret = json.loads(response['SecretString']) client_id = secret['client_id'] client_secret = secret['client_secret'] unencoded_auth = f'{client_id}:{client_secret}' headers = { 'Authorization': f'Basic {base64.b64encode(unencoded_auth.encode()).decode()}', 'Content-Type': 'application/x-www-form-urlencoded' } auth_endpoint = os.environ['auth-server-base-url'] # Base URL of the Authorization server user_role_arn = os.environ['iam-role-arn'] # The IAM role client application will use to complete the HTTP request on the datastore def lambda_handler(event, context): if 'datastoreEndpoint' not in event or 'operationName' not in event or 'bearerToken' not in event: return {} datastore_endpoint = event['datastoreEndpoint'] operation_name = event['operationName'] bearer_token = event['bearerToken'] logger.info('Datastore Endpoint [{}], Operation Name: [{}]'.format(datastore_endpoint, operation_name)) ## To validate the token auth_response = auth_with_provider(bearer_token) logger.info('Auth response: [{}]'.format(auth_response)) auth_payload = json.loads(auth_response) ## Required parameters needed to be sent to the datastore endpoint for the HTTP request to go through auth_payload["isAuthorized"] = bool(auth_payload["active"]) auth_payload["nbf"] = auth_payload["iat"] return {"authPayload": auth_payload, "iamRoleARN": user_role_arn} ## access the server def auth_with_provider(token): data = {'token': token, 'token_type_hint': 'access_token'} req = request.Request(url=auth_endpoint + '/v1/introspect', data=parse.urlencode(data).encode(), headers=headers) with request.urlopen(req) as resp: return resp.read().decode()

次の手順では、SMART on FHIR 対応データストアで FHIR REST API リクエストを処理するときに HealthLake が引き受けるサービスロールが既に作成されていることを前提としています。サービスロールを作成していない場合でも、Lambda 関数を作成できます。Lambda 関数が機能する前に、サービスロールの ARN を追加する必要があります。サービスロールの作成と Lambda 関数での指定の詳細については、「」を参照してください。 JWT のデコードに使用される AWS Lambda 関数で使用する HealthLake サービスロールの作成

Lambda 関数を作成するには (AWS マネジメントコンソール)
  1. Lambda コンソールの [関数] ページを開きます。

  2. [関数の作成] を選択してください。

  3. [一から作成] を選択します。

  4. 基本情報関数名を入力します。Runtime で、Python ベースのランタイムを選択します。

  5. [Execution role] (実行ロール) で [Create a new role with basic Lambda permissions] (基本的な Lambda アクセス権限で新しいロールを作成) を選択します。

    Lambda が、Amazon CloudWatch にログをアップロードする関数許可を付与する実行ロールを作成します。Lambda 関数は、関数を呼び出すときに実行ロールを引き受け、実行ロールを使用して AWS SDK の認証情報を作成します。

  6. Code タブを選択し、サンプル Lambda 関数を追加します。

    Lambda 関数が使用するサービスロールをまだ作成していない場合は、サンプルの Lambda 関数が機能する前に作成する必要があります。Lambda 関数のサービスロールの作成の詳細については、「」を参照してくださいJWT のデコードに使用される AWS Lambda 関数で使用する HealthLake サービスロールの作成

    import base64 import boto3 import logging import json import os from urllib import request, parse logger = logging.getLogger() logger.setLevel(logging.INFO) ## Uses Secrets manager to gain access to the access key ID and secret access key for the authorization server client = boto3.client('secretsmanager', region_name="region-of-datastore") response = client.get_secret_value(SecretId='name-specified-by-customer-in-secretsmanager') secret = json.loads(response['SecretString']) client_id = secret['client_id'] client_secret = secret['client_secret'] unencoded_auth = f'{client_id}:{client_secret}' headers = { 'Authorization': f'Basic {base64.b64encode(unencoded_auth.encode()).decode()}', 'Content-Type': 'application/x-www-form-urlencoded' } auth_endpoint = os.environ['auth-server-base-url'] # Base URL of the Authorization server user_role_arn = os.environ['iam-role-arn'] # The IAM role client application will use to complete the HTTP request on the datastore def lambda_handler(event, context): if 'datastoreEndpoint' not in event or 'operationName' not in event or 'bearerToken' not in event: return {} datastore_endpoint = event['datastoreEndpoint'] operation_name = event['operationName'] bearer_token = event['bearerToken'] logger.info('Datastore Endpoint [{}], Operation Name: [{}]'.format(datastore_endpoint, operation_name)) ## To validate the token auth_response = auth_with_provider(bearer_token) logger.info('Auth response: [{}]'.format(auth_response)) auth_payload = json.loads(auth_response) ## Required parameters needed to be sent to the datastore endpoint for the HTTP request to go through auth_payload["isAuthorized"] = bool(auth_payload["active"]) auth_payload["nbf"] = auth_payload["iat"] return {"authPayload": auth_payload, "iamRoleARN": user_role_arn} ## Access the server def auth_with_provider(token): data = {'token': token, 'token_type_hint': 'access_token'} req = request.Request(url=auth_endpoint + '/v1/introspect', data=parse.urlencode(data).encode(), headers=headers) with request.urlopen(req) as resp: return resp.read().decode()

Lambda 関数の実行ロールの変更

Lambda 関数を作成したら、Secrets Manager を呼び出すために必要なアクセス許可を含めるように実行ロールを更新する必要があります。Secrets Manager では、作成する各シークレットに ARN があります。最小権限を適用するには、実行ロールが Lambda 関数の実行に必要なリソースにのみアクセスできる必要があります。

Lambda 関数の実行ロールを変更するには、IAM コンソールで検索するか、Lambda コンソールで設定を選択します。Lambda 関数の実行ロールの管理の詳細については、「」を参照してくださいLambda 実行ロール

例 へのアクセスを許可する Lambda 関数実行ロール GetSecretValue

IAM アクションGetSecretValueを実行ロールに追加すると、サンプルの Lambda 関数が機能するために必要なアクセス許可が付与されます。

この時点で、FHIR 対応データストアで SMART に送信される FHIR REST リクエストの一部として提供されるアクセストークンを検証するために使用できる Lambda 関数を作成しました。

JWT のデコードに使用される AWS Lambda 関数で使用する HealthLake サービスロールの作成

ペルソナ: IAM 管理者

IAM ポリシーを追加または削除し、新しい IAM ID を作成できるユーザー。

サービスロール

サービスロールとは、サービスがユーザーに代わってアクションを実行するために引き受ける IAM ロールです。IAM 管理者は、IAM 内からサービスロールを作成、変更、削除できます。詳細については、「IAM ユーザーガイド」の「AWS のサービスに許可を委任するロールを作成する」を参照してください。

JSON ウェブトークン (JWT) がデコードされると、認可 Lambda も IAM ロール ARN を返す必要があります。このロールには、REST API リクエストを実行するために必要なアクセス許可が必要です。そうしないと、アクセス許可が不十分であるために失敗します。

IAM を使用してカスタムポリシーを設定する場合は、必要な最小限のアクセス許可を付与することをお勧めします。詳細については、IAM ユーザーガイド「最小特権のアクセス許可を適用する」を参照してください。

認可 Lambda 関数で指定する HealthLake サービスロールを作成するには、2 つのステップが必要です。

  • まず、IAM ポリシーを作成する必要があります。ポリシーでは、認可サーバーでスコープを指定した FHIR リソースへのアクセスを指定する必要があります。

  • 次に、サービスロールを作成する必要があります。ロールを作成するときは、信頼関係を指定し、ステップ 1 で作成したポリシーをアタッチします。信頼関係はHealthLake をサービスプリンシパルとして指定します。このステップでは、HealthLake データストア ARN と AWS アカウント ID を指定する必要があります。

新しい IAM ポリシーの作成

認可サーバーで定義するスコープによって、認証されたユーザーが HealthLake データストアでアクセスできる FHIR リソースが決まります。

作成した IAM ポリシーは、定義したスコープに合わせて調整できます。

IAM ポリシーステートメントの Action要素で以下のアクションを定義できます。テーブルAction内の ごとに、 を定義できますResource types。HealthLake では、データストアは、IAM アクセス許可ポリシーステートメントの Resource要素で定義できる唯一のサポートされているリソースタイプです。

個々の FHIR リソースは、IAM アクセス許可ポリシーの 要素として定義できるリソースではありません。

 HealthLake によって定義されたアクション
アクション 説明 アクセスレベル リソースタイプ (必須)

CreateResource

リソースの作成にアクセス許可を付与します

書き込み データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
DeleteResource

リソースを削除する許可を付与

書き込み データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
ReadResource

リソースを読み取るアクセス許可を付与します

読み取り データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
SearchWithGet

GET メソッドでリソースを検索する許可を付与

読み取り データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
SearchWithPost POST メソッドでリソースを検索する許可を付与 読み取り データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
StartFHIRExportJobWithPost

GET で FHIR エクスポートジョブを開始する許可を付与

書き込み データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id
UpdateResource

リソースを更新する許可を付与

書き込み データストア ARN: arn:aws:healthlake:your-region111122223333:datastore/fhir/your-datastore-id

開始するには、 を使用できますAmazonHealthLakeFullAccess。このポリシーは、データストアで見つかったすべての FHIR リソースの読み取り、書き込み、検索、エクスポートを許可します。データストアに読み取り専用アクセス許可を付与するには、 を使用しますAmazonHealthLakeReadOnlyAccess

、、または IAM SDK を使用したカスタムポリシーの作成の詳細については AWS マネジメントコンソール AWS CLI、IAM ユーザーガイドの「IAM ポリシーの作成」を参照してください。 SDKs

HealthLake のサービスロールの作成 (IAM コンソール)

この手順を使用して、サービスロールを作成します。サービスを作成するときは、IAM ポリシーも指定する必要があります。

HealthLake のサービスロールを作成するには (IAM コンソール)
  1. にサインイン AWS マネジメントコンソール し、https://console.aws.amazon.com/iam/ で IAM コンソールを開きます。

  2. IAM コンソールのナビゲーションペインで [ロール] を選択します。

  3. 続いて、[ロールの作成] を選択します。

  4. 信頼エンティティの選択ページで、カスタム信頼ポリシーを選択します。

  5. 次に、カスタム信頼ポリシーで、次のようにサンプルポリシーを更新します。をアカウント番号your-account-idに置き換え、インポートジョブまたはエクスポートジョブで使用するデータストアの ARN を追加します。

  6. 続いて、[次へ] を選択します。

  7. アクセス許可の追加ページで、HealthLake サービスが引き受けるポリシーを選択します。ポリシーを検索するには、アクセス許可ポリシーで検索します。

  8. 次に、ポリシーのアタッチを選択します。

  9. 次に、「名前」、「確認」、「作成」ページの「ロール名」に名前を入力します。

  10. (オプション) 説明 に、ロールの簡単な説明を追加します。

  11. 可能な場合は、このロールの目的を識別するのに役立つロール名またはロール名サフィックスを入力します。ロール名は AWS アカウントアカウント内で一意である必要があります。大文字と小文字は区別されません。例えば、PRODROLEprodrole というロール名を両方作成することはできません。多くのエンティティによりロールが参照されるため、作成後にロール名を変更することはできません。

  12. ロールの詳細を確認し、ロールの作成を選択します。

サンプル Lambda 関数でロール ARN を指定する方法については、「」を参照してくださいAWS Lambda 関数の作成

Lambda 実行ロール

Lambda 関数の実行ロールは、 AWS サービスとリソースへのアクセス許可を関数に付与する IAM ロールです。このページでは、Lambda 関数の実行ロールを作成、表示、および管理する方法について説明します。

デフォルトでは、 を使用して新しい Lambda 関数を作成すると、Lambda は最小限のアクセス許可で実行ロールを作成します AWS マネジメントコンソール。実行ロールで付与されたアクセス許可を管理するには、Lambda デベロッパーガイド「IAM コンソールでの実行ロールの作成」を参照してください。

このトピックで提供されるサンプル Lambda 関数は、Secrets Manager を使用して認可サーバーの認証情報を隠します。

作成した IAM ロールと同様に、最小特権のベストプラクティスに従うことが重要です。開発フレーズ中に、必要以上のアクセス許可を付与することがあります。ベストプラクティスとしては、本番環境に関数を公開する前に、ポリシーを調整して必要なアクセス許可のみを含めるようにします。詳細については、IAM ユーザーガイド「最小権限の適用」を参照してください。

HealthLake に Lambda 関数のトリガーを許可する

HealthLake がユーザーに代わって Lambda 関数を呼び出すには、以下を実行する必要があります。

  • HealthLake がCreateFHIRDatastoreリクエストで呼び出す Lambda 関数の ARN とIdpLambdaArn等しく設定する必要があります。

  • HealthLake がユーザーに代わって Lambda 関数を呼び出すことを許可するリソースベースのポリシーが必要です。

HealthLake が SMART on FHIR 対応データストアで FHIR REST API リクエストを受信すると、ユーザーに代わってデータストアの作成時に指定された Lambda 関数を呼び出すアクセス許可が必要です。HealthLake アクセスを許可するには、リソースベースのポリシーを使用します。Lambda 関数のリソースベースのポリシーの作成の詳細については、「 AWS Lambda デベロッパーガイド」の「 AWS サービスによる Lambda 関数の呼び出しを許可する」を参照してください。

Lambda 関数の同時実行のプロビジョニング

重要

HealthLake では、Lambda 関数の最大実行時間が 1 秒 (1000 ミリ秒) 未満である必要があります。

Lambda 関数が実行時間の制限を超えると、TimeOut 例外が発生します。

この例外が発生しないように、プロビジョニングされた同時実行を設定することをお勧めします。呼び出しの増加前にプロビジョニングされた同時実行数を割り当てることにより、すべてのリクエストが、短いレイテンシーで、初期化されたインスタンスによって処理されるようにできます。プロビジョニングされた同時実行の設定の詳細については、Lambda デベロッパーガイド「プロビジョニングされた同時実行の設定」を参照してください。

現在、Lambda 関数の平均実行時間を確認するには、Lambda コンソールの Lambda 関数のモニタリングページを使用します。デフォルトでは、Lambda コンソールには、関数コードがイベントの処理に費やした平均、最小、最大時間を示す期間グラフが表示されます。Lambda 関数のモニタリングの詳細については、Lambda デベロッパーガイドの「Lambda コンソールでの関数のモニタリング」を参照してください。

Lambda 関数の同時実行を既にプロビジョニングしていて、それをモニタリングする場合は、「Lambda デベロッパーガイド」の「同時実行のモニタリング」を参照してください。