

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

# AWS Lambda トークン自動販売機を使用して Amazon S3 の SaaS テナント分離を実装する
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine"></a>

*Amazon Web Services、Tabby Ward、Thomas Davis、および Sravan Periyathambi*

## 概要
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-summary"></a>

マルチテナントSaaSアプリケーションは、テナントの分離が維持されるようにシステムを実装する必要があります。複数のテナントが同じ Amazon Simple Storage Service (Amazon S3) バケットにデータを保存する場合など、テナントデータを同じ AWS リソースに保存する場合は、クロステナントアクセスが発生しないようにする必要があります。トークン自動販売機 (TVM) は、テナントデータを分離する 1 つの方法です。これらのマシンは、トークンの生成方法の複雑さを抽象化しながら、トークンを取得するメカニズムを提供します。開発者は、TVM がどのようにトークンを生成するかについての詳細な知識がなくても使用できます。

このパターンは、 を使用して TVM を実装します AWS Lambda。TVM は、S3 バケット内の 1 つの SaaS テナントのデータへのアクセスを制限する一時的なセキュリティトークンサービス (STS) 認証情報で構成されるトークンを生成します。

TVMsおよびこのパターンで提供されるコードは、通常、JSON ウェブトークン (JWTs) から派生したクレームで使用され、 AWS リソースのリクエストをテナントスコープ AWS Identity and Access Management (IAM) ポリシーに関連付けます。このパターンのコードを基礎として使用して、JWT トークンで提供されるクレームに基づいてスコープ付きの一時的な STS 認証情報を生成する SaaS アプリケーションを実装できます。

## 前提条件と制限事項
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-prereqs"></a>

**前提条件**
+ アクティブ AWS アカウント。
+ AWS Command Line Interface (AWS CLI) [バージョン 1.19.0 以降](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)。macOS、Linux、または Windows にインストールおよび設定されています。または、 AWS CLI [バージョン 2.1 以降](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)を使用することもできます。

**制限事項**
+ このコードは Java で実行され、現在他のプログラミング言語はサポートされていません。 
+ サンプルアプリケーションには、 AWS クロスリージョンまたはディザスタリカバリ (DR) サポートは含まれません。 
+ このパターンは、SaaS アプリケーション用の Lambda TVM がスコープ付きのテナントアクセスを提供する方法を示しています。このパターンは、特定のアプリケーションまたはユースケースの一部として追加のセキュリティテストを行わずに本番環境で使用することを意図したものではありません。

## アーキテクチャ
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-architecture"></a>

**ターゲットテクノロジースタック**
+ AWS Lambda
+ Amazon S3
+ IAM
+ AWS Security Token Service (AWS STS)

**ターゲットアーキテクチャ**

![\[S3 バケット内のデータにアクセスするための一時的な STS 認証情報を取得するためのトークンを生成します。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/14d0508a-703b-4229-85e6-c5094de7fe01.png)


 

## ツール
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-tools"></a>

**AWS のサービス**
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) は、コマンドラインシェルのコマンド AWS のサービス を使用して を操作するのに役立つオープンソースツールです。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) は、誰を認証し、誰に使用する権限を付与するかを制御することで、 AWS リソースへのアクセスを安全に管理するのに役立ちます。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [AWS Security Token Service (AWS STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) は、ユーザーの権限が制限された一時的な認証情報をリクエストするのに役立ちます。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、あらゆる量のデータを保存、保護、取得できるクラウドベースのオブジェクトストレージサービスです。

**コード**

このパターンのソースコードは添付ファイルとして提供され、以下のファイルが含まれています。
+ `s3UploadSample.jar`は、JSON ドキュメントを S3 バケットにアップロードする Lambda 関数のソースコードを提供します。
+ `tvm-layer.zip`には、Lambda 関数が S3 バケットにアクセスして JSON ドキュメントをアップロードするためのトークン (STS 一時認証情報) を提供する再利用可能な Java ライブラリが用意されています。
+ `token-vending-machine-sample-app.zip`は、これらのアーティファクトの作成に使用されるソースコードとコンパイル手順を提供します。

これらのファイルを使用するには、次のセクションの指示に従います。

## エピック
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-epics"></a>

### 可変値の決定
<a name="determine-variable-values"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 可変値を決定します。 | このパターンの実装には、一貫して使用しなければならない変数名がいくつか含まれています。各変数に使用すべき値を決定し、以降のステップで要求されたらその値を指定します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine.html) | クラウド管理者 | 

