使用 AWS Lambda 權杖自動售貨機實作 Amazon S3 的 SaaS 租用戶隔離 - AWS Prescriptive Guidance

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 AWS Lambda 權杖自動售貨機實作 Amazon S3 的 SaaS 租用戶隔離

由塔比沃德 (AWS)、斯拉文周邊 (AWS) 和托馬斯·戴維斯 (AWS) 所建立

環境:PoC 或試驗

技術:現代化;SaaS

AWS 服務:AWS Identity and Access Management;AWS Lambda;AWS STS

Summary

多組織用戶共享 SaaS 應用程式必須實作系統,以確保保持租用戶隔離。當您將租用戶資料存放在同一個 Amazon Web Services (AWS) 資源上時,例如將資料存放在同一個 Amazon Simple Storage Service (Amazon S3) 中的多個租用戶,您必須確保無法進行跨租用戶存取。代幣自動販賣機(TVM)是保證租戶數據隔離的一種方法。這些機器提供了獲取令牌的機制,同時抽象如何生成這些令牌的複雜性。開發人員可以使用 TVM,而無需詳細了解它如何生成令牌。

這種模式使用 AWS Lambda 實現了一個 TVM。TVM 會產生一個由暫時安全性權杖服務 (STS) 認證所組成的權杖,這些權杖會限制對 S3 儲存貯體中單一 SaaS 租用戶資料的存取。

TVM 以及此模式提供的程式碼通常會與衍生自 JSON Web 令牌 (JWT) 的宣告搭配使用,以便將 AWS 資源的請求與承租人範圍的 AWS Identity and Access Management (IAM) 政策建立關聯。您可以使用此模式中的程式碼做為基礎,以實作 SaaS 應用程式,該應用程式會根據 JWT Token 中提供的宣告產生範圍的臨時 STS 認證。

先決條件和限制

先決條件

限制

  • 此程式碼以 Java 執行,目前不支援其他程式設計語言。 

  • 範例應用程式不包含 AWS 跨區域或災難復原 (DR) 支援。 

  • 此模式示範 SaaS 應用程式的 Lambda TVM 如何提供範圍的租用戶存取權。它不打算在生產環境中使用。

Architecture

目標技術堆疊

  • AWS Lambda

  • Amazon S3

  • IAM

  • AWS Security Token Service (AWS STS)

目標架構

Tools

AWS 服務

  • AWS CLI— AWS Command Line Interface (AWS CLI) 是一種統一的工具,可使用命令列 shell 中的命令與 AWS 服務互動。

  • AWS Lambda— AWS Lambda 可讓您執行程式碼,無需佈建或管理伺服器。您只需為使用的運算時間支付費用。

  • Amazon S3— Amazon S3 是一種物件儲存服務,提供可擴展性、資料可用性、資料可用性、安全性和效能。

  • IAM— AWS Identity and Access Management (IAM) 是一種 Web 服務,可以安全地控制 AWS 服務的存取。

  • AWS STS-AWS Security Token Service (AWS STS) 可讓您為 IAM 使用者或您驗證身分的使用者 (聯合身分使用者) 請求臨時的登入資料。

Code

此病毒碼的原始程式碼可作為附件使用,並包含下列檔案:

  • s3UploadSample.jar提供了 Lambda 函數的源代碼,該函數將 JSON 文檔上傳到 S3 存儲桶。

  • tvm-layer.zip提供了一個可重複使用的 Java 庫,該庫為 Lambda 函數提供一個令牌(STS 臨時憑據),以訪問 S3 存儲桶並上傳 JSON 文檔。

  • token-vending-machine-sample-app.zip提供了用於創建這些工件和編譯指令的源代碼。

若要使用這些檔案,請遵循下一節中的指示。

Epics

任務描述所需技能
決定變數值。

這種模式的實現需要包括幾個必須一致使用的變量名稱。決定每個變數應使用的值,並在後續步驟中要求時提供該值。

<AWS Account ID>─與您實作此模式之 AWS 帳戶相關聯的 12 位數帳戶 ID。如需有關如何尋找 AWS cccount ID 的資訊,請參閱您的 AWS 帳戶 ID 和其別名在 IAM 文件中。

