

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

# を使用したトークンの検証 AWS Lambda
<a name="reference-smart-on-fhir-token-validation"></a>

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 リクエストを完了するには、次のクレームが必要です。詳細については[必要なクレーム](reference-smart-on-fhir-authentication.md#server-response)を参照してください。
  + `nbf`
  + `exp`
  + `isAuthorized`
  + `aud`
  + `scope`

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

このトピックのセクションでは、クライアントアプリケーションからのリクエスト例とデコードされたレスポンス、 AWS Lambda 関数の作成に必要なステップ、および HealthLake が引き受けることができるリソースベースのポリシーの作成方法について説明します。
+ [パート 1: Lambda 関数の作成](#smart-on-fhir-lambda-create)
+ [パート 2: AWS Lambda 関数で使用される HealthLake サービスロールの作成](#smart-on-fhir-lambda-service-role)
+ [パート 3: Lambda 関数の実行ロールの更新](#smart-on-fhir-lambda-service-role-execution-role)
+ [パート 4: Lambda 関数へのリソースポリシーの追加](#smart-on-fhir-lambda-invoke-healthlake)
+ [パート 5: Lambda 関数の同時実行のプロビジョニング](#smart-on-fhir-lambda-function-scaling)

## AWS Lambda 関数の作成
<a name="smart-on-fhir-lambda-create"></a>

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

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

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

**Example 認可ベアラートークンを含む FHIR REST リクエストの検証**  
Lambda 関数の例は、SMART on FHIR 対応データストアに送信された FHIR REST リクエストを検証する方法を示しています。この Lambda 関数を実装する手順については、 step-by-steps 「」を参照してください[を使用した Lambda 関数の作成 AWS マネジメントコンソール](#create-lambda-console)。  
FHIR REST API リクエストに有効なデータストアエンドポイント、アクセストークン、REST オペレーションが含まれていない場合、Lambda 関数は失敗します。必要な認可サーバー要素の詳細については、「」を参照してください[必要なクレーム](reference-smart-on-fhir-authentication.md#server-response)。  

```
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 関数の作成 AWS マネジメントコンソール
<a name="create-lambda-console"></a>

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

**Lambda 関数を作成するには (AWS マネジメントコンソール)**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home/functions) ページを開きます。

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

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

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

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

   Lambda が、Amazon CloudWatch にログをアップロードする関数許可を付与する[実行ロール](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)を作成します。Lambda 関数は、関数を呼び出すときに実行ロールを引き受け、実行ロールを使用して AWS SDK の認証情報を作成します。

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

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

   ```
   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 関数の実行ロールの変更
<a name="modify-lambda-execution-role"></a>

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

Lambda 関数の実行ロールを変更するには、IAM コンソールで検索するか、Lambda コンソールで**設定**を選択します。Lambda 関数の実行ロールの管理の詳細については、「」を参照してください[Lambda 実行ロール](#smart-on-fhir-lambda-service-role-execution-role)。

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

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:secret-name-DKodTA"
        }
    ]
}
```

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

## JWT のデコードに使用される AWS Lambda 関数で使用する HealthLake サービスロールの作成
<a name="smart-on-fhir-lambda-service-role"></a>

**ペルソナ: IAM 管理者**  
IAM ポリシーを追加または削除し、新しい IAM ID を作成できるユーザー。  

**サービスロール**  
 サービスロールとは、サービスがユーザーに代わってアクションを実行するために引き受ける [IAM ロール](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)です。IAM 管理者は、IAM 内からサービスロールを作成、変更、削除できます。詳細については、IAM ユーザーガイド**の [AWS のサービスに許可を委任するロールを作成する](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)を参照してください。

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

IAM を使用してカスタムポリシーを設定する場合は、必要な最小限のアクセス許可を付与することをお勧めします。詳細については、*IAM ユーザーガイド*の[「最小特権のアクセス許可を適用する](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)」を参照してください。

認可 Lambda 関数で指定する HealthLake サービスロールを作成するには、2 つのステップが必要です。
+ まず、IAM ポリシーを作成する必要があります。ポリシーは、認可サーバーでスコープを指定した FHIR リソースへのアクセスを指定する必要があります。
+ 次に、サービスロールを作成する必要があります。ロールを作成するときは、信頼関係を指定し、ステップ 1 で作成したポリシーをアタッチします。信頼関係はHealthLake をサービスプリンシパルとして指定します。このステップでは、HealthLake データストア ARN と AWS アカウント ID を指定する必要があります。

### 新しい IAM ポリシーの作成
<a name="lambda-service-role-part-1"></a>

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

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

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

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


** HealthLake によって定義されたアクション**  

| アクション | 説明 | アクセスレベル | リソースタイプ (必須) | 
| --- | --- | --- | --- | 
| CreateResource | リソースの作成にアクセス許可を付与します | 書き込み | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| DeleteResource | リソースを削除する許可を付与 | 書き込み | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| ReadResource | リソースを読み取るアクセス許可を付与します | 読み取り | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| SearchWithGet | GET メソッドでリソースを検索する許可を付与 | 読み取り | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| SearchWithPost | POST メソッドでリソースを検索する許可を付与 | 読み取り | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| StartFHIRExportJobWithPost | GET で FHIR エクスポートジョブを開始する許可を付与 | 書き込み | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 
| UpdateResource | リソースを更新する許可を付与 | 書き込み  | データストア ARN: arn:aws:healthlake:your-region:111122223333:datastore/fhir/your-datastore-id | 

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

、、または IAM SDK を使用したカスタムポリシーの作成の詳細については AWS マネジメントコンソール AWS CLI、IAM *ユーザーガイド*の「IAM ポリシー[の作成](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html)」を参照してください。 SDKs

### HealthLake のサービスロールの作成 (IAM コンソール)
<a name="lambda-service-role-part-2"></a>

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

**HealthLake のサービスロールを作成するには (IAM コンソール)**

1. にサインイン AWS マネジメントコンソール し、[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) で IAM コンソールを開きます。

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

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

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

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

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "sts:AssumeRole",
               "Principal": {
                   "Service": "healthlake.amazonaws.com"
               },
               "Condition": {
                   "StringEquals": {
                       "aws:SourceAccount": "123456789012"
                   },
                   "ArnEquals": {
                       "aws:SourceArn": "arn:aws:healthlake:us-east-1:123456789012:datastore/fhir/your-datastore-id"
                   }
               }
           }
       ]
   }
   ```

------

1. その後、**[Next]** を選択します。

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

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

1. 次に**、名前、レビュー、作成**のページで、**ロール名**に名前を入力します。

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

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

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

サンプル Lambda 関数でロール ARN を指定する方法については、「」を参照してください[AWS Lambda 関数の作成](#smart-on-fhir-lambda-create)。

## Lambda 実行ロール
<a name="smart-on-fhir-lambda-service-role-execution-role"></a>

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

デフォルトでは、 を使用して新しい Lambda 関数を作成すると、Lambda は最小限のアクセス許可で実行ロールを作成します AWS マネジメントコンソール。実行ロールで付与されたアクセス許可を管理するには、*Lambda デベロッパーガイド*の[「IAM コンソールでの実行ロールの作成](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html#permissions-executionrole-console)」を参照してください。

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

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

## HealthLake に Lambda 関数のトリガーを許可する
<a name="smart-on-fhir-lambda-invoke-healthlake"></a>

HealthLake がユーザーに代わって Lambda 関数を呼び出すには、以下を実行する必要があります。
+ HealthLake が`CreateFHIRDatastore`リクエストで呼び出す Lambda 関数の ARN と`IdpLambdaArn`等しく設定する必要があります。
+ HealthLake がユーザーに代わって Lambda 関数を呼び出すことを許可するリソースベースのポリシーが必要です。

HealthLake が SMART on FHIR 対応データストアで FHIR REST API リクエストを受信すると、ユーザーに代わってデータストアの作成時に指定された Lambda 関数を呼び出すアクセス許可が必要です。HealthLake アクセスを許可するには、リソースベースのポリシーを使用します。Lambda 関数のリソースベースのポリシーの作成の詳細については、「 *AWS Lambda デベロッパーガイド*[」の「Lambda 関数を呼び出すことを AWS に許可](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke)する」を参照してください。

## Lambda 関数の同時実行のプロビジョニング
<a name="smart-on-fhir-lambda-function-scaling"></a>

**重要**  
HealthLake では、Lambda 関数の最大実行時間が 1 秒 (1000 ミリ秒) 未満である必要があります。  
Lambda 関数が実行時間の制限を超えると、TimeOut 例外が発生します。

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

現在、Lambda 関数の平均実行時間を確認するには、Lambda コンソールの Lambda 関数**のモニタリング**ページを使用します。デフォルトでは、Lambda コンソールには、関数コードがイベントの処理に費やした平均、最小、最大時間を示す**期間**グラフが表示されます。Lambda 関数のモニタリングの詳細については、[Lambda デベロッパーガイドの「Lambda コンソールでの関数のモニタリング](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-access-metrics.html#monitoring-console-graph-types)」を参照してください。 **

Lambda 関数の同時実行を既にプロビジョニングしていて、それをモニタリングする場合は、*Lambda デベロッパーガイド*の[「同時実行のモニタリング](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-concurrency.html)」を参照してください。