### S3 バケットを作成する
<a name="create-an-s3-bucket"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| サンプルアプリケーション用の S3 バケット環境を作成します。 | S3 バケットを作成するには、次の AWS CLI コマンドを使用します。コードスニペットで `<sample-app-bucket-name>`** **の値を指定します。<pre>aws s3api create-bucket --bucket <sample-app-bucket-name></pre>Lambda サンプルアプリケーションは JSON ファイルをこのバケットにアップロードします。 | クラウド管理者 | 

### IAM TVM ロールとポリシーを作成する
<a name="create-the-iam-tvm-role-and-policy"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| TVM ロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで `<sample-tvm-role-name>`** **値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam create-role \<br />--role-name <sample-tvm-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Action": [<br />                "sts:AssumeRole"<br />            ],<br />            "Principal": {<br />                "Service": [<br />                    "lambda.amazonaws.com"<br />                ]<br />            },<br />            "Condition": {<br />                "StringEquals": {<br />                    "aws:SourceAccount": "<AWS Account ID>"<br />                }<br />            }<br />        }<br />    ]<br />}'</pre>Windows コマンドラインの場合：<pre>aws iam create-role ^<br />--role-name <sample-tvm-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"sts:AssumeRole\"], \"Principal\": {\"Service\": [\"lambda.amazonaws.com\"]}, \"Condition\": {\"StringEquals\": {\"aws:SourceAccount\": \"<AWS Account ID>\"}}}]}"</pre>Lambda サンプルアプリケーションは、アプリケーションが呼び出されるとこのロールを引き受けます。スコープポリシーを使用してアプリケーションロールを引き受けることができるため、S3 バケットにアクセスするための幅広いアクセス権限がコードに付与されます。 | クラウド管理者 | 
| インライン TVM ロールポリシーを作成します。 | IAM ポリシーを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで、`<sample-tvm-role-name>`、****`<AWS Account ID>`、および `<sample-app-role-name>` の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam put-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-name assume-app-role \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": "sts:AssumeRole", <br />            "Resource": "arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam put-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-name assume-app-role ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"sts:AssumeRole\", \"Resource\": \"arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>\"}]}"</pre>このポリシーは、TVM ロールにアタッチされます。これにより、S3 バケットにアクセスするための幅広い権限を持つアプリケーションロールを引き受けることができるようコードに付与されます。 | クラウド管理者 | 
| マネージド Lambda ポリシーをアタッチします。 | IAM ポリシーを`AWSLambdaBasicExecutionRole`アタッチするには、次の AWS CLI コマンドを使用します。コマンドで `<sample-tvm-role-name>` 値を指定します。<pre>aws iam attach-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>Windows コマンドラインの場合：<pre>aws iam attach-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>この管理ポリシーは TVM ロールにアタッチされ、Lambda が Amazon CloudWatch にログを送信することを許可します。 | クラウド管理者 | 