<AWS Region>─您正在實作此模式的 AWS 區域。如需 AWS 區域的詳細資訊,請參閱區域與可用區域在 AWS 網站上。

<sample-tenant-name>─要在應用程式中使用的承租人名稱。為了簡單起見,我們建議您在此值中僅使用英數字元,但您可以使用任何S3 物件金鑰的有效名稱

<sample-tvm-role-name>─附加至執行 TVM 和範例應用程式之 Lambda 函數的 IAM 角色名稱。角色名稱是由大小寫英數字元組成且不含空格的字串。您也可以包含下列任何字元:底線 (_)、加號 (+)、等號 (=)、逗號 (,)、逗號 (,)、句點 (.) 和連字號 (-)。角色名稱在帳戶內必須是唯一的。

<sample-app-role-name>─Lambda 函數產生限定範圍的暫時 STS 認證時,所假設的 IAM 角色名稱。角色名稱是由大小寫英數字元組成且不含空格的字串。您也可以包含下列任何字元:底線 (_)、加號 (+)、等號 (=)、逗號 (,)、逗號 (,)、句點 (.) 和連字號 (-)。角色名稱在帳戶內必須是唯一的。

<sample-app-function-name>─Lambda 函數的名稱。這是長度最多可達 64 個字元的字串。

<sample-app-bucket-name>─必須以特定承租人範圍的權限存取 S3 儲存貯體的名稱。S3 儲存貯體名稱:

  • 長度必須介於 3 與 63 個字元之間。

  • 必須只包含小寫字母、數字、句點 (.) 和連字號 (-)。

  • 開頭和結尾必須為字母或數字。

  • 不得採用 IP 地址格式 (例如,192.168.5.4)。

  • 在分割區內必須是唯一的。分割區是區域的群組。AWS 目前有三個分割區:aws (標準區域)、aws-cn(中國地區) 及aws-us-gov(AWS GovCloud [美國] 區域)。

雲端管理員
任務描述所需技能
為範例應用程式建立 S3 儲存貯體。

使用下列 AWS CLI 命令建立 S3 儲存貯體。提供<sample-app-bucket-name>在代碼片段中的值:

aws s3api create-bucket --bucket <sample-app-bucket-name>

Lambda 範例應用程式會將 JSON 檔案上傳至此儲存貯體。

雲端管理員
任務描述所需技能
建立 TVM 角色。

使用以下其中一個 AWS CLI 命令來建立 IAM 角色。提供<sample-tvm-role-name>值。

macOS 或 Linux 殼層:

aws iam create-role --role-name <sample-tvm-role-name> --assume-role-policy-document '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

對於視窗命令列:

aws iam create-role --role-name <sample-tvm-role-name> --assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Principal\": {\"Service\": \"lambda.amazonaws.com\"}, \"Action\": \"sts:AssumeRole\"}]}"

Lambda 範例應用程式會在呼叫應用程式時假設此角色。假設應用程式角色具有範圍的原則的功能,可讓程式碼更廣泛的存取 S3 儲存貯體。

雲端管理員
建立內嵌 TVM 角色原則。

使用以下其中一個 AWS CLI 命令來建立 IAM 政策。提供<sample-tvm-role-name><AWS Account ID>,以及<sample-app-role-name>值。

macOS 或 Linux 殼層:

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>"}]}'

對於視窗命令列:

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>\"}]}"

此政策會連接至 TVM 角色。它可讓程式碼擔任應用程式角色的能力,該角色擁有更廣泛的存取 S3 儲存貯體。

雲端管理員
附加受管理的 Lambda 原則。

使用下列 AWS CLI 命令連接AWSLambdaBasicExecutionRole IAM 政策。提供<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

此受管政策附加至 TVM 角色,以允許 Lambda 將日誌傳送至 Amazon CloudWatch。

雲端管理員
任務描述所需技能
建立應用程式角色。

