什麼是 AWS STS
AWS Security Token Service (STS) 是 Amazon Web Services 提供的一個 Web 服務,用於臨時地提供一組受限的安全憑證。這些憑證允許用戶或應用程式在指定的時間內訪問 AWS 資源,而不需要擁有長期的 AWS 認證。STS 的主要用途包括跨帳戶訪問、臨時升級權限以及移動和 Web 應用程式中的身份聯合(Federation)。
為什麼要用 AWS STS
傳統上,我們都是使用 IAM User 長期的 AWS Access Keys 憑證來訪問 AWS 資源。然而,這種做法存在一些風險:
- 安全問題:User 長期憑證如果洩露,風險極大。
- 管理困難:多個帳戶和角色的長期憑證管理起來相當麻煩。
這時候,AWS STS 就派上用場了。它可以發放臨時憑證,並且這些憑證都有時效性,減少了被濫用的風險。
AWS STS 的主要用途
- 短期存取權限:適合需要臨時存取 AWS 資源的情況,例如執行敏感操作。
- 應用程式存取:應用程式可以通過 STS 取得臨時憑證,避免長期憑證暴露的風險。
- Federation:整合外部身份提供者(如 Google 或 Azure),用戶可以通過外部提供者登入 AWS。
- 跨帳戶存取:讓一個帳戶中的用戶臨時存取其他帳戶中的資源,避免繁瑣的身份管理。
如果你有用過 AWS IAM Identity Center,你會發現這個服務的底層原理也是透過 STS 頒發臨時憑證。
Switching accounts from the User Portal - AWS Blogs
Methods to request credentials from AWS STS - AWS Blogs
AWS STS 是怎麼運作的
成功的 STS 交易會經歷以下的步驟:
- 創建 User 和 Role:AWS 管理員創建一個 IAM User 和一個 IAM Role。User 需被附加
sts:AssumeRole
Policy 使其可以扮演 Role,而 Role 要附加想要給予的 Policy,比如查看 S3 的權限。 - 配置 Trust Policy:管理員為 User 和 Role 配置 Trust Policy。一旦 Trust Policy 被創建,User 可以調用 STS 服務請求該 Role 的憑證。
- 請求扮演 Role:當 User 需要 Role 的權限時,調用 STS API 並請求扮演該 Role。STS 通過檢查適當的 Trust Policy 來驗證請求。
- 生成臨時憑證:STS 動態生成一組新憑證並在 API 回應中發給用戶的應用程式。這些憑證不會存儲在用戶上,只在過期前有效。
- 調用 AWS API:使用剛剛得到的新憑證,調用所需的 AWS API 進行訪問。
如果想要深入淺出了解 STS,可以到 Benefits of ROSA STS 看看他們的講解。
Hands On
接下來,我會演示 AWS STS 資源建置,以及如何透過 STS 賦予臨時憑證,來訪問 S3 資源。
以下操作的 AWS CLI Credentials 預設使用的是系統管理員身份,建立的臨時憑證將會設為 profile 管理。
建立 S3
首先,創建當作示範的 AWS S3,這裡命名為 vince987-sts-demo
,bucket 位置設定在 us-west-2
。
1$ aws s3api create-bucket --bucket vince987-sts-demo --create-bucket-configuration LocationConstraint=us-west-22{3 "Location": "http://vince987-sts-demo.s3.amazonaws.com/"4}
建立 IAM User
我們需要創建 User,這個 User 可以透過 STS 取得臨時憑證,來訪問 S3。
-
創建 IAM User -
temp-user
Terminal window 1$ aws iam create-user --user-name temp-user2{3"User": {4"Path": "/",5"UserName": "temp-user",6"UserId": "AIDAYZKJQNIYGPXY6GJFV",7"Arn": "arn:aws:iam::344227375522:user/temp-user",8"CreateDate": "2024-06-08T08:42:12+00:00"9}10} -
創建 Access Key
Terminal window 1$ aws iam create-access-key --user-name temp-user2{3"AccessKey": {4"UserName": "temp-user",5"AccessKeyId": "AKIAYZKJQNIYECUDIXUQ",6"Status": "Active",7"SecretAccessKey": "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",8"CreateDate": "2024-06-08T08:43:10+00:00"9}10} -
在 Terminal 添加新的 profile:
-
在
~/.aws/config
加上新的配置:1[profile sts]2region=us-west-23output=json -
在
~/.aws/credentials
加上新的憑證信息:1[sts]2aws_access_key_id=AKIAYZKJQNIYECUDIXUQ3aws_secret_access_key=tG3K8HonKZlVNiDYbJ+X9ptLOAI172kDMrHWbYqe
-
-
使用剛剛建立的 User 進行測試:
Terminal window 1$ aws s3api list-buckets --profile sts23An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
被拒絕是正常的,因為這個使用者並沒有任何權限,也沒有扮演任何角色
允許使用者扮演 roles - 建立 IAM Policy - Assume roles
為了讓 user 可以透過 STS 扮演角色,需要給他 IAM permission – sts:AssumeRole
。
-
assume_roles.json
內容如下:1{2"Version": "2012-10-17",3"Statement": [4{5"Effect": "Allow",6"Action": [7"sts:AssumeRole"8],9"Resource": "*"10}11]12} -
透過
assume_roles.json
創建 policyTerminal window 1$ aws iam create-policy --policy-name sts-assume-roles --policy-document file://assume_roles.json2{3"Policy": {4"PolicyName": "sts-assume-roles",5"PolicyId": "ANPAYZKJQNIYMF66RJEUA",6"Arn": "arn:aws:iam::344227375522:policy/sts-assume-roles",7"Path": "/",8"DefaultVersionId": "v1",9"AttachmentCount": 0,10"PermissionsBoundaryUsageCount": 0,11"IsAttachable": true,12"CreateDate": "2024-06-08T08:57:14+00:00",13"UpdateDate": "2024-06-08T08:57:14+00:00"14}15} -
附加 Policy 到
temp-user
Terminal window 1$ aws iam attach-user-policy --user-name temp-user --policy-arn "arn:aws:iam::344227375522:policy/sts-assume-roles" -
使用
aws iam list-attached-user-policies
檢查結果Terminal window 1$ aws iam list-attached-user-policies --user-name temp-user2{3"AttachedPolicies": [4{5"PolicyName": "sts-assume-roles",6"PolicyArn": "arn:aws:iam::344227375522:policy/sts-assume-roles"7}8]9}
建立 User 將要扮演的 Role
接下來,增加一個 IAM Role user-trust-policy-role
,這個 Role 擁有剛好的權限,允許我們訪問特定的 S3。
不過在這之前,先建立 Policy。
-
s3-readonly-role.json
內容如下:1{2"Version": "2012-10-17",3"Statement": [4{5"Effect": "Allow",6"Action": [7"s3:Get*",8"s3:List*"9],10"Resource": "*"11}12]13} -
透過
s3-readonly-role.json
創建 PolicyTerminal window 1aws iam create-policy --policy-name s3-readonly --policy-document file://s3-readon2ly-role.json3{4"Policy": {5"PolicyName": "s3-readonly",6"PolicyId": "ANPAYZKJQNIYJCA3V22KR",7"Arn": "arn:aws:iam::344227375522:policy/s3-readonly",8"Path": "/",9"DefaultVersionId": "v1",10"AttachmentCount": 0,11"PermissionsBoundaryUsageCount": 0,12"IsAttachable": true,13"CreateDate": "2024-06-08T11:30:00+00:00",14"UpdateDate": "2024-06-08T11:30:00+00:00"15}1 collapsed line16}
建立 Trust policy
接下來,我們需要在創建 Role 的同時,使用 Trust policy 將 User 和 Role 關聯在一起。
-
user-trust-policy.json
內容如下:1{2"Version": "2012-10-17",3"Statement": {4"Effect": "Allow",5"Principal": {6"AWS": "arn:aws:iam::344227375522:user/temp-user"7},8"Action": "sts:AssumeRole"9}10} -
創建 Role -
user-trust-policy-role
,同時將 Trust Policy 添加到這個 RoleTerminal window 1$ aws iam create-role --role-name user-trust-policy-role --assume-role-policy-document file://user-trust-policy.json2{3"Role": {4"Path": "/",5"RoleName": "user-trust-policy-role",6"RoleId": "AROAYZKJQNIYLHNL7TQOJ",7"Arn": "arn:aws:iam::344227375522:role/user-trust-policy-role",8"CreateDate": "2024-06-08T19:01:52+00:00",9"AssumeRolePolicyDocument": {10"Version": "2012-10-17",11"Statement": {12"Effect": "Allow",13"Principal": {14"AWS": "arn:aws:iam::344227375522:user/temp-user"15},5 collapsed lines16"Action": "sts:AssumeRole"17}18}19}20} -
別忘了將 Policy -
s3-readonly
附加到user-trust-policy-role
Terminal window 1$ aws iam attach-role-policy --role-name user-trust-policy-role --policy-arn "arn:aws:iam::344227375522:policy/s3-readonly"
現在,temp-user
可以透過 STS,扮演 user-trust-policy-role
(擁有 Policy s3-readonly),達成訪問 S3 的目的。
使用 STS 承擔角色
我們來實際使用 STS 來演示:
-
使用
aws sts assume-role
取得臨時憑證Terminal window 1$ aws sts assume-role --role-arn "arn:aws:iam::344227375522:role/user-trust-policy-role" --role-session-name demo-session --profile sts2{3"Credentials": {4"AccessKeyId": "ASIAYZKJQNIYFP2D4E53",5"SecretAccessKey": "sTT2UNJ6hiNckG0kp4sfsunUlWKmSaqFDQaBVitR",6"SessionToken": "FwoGZXIvYXdzEJX//////////wEaDDL6IaMES/D3Fsz0OiKwAZx0Jb2jz/q0L6XGu3i6aWb9qQIHxLqP1w41ypXdQwJnjMLfYwHYIXJ1m+CNoAUGKPV1fr2TULrd1iKRDgWxweaPE0NAYTnNnSBk2r2oUIumgJhIDWMtrTMDzIOmPNazkNbLrIVn8RyDoIDastWUqsyKqoTedToDHw9muTgDn4IRaETMepIs+GL8QzLlSPBlblnjX/+/4KpgZkJtUhsyNye1jIqoo9HogciJ1kCKEbZEKNLZkrMGMi0w4Lk3b7iw/dx2mFHDIoPZGI4nDqdEK/Y4EwYxtmXafXYpSVWD3KDgwJg+T4s=",7"Expiration": "2024-06-08T20:11:14+00:00"8},9"AssumedRoleUser": {10"AssumedRoleId": "AROAYZKJQNIYLHNL7TQOJ:demo-session",11"Arn": "arn:aws:sts::344227375522:assumed-role/user-trust-policy-role/demo-session"12}13}(Option) 預設的憑證過期時間是 1 天,如果想要控制過期時間,可以使用以下指令:
Terminal window 1# 300 秒過期2$ aws sts assume-role --role-arn "<your_trust_policy_role_arn>" --role-session-name demo-session --duration-seconds 300 -
在 Terminal 添加臨時憑證的 profile
-
在
~/.aws/config
加上新的配置:1[profile demo-session]2region=us-west-23output=json -
在
~/.aws/credentials
加上新的憑證信息:1[demo-session]2aws_access_key_id=ASIAYZKJQNIYFP2D4E533aws_secret_access_key=sTT2UNJ6hiNckG0kp4sfsunUlWKmSaqFDQaBVitR4aws_session_token=FwoGZXIvYXdzEJX//////////wEaDDL6IaMES/D3Fsz0OiKwAZx0Jb2jz/q0L6XGu3i6aWb9qQIHxLqP1w41ypXdQwJnjMLfYwHYIXJ1m+CNoAUGKPV1fr2TULrd1iKRDgWxweaPE0NAYTnNnSBk2r2oUIumgJhIDWMtrTMDzIOmPNazkNbLrIVn8RyDoIDastWUqsyKqoTedToDHw9muTgDn4IRaETMepIs+GL8QzLlSPBlblnjX/+/4KpgZkJtUhsyNye1jIqoo9HogciJ1kCKEbZEKNLZkrMGMi0w4Lk3b7iw/dx2mFHDIoPZGI4nDqdEK/Y4EwYxtmXafXYpSVWD3KDgwJg+T4s=
-
-
使用 s3api 進行測試
1$ aws s3api list-buckets --profile demo-session -
使用
aws sts get-caller-identity
可以查看目前用於驗證請求的 IAM 身分的相關資訊1$ aws sts get-caller-identity --profile demo-session2{3"UserId": "AROAYZKJQNIYLHNL7TQOJ:demo-session",4"Account": "344227375522",5"Arn": "arn:aws:sts::344227375522:assumed-role/user-trust-policy-role/demo-session"6}
通過以上步驟,我們完成了使用 AWS STS 來管理臨時憑證的基本操作。這樣可以大幅提升安全性,並簡化多帳戶和多角色管理的難度。