### IAM アプリケーションロールとポリシーを作成する。
<a name="create-the-iam-application-role-and-policy"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| アプリケーションロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで、`<sample-app-role-name>`、`<AWS Account ID>`、および `<sample-tvm-role-name>` の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam create-role \<br />--role-name <sample-app-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": <br />            "Allow",<br />            "Principal": {<br />                "AWS": "arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>"<br />            },<br />            "Action": "sts:AssumeRole"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam create-role ^<br />--role-name <sample-app-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>\"},\"Action\": \"sts:AssumeRole\"}]}"</pre>Lambda サンプルアプリケーションは、S3 バケットへのテナントベースのアクセスを取得するためのスコープポリシーを使用してこのロールを引き受けます。 | クラウド管理者 | 
| インラインアプリケーションロールポリシーを作成します。 | 次のいずれかの AWS CLI mmands を使用して IAM ポリシーを作成します。コマンドで、`<sample-app-role-name>` および `<sample-app-bucket-name>`** ** の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam put-role-policy \<br />--role-name <sample-app-role-name> \<br />--policy-name s3-bucket-access \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": [<br />                "s3:PutObject", <br />                "s3:GetObject", <br />                "s3:DeleteObject"<br />            ], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>/*"<br />        }, <br />        {<br />            "Effect": "Allow", <br />            "Action": ["s3:ListBucket"], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam put-role-policy ^<br />--role-name <sample-app-role-name> ^<br />--policy-name s3-bucket-access ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\", \"s3:DeleteObject\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>/*\"}, {\"Effect\": \"Allow\", \"Action\": [\"s3:ListBucket\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>\"}]}"</pre>このポリシーは、アプリケーションロールにアタッチされます。S3 バケット内のオブジェクトに幅広くアクセスできます。サンプルアプリケーションが役割を引き受けると、これらの権限は TVM の動的に生成されたポリシーによって特定のテナントに限定されます。 | クラウド管理者 | 

### TVM を使用して Lambda サンプルアプリケーションを作成する
<a name="create-the-lam-sample-application-with-tvm"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| コンパイルされたソースファイルをダウンロードします。 | 添付ファイルとして含まれている`s3UploadSample.jar`および`tvm-layer.zip`** **ファイルをダウンロードします。これらのアーティファクトの作成に使用されたソースコードとコンパイル手順は、`token-vending-machine-sample-app.zip`に記載されています。 | クラウド管理者 | 
| Lambda コードを作成します。 | 次の AWS CLI コマンドを使用して Lambda レイヤーを作成します。これにより、TVM が Lambda にアクセスできるようになります。 ` tvm-layer.zip` をダウンロードした場所からこのコマンドを実行しない場合は、`--zip-file` パラメータに `tvm-layer.zip` への正しいパスを指定してください。 <pre>aws lambda publish-layer-version \<br />--layer-name sample-token-vending-machine \<br />--compatible-runtimes java11 \<br />--zip-file fileb://tvm-layer.zip</pre>Windows コマンドラインの場合：<pre>aws lambda publish-layer-version ^<br />--layer-name sample-token-vending-machine ^<br />--compatible-runtimes java11 ^<br />--zip-file fileb://tvm-layer.zip</pre>このコマンドは、再利用可能な TVM ライブラリを含む Lambda レイヤーを作成します。 | クラウド管理者、アプリ開発者 | 
| Lambda 関数の作成 | 次の AWS CLI コマンドを使用して Lambda 関数を作成します。コマンドで、`<sample-app-function-name>`、`<AWS Account ID>`、`<AWS Region>`、`<sample-tvm-role-name>`、`<sample-app-bucket-name>`、および `<sample-app-role-name>` の値を指定します。 `s3UploadSample.jar` をダウンロードした場所からこのコマンドを実行しない場合は、`--zip-file` パラメータに `s3UploadSample.jar` への正しいパスを指定してください。 <pre>aws lambda create-function \<br />--function-name <sample-app-function-name>  \<br />--timeout 30 \<br />--memory-size 256 \<br />--runtime java11 \<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> \<br />--handler com.amazon.aws.s3UploadSample.App \<br />--zip-file fileb://s3UploadSample.jar \<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 \<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,<br />ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>Windows コマンドラインの場合：<pre>aws lambda create-function ^<br />--function-name <sample-app-function-name>  ^<br />--timeout 30 ^<br />--memory-size 256 ^<br />--runtime java11 ^<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> ^<br />--handler com.amazon.aws.s3UploadSample.App ^<br />--zip-file fileb://s3UploadSample.jar ^<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 ^<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>このコマンドは、サンプルアプリケーションコードと TVM レイヤーをアタッチした Lambda 関数を作成します。また、`S3_BUCKET`と`ROLE`の 2 つの環境変数も設定します。サンプルアプリケーションでは、これらの変数を使用して、引き受けるロールと JSON ドキュメントをアップロードする S3 バケットを決定します。 | クラウド管理者、アプリ開発者 | 

### サンプルアプリケーションをデプロイしてテストする
<a name="test-the-sample-application-and-tvm"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda サンプルアプリケーションを呼び出します。 | 次のいずれかの AWS CLI コマンドを使用して、予想されるペイロードで Lambda サンプルアプリケーションを起動します。コマンドで、`<sample-app-function-name>` および `<sample-tenant-name>` の値を指定します。macOS および Linux システムの場合：<pre>aws lambda invoke \<br />--function <sample-app-function-name> \<br />--invocation-type RequestResponse \<br />--payload '{"tenant": "<sample-tenant-name>"}' \<br />--cli-binary-format raw-in-base64-out response.json</pre>Windows コマンドラインの場合：<pre>aws lambda invoke ^<br />--function <sample-app-function-name> ^<br />--invocation-type RequestResponse ^<br />--payload "{\"tenant\": \"<sample-tenant-name>\"}" ^<br />--cli-binary-format raw-in-base64-out response.json</pre>このコマンドは Lambda 関数を呼び出し、結果を`response.json`ドキュメントに返します。多くの UNIX ベースのシステムでは、`response.json`を`/dev/stdout`に変更すると、別のファイルを作成せずに結果をシェルに直接出力できます。 この Lambda 関数の後続の呼び出しで `<sample-tenant-name>` の値を変更すると、JSON ドキュメントの場所とトークンが提供するアクセス許可が変更されます。 | クラウド管理者、アプリ開発者 | 
| S3 バケットを表示して、作成されたオブジェクトを確認します。 | 先ほど作成した S3 バケット（`<sample-app-bucket-name>`）を参照します。このバケットには、`<sample-tenant-name>` 値の S3 オブジェクトのプレフィックスが含まれています。そのプレフィックスの下に、UUID が付いた名前の JSON ドキュメントがあります。サンプルアプリケーションを複数回呼び出すと、JSON ドキュメントがさらに追加されます。 | クラウド管理者 | 
| CloudWatch Logs でサンプルアプリケーションのログを表示します。 | CloudWatch Logs で `<sample-app-function-name>` という名前の Lambda 関数に関連付けられているログを表示します。手順については、Lambda ドキュメントの「[Lambda 関数ログを CloudWatch Logs に送信する](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html)」を参照してください。TVM によって生成されたテナントスコープのポリシーは、これらのログで確認できます。このテナントを対象とするポリシーは、Amazon S3 「**PutObject**」、「**GetObject**」、「**DeleteObject**」および「**ListBucket**」 の API にサンプルアプリケーションのアクセス許可を付与しますが、`<sample-tenant-name>` に関連するオブジェクトプレフィックスのアクセス許可のみを付与します。それ以降のサンプルアプリケーションの呼び出しで `<sample-tenant-name>` を変更すると、TVM は呼び出しペイロードで指定されたテナントに対応するスコープポリシーを更新します。この動的に生成されたポリシーは、SaaS アプリケーションで TVM を使用してテナントスコープのアクセスを維持する方法を示しています。 TVM 機能は Lambda レイヤーで提供されるため、コードを複製しなくても、アプリケーションで使用される他の Lambda 関数に接続できます。動的に生成されるポリシーの図については、「[追加情報](#implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional)」セクションを参照してください。 | クラウド管理者 | 

## 関連リソース
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-resources"></a>
+ [動的に生成される IAM ポリシーによるテナントの分離 (ブログ記事](https://aws.amazon.com/blogs/apn/isolating-saas-tenants-with-dynamically-generated-iam-policies/))
+ [Applying Dynamically Generated Isolation Policies in SaaS Environments](https://aws.amazon.com/blogs/apn/applying-dynamically-generated-isolation-policies-in-saas-environments/) (ブログ記事)
+ [での SaaS AWS](https://aws.amazon.com/saas/)

## 追加情報
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional"></a>

次のログは、このパターンで TVM コードによって生成された、動的に生成されたポリシーを示しています。このスクリーンショットでは、`<sample-app-bucket-name>` は `DOC-EXAMPLE-BUCKET` で、`<sample-tenant-name>` は `test-tenant-1` となります。このスコープポリシーによって返される STS 認証情報は、オブジェクトkey prefix `test-tenant-1` に関連付けられているオブジェクトを除き、S3 バケット内のオブジェクトに対してアクションを実行できません。

![\[TVM コードによって生成された、動的に生成されたポリシーを示すログ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/d4776ebe-fb8f-41ac-b8c5-b4f97a821c8c.png)


## アタッチメント
<a name="attachments-97a34c8e-d04e-40b6-acbf-1baa176d22a9"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「[attachment.zip](samples/p-attach/97a34c8e-d04e-40b6-acbf-1baa176d22a9/attachments/attachment.zip)」