翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
AWS Lambda トークン自動販売機を使用して Amazon S3 の SaaS テナント分離を実装する
Tabby Ward、Thomas Davis、Sravan Periyathambi、Amazon Web Services
概要
マルチテナント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 アプリケーションを実装できます。
前提条件と制限
前提条件
機能制限
このコードは Java で実行され、現在他のプログラミング言語はサポートされていません。
サンプルアプリケーションには、 AWS クロスリージョンまたはディザスタリカバリ (DR) サポートは含まれません。
このパターンは、SaaS アプリケーション用の Lambda TVM がスコープ付きのテナントアクセスを提供する方法を示しています。このパターンは、特定のアプリケーションまたはユースケースの一部として追加のセキュリティテストなしで本番環境で使用することを意図していません。
アーキテクチャ
ターゲットテクノロジースタック
ターゲット アーキテクチャ
AWS のサービス
コード
このパターンのソースコードは添付ファイルとして提供され、以下のファイルが含まれています。
s3UploadSample.jarは、JSON ドキュメントを S3 バケットにアップロードする Lambda 関数のソースコードを提供します。
tvm-layer.zipには、Lambda 関数が S3 バケットにアクセスして JSON ドキュメントをアップロードするためのトークン (STS 一時認証情報) を提供する再利用可能な Java ライブラリが用意されています。
token-vending-machine-sample-app.zipは、これらのアーティファクトの作成に使用されるソースコードとコンパイル手順を提供します。
これらのファイルを使用するには、次のセクションの指示に従います。
エピック
| タスク | 説明 | 必要なスキル |
|---|
可変値を決定します。 | このパターンの実装には、一貫して使用しなければならない変数名がいくつか含まれています。各変数に使用すべき値を決定し、以降のステップで要求されたらその値を指定します。 <AWS Account ID> ─ このパターン AWS アカウント を実装する に関連付けられている 12 桁のアカウント ID。 AWS アカウント ID を検索する方法については、IAM ドキュメントの AWS アカウント 「ID のエイリアスの使用」を参照してください。
<AWS Region> ─ このパターンを実装 AWS リージョン する 。詳細については AWS リージョン、 AWS ウェブサイトの「リージョンとアベイラビリティーゾーン」を参照してください。
<sample-tenant-name> ─ アプリケーションで使用するテナントの名前。わかりやすくするためにこの値には英数字のみを使用することをお勧めしますが、「S3 オブジェクトキーの有効な名前」を使用できます。
<sample-tvm-role-name> ─ TVM とサンプルアプリケーションを実行する Lambda 関数にアタッチされた IAM ロールの名前。ロール名は、スペースを含まない大文字と小文字の英数字からなる文字列です。カンマ (,)、ピリオド (.)、アットマーク (@)、アンダースコア (_)、等号 (=)、プラス記号 (+) を含めることもできます。ロール名はアカウント内で一意である必要があります。
<sample-app-role-name> ─ スコープ付きの一時的な STS 認証情報を生成するときに Lambda 関数が引き受ける IAM ロールの名前。ロール名は、スペースを含まない大文字と小文字の英数字からなる文字列です。カンマ (,)、ピリオド (.)、アットマーク (@)、アンダースコア (_)、等号 (=)、プラス記号 (+) を含めることもできます。ロール名はアカウント内で一意である必要があります。
<sample-app-function-name> ─ Lambda 関数の名前。これは最大長が 64 文字の文字列です。
<sample-app-bucket-name> ─ 特定のテナントを対象とするアクセス許可でアクセスする必要がある S3 バケットの名前。S3 バケット名*
3~63 文字の長さにする。 小文字、数字、ピリオド (.)、ハイフン (-) のみで構成されるようにしてください。 名前の最初と最後は、文字または数字でなければなりません。 IP アドレスの形式 (例: 192.168.5.4) にすることはできません。 パーティション内で一意にする必要があります。パーティションは Regions のグループです。 AWS 現在、 には 3 つのパーティションがあります。標準リージョンawsの場合は 、中国リージョンaws-cnの場合は 、 aws-us-gov の場合は です AWS GovCloud (US) Regions。
| クラウド管理者 |
| タスク | 説明 | 必要なスキル |
|---|
サンプルアプリケーション用の S3 バケット環境を作成します。 | S3 バケットを作成するには、次の AWS CLI コマンドを使用します。コードスニペット<sample-app-bucket-name>の値を指定します。 aws s3api create-bucket --bucket <sample-app-bucket-name>
Lambda サンプルアプリケーションは JSON ファイルをこのバケットにアップロードします。 | クラウド管理者 |
| タスク | 説明 | 必要なスキル |
|---|
TVM ロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで <sample-tvm-role-name>値を指定します。 macOS または Linux 上の Bash シェルの場合: aws iam create-role \
--role-name <sample-tvm-role-name> \
--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>"
}
}
}
]
}'
Windows コマンドラインの場合: aws iam create-role ^
--role-name <sample-tvm-role-name> ^
--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>\"}}}]}"
Lambda サンプルアプリケーションは、アプリケーションが呼び出されるとこのロールを引き受けます。スコープポリシーを使用してアプリケーションロールを引き受けることができるため、S3 バケットにアクセスするための幅広いアクセス権限がコードに付与されます。 | クラウド管理者 |
インライン TVM ロールポリシーを作成します。 | 次のいずれかの AWS CLI コマンドを使用して、IAM ポリシーを作成します。コマンドで、<sample-tvm-role-name><AWS Account ID>、、および <sample-app-role-name>の値を指定します。 macOS または Linux 上の Bash シェルの場合: aws iam put-role-policy \
--role-name <sample-tvm-role-name> \
--policy-name assume-app-role \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>"
}
]}'
Windows コマンドラインの場合: aws iam put-role-policy ^
--role-name <sample-tvm-role-name> ^
--policy-name assume-app-role ^
--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"sts:AssumeRole\", \"Resource\": \"arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>\"}]}"
このポリシーは、 マネージドのロール にアタッチされます。これにより、S3 バケットにアクセスするための幅広い権限を持つアプリケーションロールを引き受けることができるようコードに付与されます。 | クラウド管理者 |
マネージド Lambda ポリシーをアタッチします。 | IAM ポリシーをAWSLambdaBasicExecutionRoleアタッチするには、次の AWS CLI コマンドを使用します。コマンドで <sample-tvm-role-name>値を指定します。 aws iam attach-role-policy \
--role-name <sample-tvm-role-name> \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Windows コマンドラインの場合: aws iam attach-role-policy ^
--role-name <sample-tvm-role-name> ^
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
この管理ポリシーは TVM ロールにアタッチされ、Lambda が Amazon CloudWatch にログを送信することを許可します。 | クラウド管理者 |
| タスク | 説明 | 必要なスキル |
|---|
アプリケーションロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで <sample-app-role-name>、<AWS Account ID>、および <sample-tvm-role-name>の値を指定します。 macOS または Linux 上の Bash シェルの場合: aws iam create-role \
--role-name <sample-app-role-name> \
--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"
}
]}'
Windows コマンドラインの場合: aws iam create-role ^
--role-name <sample-app-role-name> ^
--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\"}]}"
Lambda サンプルアプリケーションは、S3 バケットへのテナントベースのアクセスを取得するためのスコープポリシーを使用してこのロールを引き受けます。 | クラウド管理者 |
インラインアプリケーションロールポリシーを作成します。 | 次のいずれかの AWS CLI mmands を使用して IAM ポリシーを作成します。コマンドで <sample-app-role-name>と <sample-app-bucket-name>の値を指定します。 macOS または Linux 上の Bash シェルの場合: aws iam put-role-policy \
--role-name <sample-app-role-name> \
--policy-name s3-bucket-access \
--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>"
}
]}'
Windows コマンドラインの場合: aws iam put-role-policy ^
--role-name <sample-app-role-name> ^
--policy-name s3-bucket-access ^
--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>\"}]}"
このポリシーは、 マネージドのロール にアタッチされます。S3 バケット内のオブジェクトに幅広くアクセスできます。サンプルアプリケーションが役割を引き受けると、これらの権限は TVM の動的に生成されたポリシーによって特定のテナントに限定されます。 | クラウド管理者 |
| タスク | 説明 | 必要なスキル |
|---|
コンパイルされたソースファイルをダウンロードします。 | 添付ファイルとして含まれている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で への正しいパスを指定します。 aws lambda publish-layer-version \
--layer-name sample-token-vending-machine \
--compatible-runtimes java11 \
--zip-file fileb://tvm-layer.zip
Windows コマンドラインの場合: aws lambda publish-layer-version ^
--layer-name sample-token-vending-machine ^
--compatible-runtimes java11 ^
--zip-file fileb://tvm-layer.zip
このコマンドは、再利用可能な TVM ライブラリを含む Lambda レイヤーを作成します。 | クラウド管理者、アプリ開発者 |
Lambda 関数を作成します。 | 次の AWS CLI コマンドを使用して Lambda 関数を作成します。コマンドで <sample-app-function-name>、<AWS Account ID>、<AWS Region>、<sample-app-bucket-name>、、および <sample-tvm-role-name><sample-app-role-name>の値を指定します。 をダウンロードした場所からこのコマンドを実行していない場合はs3UploadSample.jar、 --zip-fileパラメータs3UploadSample.jarに正しいパスを指定します。 aws lambda create-function \
--function-name <sample-app-function-name> \
--timeout 30 \
--memory-size 256 \
--runtime java11 \
--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> \
--handler com.amazon.aws.s3UploadSample.App \
--zip-file fileb://s3UploadSample.jar \
--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 \
--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,
ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"
Windows コマンドラインの場合: aws lambda create-function ^
--function-name <sample-app-function-name> ^
--timeout 30 ^
--memory-size 256 ^
--runtime java11 ^
--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> ^
--handler com.amazon.aws.s3UploadSample.App ^
--zip-file fileb://s3UploadSample.jar ^
--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 ^
--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"
このコマンドは、サンプルアプリケーションコードと TVM レイヤーをアタッチした Lambda 関数を作成します。また、S3_BUCKETとROLEの 2 つの環境変数も設定します。サンプルアプリケーションでは、これらの変数を使用して、引き受けるロールと JSON ドキュメントをアップロードする S3 バケットを決定します。 | クラウド管理者、アプリ開発者 |
| タスク | 説明 | 必要なスキル |
|---|
Lambda サンプルアプリケーションを呼び出します。 | 次のいずれかの AWS CLI コマンドを使用して、予想されるペイロードで Lambda サンプルアプリケーションを起動します。コマンドで <sample-app-function-name>と <sample-tenant-name>の値を指定します。 macOS および Linux システムの場合: aws lambda invoke \
--function <sample-app-function-name> \
--invocation-type RequestResponse \
--payload '{"tenant": "<sample-tenant-name>"}' \
--cli-binary-format raw-in-base64-out response.json
Windows コマンドラインの場合: aws lambda invoke ^
--function <sample-app-function-name> ^
--invocation-type RequestResponse ^
--payload "{\"tenant\": \"<sample-tenant-name>\"}" ^
--cli-binary-format raw-in-base64-out response.json
このコマンドは Lambda 関数を呼び出し、結果をresponse.jsonドキュメントに返します。多くの UNIX ベースのシステムでは、response.jsonを/dev/stdoutに変更すると、別のファイルを作成せずに結果をシェルに直接出力できます。 この Lambda 関数の後続の呼び出し<sample-tenant-name>の値を変更すると、JSON ドキュメントの場所とトークンが提供するアクセス許可が変更されます。 | クラウド管理者、アプリ開発者 |
S3 バケットを表示して、作成されたオブジェクトを確認します。 | 前に作成した S3 バケット (<sample-app-bucket-name>) を参照します。このバケットには、 の値を持つ S3 オブジェクトプレフィックスが含まれています<sample-tenant-name>。そのプレフィックスの下に、UUID が付いた名前の JSON ドキュメントがあります。サンプルアプリケーションを複数回呼び出すと、JSON ドキュメントがさらに追加されます。 | クラウド管理者 |
CloudWatch Logs でサンプルアプリケーションのログを表示します。 | CloudWatch Logs <sample-app-function-name>で という名前の Lambda 関数に関連付けられているログを表示します。手順については、Lambda ドキュメントのCloudWatch Logs への Lambda 関数ログの送信」を参照してください。TVM によって生成されたテナントスコープのポリシーは、これらのログで確認できます。このテナントスコープポリシーは、サンプルアプリケーションのアクセス許可を Amazon S3 PutObject、GetObject、DeleteObject、ListBucket APIs に付与しますが、 に関連付けられているオブジェクトプレフィックスにのみ付与します<sample-tenant-name>。以降のサンプルアプリケーションの呼び出しで を変更すると<sample-tenant-name>、TVM は呼び出しペイロードで指定されたテナントに対応するようにスコープポリシーを更新します。この動的に生成されたポリシーは、SaaS アプリケーションで TVM を使用してテナントスコープのアクセスを維持する方法を示しています。 TVM 機能は Lambda レイヤーで提供されるため、コードを複製しなくても、アプリケーションで使用される他の Lambda 関数に接続できます。 動的に生成されるポリシーの図については、「追加情報」セクションを参照してください。 | クラウド管理者 |
関連リソース
追加情報
次のログは、このパターンの TVM コードによって生成された動的に生成されたポリシーを示しています。このスクリーンショットでは、 <sample-app-bucket-name>はDOC-EXAMPLE-BUCKET で、 <sample-tenant-name>は ですtest-tenant-1。このスコープポリシーによって返される STS 認証情報は、オブジェクトkey prefix test-tenant-1 に関連付けられているオブジェクトを除き、S3 バケット内のオブジェクトに対してアクションを実行できません。
添付ファイル
このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「attachment.zip」