使用以下其中一個 AWS CLI 命令來建立 IAM 角色。提供<sample-app-role-name><AWS Account ID>,以及<sample-tvm-role-name>值。

macOS 或 Linux 殼層:

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"}]}'

對於視窗命令列:

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 命令來建立 IAM 政策。提供<sample-app-role-name><sample-app-bucket-name>值。

macOS 或 Linux 殼層:

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>"}]}'

對於視窗命令列:

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.jartvm-layer.zip 文件,這些文件作為附件包含在內。用於創建這些工件和編譯實現的源代碼提供在token-vending-machine-sample-app.zip

雲端管理員
建立 Lambda 圖層。

使用下列 AWS CLI 命令建立一個 Lambda 層,這使得 Lambda 可以存取 TVM。 

請注意:如果您沒有從下載 tvm-layer.zip,請提供正確的路徑tvm-layer.zip中的--zip-file參數。 

aws lambda publish-layer-version --layer-name sample-token-vending-machine --compatible-runtimes java11 --zip-file fileb://tvm-layer.zip

這個命令會建立一個 Lambda 層,其中包含可重複使用的 TVM 程式庫。

雲端管理員,應用程式開發人員
建立 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,請提供正確的路徑s3UploadSample.jar中的--zip-file參數。 

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>}"

這個命令會建立 Lambda 函數,並附加了範例應用程式碼和 TVM 層。它還設置兩個環境變量:S3_BUCKETROLE。範例應用程式會使用這些變數來決定要假設的角色,以及上傳 JSON 文件的 S3 儲存貯體。

雲端管理員,應用程式開發人員
任務描述所需技能
叫用 Lambda 範例應用程式。

使用以下其中一個 AWS CLI 命令,使用其預期的承載來啟動 Lambda 範例應用程式。提供<sample-app-function-name><sample-tenant-name>值。

macOS 和 Linux shell:

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

對於視窗命令列:

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.jsondocument. 在許多 Unix 系統上,您可以將response.json/dev/stdout將結果直接輸出到 shell 而不創建另一個文件。 

請注意:變更<sample-tenant-name>值會改變 JSON 文件的位置和權杖提供的權限。

雲端管理員,應用程式開發人員
查看 S3 存儲桶以查看創建的對象。

瀏覽至 S3 儲存貯體 (<sample-app-bucket-name>) 您先前建立的。該存儲桶包含一個 S3 對象前綴,其值為<sample-tenant-name>。在該前綴下,你會發現一個用 UUID 命名的 JSON 文檔。多次叫用範例應用程式會新增更多 JSON 文件。

雲端管理員
檢視範例應用程式的 Cloudwatch 記錄檔。

檢視與 Lambda 為<sample-app-function-name>。如需說明,請參閱「」存取 AWS Lambda 的 Amazon CloudWatch Logs在 AWS Lambda 文件中。您可以在這些記錄檔中檢視 TVM 產生的承租人範圍原則。此承租人範圍政策將範例應用程式的權限提供給 Amazon S3PutObjectGetObjectDeleteObject,以及ListBucketAPI,但僅適用於與<sample-tenant-name>。在後續的範例應用程式呼叫中,如果您變更<sample-tenant-name>時,TVM 會更新範圍的原則,以對應於呼叫內容中提供的租用戶。此動態產生的原則顯示如何在 SaaS 應用程式中透過 TVM 維護承租人範圍的存取。 

TVM 功能是在 Lambda 層中提供,因此它可以附加到應用程式使用的其他 Lambda 函數,而不需要複寫程式碼。

如需動態產生之原則的圖例,請參閱其他資訊區段。

雲端管理員

相關資源

其他資訊

下列 Amazon Cloudwatch 日誌顯示 TVM 程式碼以此模式產生的動態產生的政策。在此螢幕擷取畫面中,<sample-app-bucket-name>DOC-EXAMPLE-BUCKET<sample-tenant-name>test-tenant-1。此範圍原則所傳回的 STS 認證無法對 S3 儲存貯體中的物件執行任何動作,但與物件索 key prefix 相關聯的物件除外test-tenant-1

Attachments

attachment.zip