AWS Identity and Access Management(IAM)是所有 AWS API 呼叫的守門人。SOA-C02 的考驗標準不再是「設計正確的 IAM 模型」——那是 SAA-C03 的範疇——而是「在生產規模下操作 IAM」。SysOps 工程師是那個在半夜十一點、主管把自己鎖在 management account 外面時執行 break-glass 的人;是為了 SOC-2 審查而稽核哪些人曾對 logs bucket 有寫入權限的人;是在除錯為何開發者剛附加政策後仍持續收到 AccessDenied 的人;是驗證新 permissions boundary 是否仍允許部署角色 assume 進 staging 帳號的人;是在公司 IdP 更換簽署憑證時輪換 SAML metadata 的人。每一個操作都牽扯到不同的 IAM 政策類型、condition key 或稽核工具——SOA-C02 考試以操作精度而非架構精度來測試這些能力。
本指南從 SOA-C02 的角度涵蓋 IAM 政策、MFA、SCP、permissions boundary、聯合身份與存取除錯。你會看到五種政策類型被清楚地界定了各自的作用範圍;考試實際會考的簡化評估邏輯;如何使用 IAM Policy Simulator 和 IAM Access Analyzer 在不發出真實 API 呼叫的情況下除錯被拒絕的動作;稽核團隊將詢問的密碼政策和 MFA 強制執行模式;SAML、OIDC 和 Cognito 聯合身份如何透過 STS:AssumeRoleWithSAML 等 API 流轉;以及反覆出現的 SOA-C02 疑難排解場景——「開發者無法讀取 S3 bucket」和「稽核人員想要所有能寫入 logs bucket 的主體清單」。本筆記的目標是:讀完之後,你能對任何 AccessDeniedException 在腦中走完評估鏈:明確拒絕、organizations SCP、resource policy、identity policy、permissions boundary、session policy、condition key。
為何 IAM 政策是 SOA-C02 Domain 4 的核心
Domain 4(安全與合規)佔 SOA-C02 考試 16%,而 Task Statement 4.1 明確列出六項圍繞 IAM 的技能:實作 IAM 功能(密碼政策、MFA、角色、SAML、聯合身份、resource policy、policy 條件)、使用 CloudTrail / IAM Access Analyzer / IAM Policy Simulator 排查與稽核存取問題、驗證 SCP 和 permissions boundary、審查 Trusted Advisor 安全檢查、驗證 region 與服務合規,以及透過 Control Tower 和 AWS Organizations 實作安全的多帳號策略。六項技能中有五項直接落在本主題上;第六項(多帳號策略)在《Multi-Account Organizations》筆記中詳細說明,但重用了你在這裡學到的 IAM 政策類型。
SOA-C02 的框架是操作導向的。SAA-C03 問「架構師應選擇哪種 IAM 政策類型來做跨帳號唯讀存取?」——這是設計選擇。SOA-C02 問「開發者昨天被指派 S3ReadOnly managed policy,但 aws s3 ls s3://prod-logs/ 仍然返回 AccessDenied——你要檢查什麼?」要回答這個問題,需要走完評估鏈:任何地方有明確拒絕嗎?開發者所在的 OU 是否有限制性的 SCP?bucket policy 是否明確允許該主體?開發者的 permissions boundary 是否限制了 S3 動作?開發者是否 assume 了一個帶有 session policy 的角色而進一步縮小了權限?請求是否因為 aws:SourceVpc 或 aws:MultiFactorAuthPresent 等 condition key 而失敗?IAM 政策、MFA、SCP 和存取疑難排解,是每一個後續安全與操作工作流程的基礎插槽。
- IAM user:一個長期存活的身份,擁有使用者名稱,以及 console 密碼或程式化存取金鑰。SysOps 在有聯合身份可用的情況下,盡量避免為人類建立 IAM user。
- IAM group:一個有名稱的 IAM user 集合,共用附加的 identity policy。群組簡化政策管理;你無法將角色附加到群組。
- IAM role:一個暫時性身份,由使用者、服務或聯合主體透過 STS 來 assume。角色有 trust policy(誰能 assume)和 identity policy(assume 後的 session 能做什麼)。
- Identity policy:附加到 user、group 或 role 的 JSON 文件,描述主體可以做什麼。AWS 中大多數的權限透過 identity policy 授予。
- Resource policy:附加到資源(S3 bucket policy、KMS key policy、SQS queue policy、Lambda resource policy、IAM role trust policy)的 JSON 文件,描述誰能對該資源做什麼。
- Service control policy(SCP):AWS Organizations 的政策,附加到 OU 或帳號,定義範圍內任何主體所能擁有的最大權限。SCP 不授予權限;只限縮。
- Permissions boundary:IAM 的進階功能,限制 user 或 role 所能擁有的最大權限,即使 identity policy 授予更多也無效。用於安全地委派 IAM 管理。
- Session policy:在
AssumeRole(或GetFederationToken)時傳入的內嵌 JSON 政策,進一步縮小 session 的範圍。無法超越角色 identity policy 所授予的權限。 - Condition key:
Condition區塊內的 JSON key(aws:SourceIp、aws:MultiFactorAuthPresent、aws:SourceVpc、aws:RequestedRegion、aws:PrincipalTag/...),根據請求上下文決定某個 statement 是否生效。 - STS(Security Token Service):透過
AssumeRole、AssumeRoleWithSAML、AssumeRoleWithWebIdentity和GetFederationToken簽發臨時憑證的 AWS 服務。 - IAM Policy Simulator:一個 console 與 API 工具,在不呼叫真實 API 的情況下,評估某個主體是否能對某個資源執行某個動作。
- IAM Access Analyzer:使用自動化推理技術,識別與外部主體共享的資源,並驗證政策正確性的服務。
- 參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html
白話文解釋 IAM Identities, Policies, and Access Auditing
IAM 的術語堆疊很快。三個類比能讓各個環節變得具體好記。
類比一:夜市攤位管理層級制度
IAM 是一個大型夜市的多層管理層級制度。Identity policy 是攤主的工作識別證,上面寫著「這個人是第三區的滷味攤老闆,可以進入食材倉庫、擺攤區和公共廁所」。Resource policy 是每個特定儲藏室門上的鎖——冷藏室門上貼著自己的存取清單:「只有海鮮攤和飲料攤的老闆能進,不管你的識別證寫什麼」。SCP 是夜市主辦單位在入口公告欄張貼的總規定:「不論是攤主、工作人員還是市長,任何人都不得進入中央電氣房」——規定適用於夜市裡的所有人,包括夜市總監。Permissions boundary 是臨時協力廠商的作業範圍書,上面寫著「這個清潔公司只被聘來負責第三區——無論他們累積了多少通行識別,永遠不得進入第一區的廚房或中央冷藏庫」。Session policy 是前台為單日稽核人員開立的臨時通行證——即使帶領稽核的攤主識別範圍更廣,臨時通行證只允許稽核人員進入指定的幾個攤位。
當某人試圖進入某個儲藏室時,管理員依序檢查所有四層:先看總規定(SCP——這個房間是否對所有人禁止?)、再看房間鎖(resource policy——這個房間本身是否允許此人?)、再看識別證(identity policy——這個人的攤主識別證是否授予入場?)、最後看臨時通行證和作業範圍書(session policy 和 permissions boundary——臨時或長期的限制是否允許?)。任何一層說「不行」,就拒絕進入。任何地方的明確拒絕就像門上貼了紅色封條——它覆蓋整個夜市的所有其他規定。
類比二:大學校園的門禁卡層級
現代大學校園使用智慧門禁卡系統而非實體鑰匙。每張卡有多層編碼權限:基本員工/學生權限(identity policy)、所屬系所規則(group 成員資格)、時段鎖定(aws:CurrentTime condition key)、位置鎖定(aws:SourceIp 對應校園網路,aws:SourceVpc 對應安全機房)、以及敏感門禁的 MFA 要求(aws:MultiFactorAuthPresent)。你拿卡感應門禁時,系統評估每一層——任何一層拒絕就無法進入。學校人事系統的稽核日誌(CloudTrail)記錄每次感應:時間戳記、門號、決定(允許/拒絕)和來源 IP。安全分析師(IAM Access Analyzer + Policy Simulator)可以查閱過去的日誌,也可以事前模擬「如果學生 X 在凌晨三點從停車場感應門 Y 會發生什麼?」——無需等到真的發生。
類比三:企業大樓的多層保全體系
IAM 是一棟大型企業大樓的多層保全體系。Identity policy 是員工門禁卡,標明「這個人是軟體工程部門,可以進入 3F、5F 和員工餐廳」。Resource policy 是每個房間的門鎖清單——董事會議室有自己的存取清單,說明「只有董事會成員和 CEO 可以進入,不管他們的門禁卡寫什麼」。SCP 是大樓業主張貼在大廳的總則:「不論員工、訪客、承包商或 CEO,任何人均不得進入頂樓直升機停機坪」。Permissions boundary 是人資簽發給承包商的工作範圍限制書:「這名承包商只被聘來在 5F 工作——無論他累積了多少門禁,永遠不得進入 8F 或機房」。Session policy 是前台為一日稽核訪客開具的臨時訪客證——即使主人的門禁範圍更廣,訪客證只允許特定幾個房間。
當有人試圖進入房間時,保全依序檢查所有四層。任何一層說「不行」,就拒絕入場。明確拒絕就像門上貼了紅色停止標誌——它覆蓋大樓裡的所有其他規定。
對 SOA-C02 而言,當題目混合多種政策類型——SCP 加上 identity 加上 resource 加上 permissions boundary——企業大樓保全體系類比最實用。當 condition key(aws:MultiFactorAuthPresent、aws:SourceIp、aws:RequestedRegion)是重點時,校園門禁卡類比更合適。夜市攤位管理類比則自然地適用於聯合身份和 assume role 的題目。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
IAM 身份類型:Users、Groups、Roles 與聯合主體
在理解政策之前,你需要對這些身份類型建立精確的心智模型。
IAM users
IAM user 是一個 AWS 帳號內的長期存活身份。每個 user 有唯一的 ARN(arn:aws:iam::123456789012:user/alice)、受帳號密碼政策保護的 console 密碼(選用),以及最多兩對程式化存取金鑰。SOA-C02 要你知道 IAM user 是舊式模式:成熟的 SysOps 環境使用聯合身份給人類、用 IAM role 給所有其他工作負載,IAM user 只留給緊急 break-glass 和少數無法使用聯合身份的服務帳號。
IAM groups
IAM group 是一個有名稱的 IAM user 集合,共用 identity policy。將政策附加到群組是管理一批 IAM user 權限的唯一可擴展方式。SOA-C02 要你知道的三件事:
- 一個 user 最多可以屬於 10 個 group(預設帳號配額;可調高)。
- Group 不能嵌套——IAM 中沒有「群組中的群組」。
- 你不能把 role 附加到 group,只能附加 identity policy。要讓群組成員能夠 assume 一個 role,就附加一個包含
sts:AssumeRole指向該 role ARN 的 identity policy。
IAM roles
IAM role 是一個暫時性身份,由主體透過 STS 來 assume。一個 role 有兩種政策:
- Trust policy(role 的 resource policy)——定義誰能 assume 這個 role。這是包含
Principal: { ... }的 JSON 文件,列出 AWS 帳號、服務、聯合身份提供者,或特定 user/role。 - Identity policy(一個或多個附加)——定義 assume 後的 session 能做什麼。這些是附加到 role 的一般 IAM policy。
當 role 被 assume 後,STS 發出有時效性的臨時憑證(access key、secret key、session token)——sts:AssumeRole 和 sts:AssumeRoleWithSAML 的時效最短 15 分鐘、最長 12 小時(role chaining 則限制在 1 小時)。Session 繼承 role 的 identity policy,並可選擇性地透過 AssumeRole 時傳入的 session policy 進一步縮小範圍。
Role 是 SysOps 的預設選擇,適用於:
- EC2 instance profile — instance 在啟動時自動取得憑證。
- Lambda 執行角色 — function 在每次呼叫時取得憑證。
- 跨帳號存取 — 帳號 A 的 user assume 帳號 B 的 role。
- 聯合使用者存取 — 企業 IdP 使用者透過 SAML assume 一個 role。
- AWS service-linked role — 特定 AWS 服務代替你使用的預定義角色(例如
AWSServiceRoleForAutoScaling)。
聯合主體
聯合主體是在 AWS 外部驗證身份的外部身份(企業 AD、Google Workspace、Okta、GitHub OIDC、Cognito 使用者、自訂 OIDC 提供者),透過 STS 映射到 IAM role:
AssumeRoleWithSAML— 用於 SAML 2.0 IdP(企業 AD via ADFS、Okta SAML、OneLogin)。AssumeRoleWithWebIdentity— 用於 OIDC 提供者(Google、Facebook、Amazon、GitHub Actions、Cognito user pool、EKS service account)。AssumeRole加上 external session name — 用於使用自己 AWS 帳號憑證的受信任合作夥伴,通常搭配ExternalId。
聯合身份是 SOA-C02 偏好的人類存取模式——不需為員工建立 IAM user、沒有共用金鑰、沒有輪換負擔,MFA、密碼政策和人員離職都由企業 IdP 處理。
在 SOA-C02 中,「讓 200 名員工存取 AWS」的標準答案是透過 SAML 或 OIDC 聯合到 IAM role,而不是每個員工各建一個 IAM user。考試偏好聯合身份,原因是成本(每個 IAM user 零額外費用不是問題,但管理成本極高)、安全(MFA 集中在 IdP)、稽核(單一事實來源的身份資料庫)和操作(只需在 IdP 離職,所有 AWS 存取即失效)。IAM user 只保留用於緊急 break-glass 帳號,並以硬體 MFA 保護、透過 CloudTrail 稽核。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html
五種 IAM 政策類型:Identity、Resource、SCP、Permissions Boundary、Session
SOA-C02 中 IAM 概念裡投資報酬率最高的,就是精確掌握五種政策類型各自的作用範圍與效果。背起這個矩陣,大多數「為什麼存取被拒絕」的題目就變得機械式可解。
- Identity policy — 附加對象:user、group 或 role。效果:為該主體授予或明確拒絕動作。AWS 中大多數權限透過 identity policy 授予。每個身份最多附加 10 個 managed policy(可透過 Service Quotas 調高);inline policy 計入身份的政策大小預算。
- Resource policy — 附加對象:資源(S3 bucket、KMS key、SQS queue、SNS topic、Lambda function、IAM role trust 等)。效果:為任何在清單中的主體(包括跨帳號)授予或拒絕對該資源的存取。跨帳號存取時,除了請求帳號的 identity policy,還必須有 resource policy。
- Service Control Policy(SCP) — 附加對象:AWS Organizations 的 OU、帳號或 root。效果:定義範圍內任何主體(包括帳號 root user,但不含 management account)所能擁有的最大權限。SCP 不授予存取;只篩選 identity 和 resource policy 能授權的範圍。
- Permissions boundary — 附加對象:IAM user 或 role。效果:定義該 user 或 role 所能擁有的最大權限,不論 identity policy 授予多少。用於安全地委派 IAM 管理——你可以讓開發者建立新的 role,但限制那些新 role 的權限上限就是 boundary 所允許的。
- Session policy — 在
AssumeRole、AssumeRoleWithSAML、AssumeRoleWithWebIdentity或GetFederationToken時內嵌傳入。效果:進一步縮小 assume 後的 session 範圍。無法超越 role 的 identity policy;只能縮小。最大 2048 字元;以Policy參數傳入,或最多 10 個 managed policy ARN。 - 參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
Identity policy — 主力政策
Identity policy 是最常見的政策類型。AWS 提供數百個 managed policy(AmazonS3ReadOnlyAccess、AmazonRDSFullAccess 等),客戶也可建立 customer-managed policy 以實現細粒度控制。Inline policy 將 JSON 直接嵌入 user/group/role,是錯誤的預設選擇——它無法被重用,且使稽核複雜化。
一個最小 identity policy 範例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::prod-logs",
"arn:aws:s3:::prod-logs/*"
]
}
]
}
Resource policy — 跨帳號橋樑
Resource policy 附著在資源本身。SOA-C02 最常考的 resource policy 包括:
- S3 bucket policy — 跨帳號和條件控制物件操作。
- KMS key policy — 跨帳號金鑰使用的必要條件;預設 key policy 將控制委派給 IAM。
- IAM role trust policy — role 的 resource policy;定義誰可以 assume。
- Lambda resource policy — 允許跨帳號呼叫、S3 事件觸發、API Gateway 整合。
- SNS topic 和 SQS queue policy — 控制跨帳號發布/訂閱和傳送/接收。
SCP — 組織的天花板
Service Control Policy 存在於 AWS Organizations,附加到 OU、帳號或 organization root。SCP 不授予權限;只篩選。最常見的 SCP 模式:
- Region 限制:使用
aws:RequestedRegion拒絕超出核准 region 的所有動作。 - 服務限制:拒絕組織未核准的服務(例如在僅用於日誌的 OU 中拒絕
ec2:*)。 - 強制加密:除非設定了
s3:x-amz-server-side-encryption,否則拒絕s3:PutObject。 - 防止 CloudTrail 停用:對所有人拒絕
cloudtrail:StopLogging和cloudtrail:DeleteTrail。 - Root user 鎖定:拒絕 root user 執行基本管理以外的動作。
Management account 不受 SCP 約束——這是重要的 SysOps 陷阱(詳見下文)。
Permissions boundary — 委派管理的安全網
Permissions boundary 限制 user 或 role 的最大權限。典型使用案例:SysOps 工程師想讓資深開發者為自己團隊的 Lambda function 建立新 IAM role——但不希望這些新 role 能夠提升權限。模式如下:
- 建立 permissions boundary 政策
DeveloperBoundary,列出這位開發者所建 role 能擁有的最大權限。 - 給開發者附加 identity policy,授予
iam:CreateRole、iam:AttachRolePolicy等——但加上條件:他們建立的 role 必須將DeveloperBoundary附加為 permissions boundary。 - 開發者現在可以自由建立 role,但無論他們附加什麼政策(包括
AdministratorAccess),都不會超過 boundary 的限制。
強制執行此條件的寫法:
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/DeveloperBoundary"
}
}
Session policy — 在 assume 時縮小範圍
Session policy 在 AssumeRole 時內嵌傳入,不會持久儲存。它將 assume 後的 session 縮小到 role 權限的子集。使用場景:
- SaaS 應用程式 assume 客戶 role,並傳入只列出當前操作所需動作的 session policy。
- 身份仲介(Cognito、自訂聯合身份)為每個 session 發出受限憑證。
- CLI 呼叫
sts:AssumeRole時使用--policy旗標進行一次性限縮操作。
Session policy 的有效權限是 role 的 identity policy 與 session policy 的交集——不是兩者中任一,而是兩者都允許的部分。
- 每個 IAM 身份最多附加的 managed policy 數:10(預設;可透過 Service Quotas 調高)。
- Managed policy 大小上限:6,144 字元。
- 每個 user 的 inline policy 大小上限:2,048 字元。
- 每個 group 的 inline policy 大小上限:5,120 字元。
- 每個 role 的 inline policy 大小上限:10,240 字元。
- Session policy 大小上限:2,048 字元(以 Policy 參數傳入)。
- 以 session policy 傳入的 managed policy ARN 最多數量:10 個。
- STS AssumeRole session 時效:最短 15 分鐘、最長 12 小時(由 role 上的
MaxSessionDuration設定;預設 1 小時)。 - STS role chaining session 時效:最長 1 小時(不可延長)。
- AssumeRoleWithSAML 時效:15 分鐘至 12 小時(依 role 的 MaxSessionDuration)。
- 每個 IAM user 的 access key 數量:最多 2 對。
- 每個 user 的 MFA 設備數量:8 個(1 個硬體 + 多個虛擬或 FIDO2)。
- SCP 大小上限:5,120 字元。
- 每個 IAM user 可加入的 group 數:10(預設)。
- 參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html
IAM 政策評估邏輯 — SOA-C02 簡化模型
官方的 IAM 政策評估邏輯是一份多頁的流程圖。SOA-C02 使用簡化模型就已足夠,一旦你內化這個模型,大多數「為什麼被拒絕」的題目都能機械式地回答。
簡化評估鏈
當主體發出 API 呼叫時,AWS 依序通過以下關卡評估請求。只要任一關卡拒絕,請求即被拒絕。要允許,每個適用的關卡都必須允許(或以允許解析的方式保持靜默)。
- 明確拒絕——任何地方優先。若任何範圍內的政策(SCP、identity、resource、permissions boundary、session)有
Effect: Deny匹配到該動作和資源,請求即被拒絕。後續關卡無法逆轉此結果。 - SCP — 若主體所在 OU 有 SCP,SCP 必須允許該動作。SCP 在允許清單模式下預設拒絕一切,在拒絕清單模式下預設允許一切。AWS 提供的預設 SCP
FullAWSAccess允許所有動作;自訂 SCP 可取代或補充它。 - Resource policy — 若資源有 resource policy 且主體來自不同帳號,resource policy 必須允許該動作。對同帳號請求,resource policy 本身可以足夠(例如 S3 bucket policy 可單獨授予同帳號使用者——但更安全的心智模型是要求兩者都允許)。
- Identity policy — 附加到主體的至少一個 identity policy 必須允許該動作。
- Permissions boundary — 若主體有 permissions boundary,boundary 必須允許該動作。
- Session policy — 若請求來自帶有 session policy 的 assume role session,session policy 必須允許該動作。
這些層的 condition 評估屬於該層的允許檢查的一部分。條件失敗的行為就像未匹配——該 statement 不允許此動作,但可能有其他 statement 允許。
「明確拒絕優先」規則的細節
SOA-C02 最常考的規則:任何層的明確 Effect: Deny 會覆蓋其他所有地方的所有 Allow。常見的操作後果:開發者的 identity policy 授予了 AdministratorAccess,但 OU 層級的 SCP 有一個 Deny 在 iam:CreateUser。無論如何,開發者都無法建立 IAM user,因為 SCP 的明確拒絕勝出。
跨帳號請求——兩側都必須允許
從帳號 A 向帳號 B 的資源發出請求時:
- 帳號 A 的 IAM identity policy 必須允許該動作。
- 帳號 B 的 resource policy 必須允許帳號 A 的主體。
- 帳號 A 的 SCP 和 permissions boundary 必須允許該動作。
- (帳號 B 的 SCP 或 permissions boundary 無要求——那些管的是帳號 B 內的主體,而不是來自帳號 A 的訪客。)
SOA-C02 最清晰的範例:dev 帳號的開發者想讀取 prod 帳號的 logs bucket。兩個條件必須同時成立:(a) dev 帳號的開發者 IAM identity policy 允許對該 bucket ARN 執行 s3:GetObject,且 (b) prod 帳號的 bucket policy 允許該開發者的主體 ARN 執行 s3:GetObject。任一條件缺失都會失敗。考生常常忘記 resource policy 的要求,浪費時間在 identity policy 上除錯。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html
Trust policy 是特殊的 resource policy
Role 的 trust policy 在技術上是 role 的 resource policy。要讓 sts:AssumeRole 成功,必須同時滿足兩個條件:(a) 主體的 identity policy 要有 sts:AssumeRole 權限,以及 (b) role 的 trust policy 要在 Principal 區塊中列出該主體。兩側都要——就像所有跨帳號存取一樣。Trust policy 也常包含條件(第三方 assume 用的 sts:ExternalId、VPC 範圍 assume 用的 aws:SourceVpc)。
MFA 設定與透過 aws:MultiFactorAuthPresent 強制執行
多因素驗證對 SOA-C02 成熟環境中的每個特權身份都是強制的,考試同時測試啟用 MFA 和透過 condition key 強制執行 MFA。
MFA 設備類型
- 虛擬 MFA 應用程式(Authy、Google Authenticator、AWS-managed
AWS Virtual MFA)— TOTP,每 30 秒產生六位數代碼。免費、快速設定,但易受網路釣魚攻擊。 - U2F / FIDO2 安全金鑰(YubiKey、Google Titan)— USB 插入的硬體金鑰。具備防網路釣魚能力,建議用於 root 和管理帳號。
- 硬體 OTP token(Gemalto / Yubico)— 顯示六位數代碼的獨立實體設備。用於具有嚴格硬體 token 政策的組織。
- SMS MFA 已不再支援新 IAM user(AWS 已棄用)。
一個 user 最多可以登錄 8 個 MFA 設備,但登入時只有一個處於啟用狀態。
Root user 的 MFA 設定
Root user 的 MFA 是每個 Trusted Advisor 安全檢查稽核的第一項。推薦模式:使用物理封存、雙人保管(兩名保管人)的硬體 FIDO2 金鑰。帳號建立後,在進行任何其他操作之前先設定 root MFA。
透過 condition key 強制執行 MFA
AWS 提供全域 condition key aws:MultiFactorAuthPresent(布林值)和 aws:MultiFactorAuthAge(數值,MFA 後經過的秒數)。標準強制執行模式:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
此模式使用 BoolIfExists 是因為在某些情境下,非 MFA session 中該 key 是缺失的(而非 false)。NotAction 豁免讓使用者可以在首次登入時自行設定 MFA 設備。
每個 API 的 MFA 要求
對於敏感 API,你可以要求每次呼叫都要有 MFA:
{
"Effect": "Allow",
"Action": "ec2:TerminateInstances",
"Resource": "*",
"Condition": {
"Bool": { "aws:MultiFactorAuthPresent": "true" },
"NumericLessThan": { "aws:MultiFactorAuthAge": "3600" }
}
}
MultiFactorAuthAge 條件要求 MFA 在一小時內完成,提高了竊取 session 憑證後的攻擊門檻。
- Root 帳號:硬體 FIDO2 + 密封袋雙人保管。
- Identity policy MFA 強制:
Deny搭配Condition: { BoolIfExists: { aws:MultiFactorAuthPresent: false } }和NotAction豁免自助 MFA 設定 API。 - 每個 API 的 MFA 要求:
Allow搭配Condition: { Bool: { aws:MultiFactorAuthPresent: true } }加上aws:MultiFactorAuthAge數值上限。 - STS AssumeRole MFA:trust policy 加上
Condition: { Bool: { aws:MultiFactorAuthPresent: true } }— 呼叫者在 AssumeRole 時必須提供 MFA。 - AssumeRole role chaining 最長 1 小時:不論 role 的
MaxSessionDuration設為多少。 - AssumeRole 其他情境最長 12 小時:透過 role 的
MaxSessionDuration設定(3600 至 43200 秒)。 - 參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html
帳號密碼政策與憑證輪換
IAM 帳號密碼政策是一個全帳號的設定,管理所有 IAM user 的 console 密碼。SOA-C02 同時考測可用的設定項和稽核/輪換模式。
密碼政策設定項
- 最小密碼長度:6 至 128 字元(預設 8;建議 14+)。
- 至少需要一個大寫字母:是/否。
- 至少需要一個小寫字母:是/否。
- 至少需要一個數字:是/否。
- 至少需要一個非英數字元:是/否。
- 允許使用者自行更改密碼:是/否。
- 密碼過期天數:1 至 1095 天;設定後,使用者必須在過期後的下次登入時輪換。
- 密碼重複使用防護:最多封鎖 24 個先前使用過的密碼。
- 密碼過期後需要管理員重設 vs 使用者可自行重設:控制過期使用者能否自行恢復。
密碼政策只適用於 IAM user——聯合使用者向 IdP 驗證,由 IdP 自己的政策管理。
憑證報告
IAM 憑證報告是 CSV 下載(或 iam:GenerateCredentialReport API),列出每個 IAM user 的:console 密碼是否已設定、密碼最後使用時間、密碼最後更改時間、MFA 是否啟用、access key 1/2 狀態、access key 最後使用時間、access key 最後輪換時間。合規稽核和 SOC 報告依賴此報告來驗證密碼和金鑰的輪換情況。
Access key 輪換
每個 IAM user 最多可以同時擁有 2 對 access key,正是為了支援無中斷輪換:
- 建立第二個 access key(此時兩個都是有效的)。
- 將新金鑰分發給應用程式並重新部署。
- 透過舊金鑰的
Last used時間戳記確認——它應該停止被使用。 - 停用(而非刪除)舊金鑰,保留一段觀察期。
- 觀察期結束後,刪除舊金鑰。
SOA-C02 可能會問「如何在不中斷服務的情況下輪換 access key」——答案就是上述的雙金鑰模式。
對於任何關於誰有過期憑證的合規問題,憑證報告是正確的工具。透過 aws iam generate-credential-report 然後 aws iam get-credential-report --output text --query Content | base64 -d 來產生。報告告訴你每個 user、MFA 狀態、密碼年齡、金鑰年齡和最後使用時間戳記。搭配排程 Lambda 每週將報告匯入 S3/Athena 進行趨勢分析。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html
SAML、OIDC 與 Cognito 聯合身份 — 操作設定
聯合身份是 SOA-C02 偏好的人類和工作負載存取模式。每種協議有不同的設定步驟和不同的 STS API。
SAML 2.0 聯合身份
SAML 2.0 是企業身份協議——由 ADFS、Azure AD / Entra ID SAML、Okta SAML、Ping、OneLogin 使用。操作設定步驟:
- 設定 IdP:將 AWS 登錄為 service provider,定義 SAML assertion 的 claim(NameID、透過
https://aws.amazon.com/SAML/Attributes/Roleclaim 的角色映射)。 - 建立 IAM SAML identity provider:上傳 IdP 的 metadata XML 到 IAM。產生 SAML provider ARN。
- 建立 IAM role,trust policy 允許 SAML provider 作為主體,並以 SAML audience 作為條件:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::123456789012:saml-provider/CorpAD" },
"Action": "sts:AssumeRoleWithSAML",
"Condition": {
"StringEquals": {
"SAML:aud": "https://signin.aws.amazon.com/saml"
}
}
}]
}
- 在 IdP 中將 IdP 群組映射到 IAM role(通常每個 IdP 群組對應一個 IAM role)。
- 使用者在 IdP 驗證並被重定向到 AWS console,帶有 SAML response;AWS 呼叫
AssumeRoleWithSAML並啟動 session。
Session 時效由 role 的 MaxSessionDuration 設定(1 至 12 小時)。
OIDC 聯合身份
OIDC 用於 Google、Facebook、Amazon、GitHub Actions、Cognito user pool 和 Kubernetes service account(EKS IRSA)。操作設定步驟:
- 建立 IAM OIDC identity provider,使用 IdP 的 issuer URL 和 TLS 憑證的指紋。
- 建立 IAM role,trust policy 允許 OIDC provider 作為主體,並以 audience 和 subject 作為條件:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
}
}
}]
}
- 工作負載向 IdP 請求 ID token,然後以該 token 呼叫
AssumeRoleWithWebIdentity。
上述 GitHub Actions 模式越來越成為 SOA-C02 偏好的 CI/CD 存取 AWS 的答案——不需要長期存取金鑰,只需要短期的 OIDC token,範圍限定在 repo 和分支。
Cognito identity pool
Cognito user pool 處理驗證;Cognito identity pool 處理 AWS 資源的授權。模式:行動應用程式對 Cognito user pool 驗證使用者身份,在 identity pool 交換 ID token,identity pool 對 pool 中設定的 role 呼叫 AssumeRoleWithWebIdentity。行動客戶端隨後用這些臨時憑證進行 AWS API 呼叫。SOA-C02 在「給行動應用程式使用者有限制的 AWS 存取,同時不嵌入長期金鑰」的情境中考測 Cognito identity pool。
STS AssumeRole — ExternalId、Role Chaining 與 Session Tags
sts:AssumeRole 是跨帳號、聯合身份和服務間存取的主力 API。三個操作細節在 SOA-C02 上反覆出現。
ExternalId — SaaS 提供商模式
當第三方 SaaS(Datadog、New Relic、Snyk、Wiz)需要存取你的帳號時,標準模式是在你的帳號中建立一個 role,讓 SaaS 的 AWS 帳號可以 assume——但在 trust policy 中要求 ExternalId:
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::222222222222:root" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "unique-tenant-id-abc123" }
}
}
ExternalId 是一個線下協商的共用機密,防止混淆代理人問題:SaaS 的惡意客戶無法欺騙 SaaS 代表他們 assume 你的 role,因為 SaaS 只會傳入你向它登錄的 ExternalId。SOA-C02 將此模式考測為「什麼條件可防止惡意第三方客戶透過 SaaS 存取我的帳號」。
Role chaining 與 1 小時上限
Role chaining 是當一個 assumed-role session 再次 assume 另一個 role。範例:SAML 使用者 assume corp-developer role(12 小時 session),然後 corp-developer assume prod-readonly role。第二次 AssumeRole 就是 role chaining。
關鍵限制:role chaining 會將第二個 session 的時效限制在 1 小時,不論目標 role 的 MaxSessionDuration 是多少。這是為了限制透過鏈式角色提升權限的爆炸半徑。SOA-C02 關於「儘管 MaxSessionDuration 設為 12 小時,腳本的 session 仍在一小時後過期」的題目,答案就是 role chaining。
Session tags
Session tag 是在 AssumeRole 時附加到 session 的鍵值對,以 aws:PrincipalTag/key condition key 的形式繼承到請求上下文中。使用案例:
- ABAC(屬性型存取控制) — 透過部門、專案或成本中心的 tag 來限定存取範圍,而不是為每個團隊建立一個 role。
- 稽核記錄豐富化 — CloudTrail 記錄 session tag,使稽核記錄比單純的主體 ARN 更有用。
Session tag 透過 AssumeRole 的 Tags 參數傳入(或自動映射自 SAML/OIDC claim)。
SOA-C02 常見干擾項:「開發者的自動化腳本每小時都會失敗,儘管目標 role 的 MaxSessionDuration 設為 12 小時」。考生查看 role 的設定;實際原因是 role chaining。第一次 AssumeRole 建立了一個 session,腳本再從那個 session assume 另一個 role,而那第二次 AssumeRole 被硬性限制在 1 小時。修復方式:(a) 直接 assume 最終 role 以消除鏈式,或 (b) 讓腳本每 50 分鐘重新 AssumeRole。參考:https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
存取稽核:CloudTrail + IAM Access Analyzer + Policy Simulator
SOA-C02 的存取稽核工具箱有三個支柱,考試測試你何時使用哪個。
CloudTrail — 已發生的事
CloudTrail 記錄帳號中的每個 API 呼叫。在存取稽核方面,它回答以下問題:
- 「昨天下午三點是誰刪除了 production S3 bucket policy?」 — 在 14:00 至 16:00 之間查詢該 bucket 的
eventName=PutBucketPolicy或DeleteBucketPolicy。 - 「本季度是誰以 root user 登入?」 — 查詢該期間的
userIdentity.type=Root。 - 「過去 90 天內哪些主體存取了 logs bucket?」 — 查詢該 bucket 的 S3 data event(必須在 trail 中單獨啟用;預設關閉)。
- 「有人停用 CloudTrail 本身嗎?」 — 查詢
eventName=StopLogging或DeleteTrail。
CloudTrail 是被動的——你只能稽核已發生的事,而且只有在 trail 啟用時才能查到。Management event 在每個帳號中預設記錄;data event(S3 物件層級、Lambda function 呼叫)需要明確啟用。
IAM Access Analyzer — 誰能存取
Access Analyzer 使用自動化推理(數學證明)來回答兩個不同的問題:
- 外部存取發現 — 對於範圍內的每個 resource policy(S3 bucket、IAM role、KMS key、Lambda function、SQS queue、Secrets Manager secret、EFS 檔案系統、RDS 快照、EBS 快照),Access Analyzer 判斷資源是否可從帳號或組織外部存取。發現結果列出每個外部主體和存取路徑。SysOps 團隊審查後,將已知情況標記為預期(封存)或收緊政策來修復。
- 未使用存取發現(較新功能)— 識別在可設定期間(預設 90 天)內未使用過其權限的 IAM user、role 和 policy。推動最小權限的精簡。
- 政策驗證 — 在撰寫政策時,Access Analyzer 呈現警告和建議(過寬的資源、缺少條件等)。
- 自訂政策檢查 — 較新功能,讓你以數學確定性斷言「此政策不會將
iam:PassRole授予組織外的任何人」。
Access Analyzer 是主動的——它告訴你目前有哪些存取是可能的,而不是已發生的事。
IAM Policy Simulator — 如果發生會怎樣
Policy Simulator 評估特定主體是否被允許對特定資源執行特定動作,而不實際發出 API 呼叫。它走相同的評估鏈(SCP、identity、resource、permissions boundary)並返回:
- 決策:
allowed、explicitDeny或implicitDeny。 - 匹配的政策 statement。
- 評估了哪些 condition key 及其值。
- 匹配的資源 ARN。
使用場景:
- 部署前測試:在附加新政策之前,模擬關鍵動作以確保沒有功能退步。
- 存取拒絕除錯:開發者回報
AccessDeniedException;模擬確切的動作和資源,查看哪個關卡拒絕。 - 跨帳號模擬:以來自另一個帳號的主體身份,對這個帳號的資源進行模擬。
- 「已發生了什麼?」 → CloudTrail。(過去式。)
- 「目前有哪些存取是可能的?」 → IAM Access Analyzer。(現在式,對所有當前政策的自動化推理。)
- 「如果 X 做 Y 會怎樣?」 → IAM Policy Simulator。(假設式,走評估鏈。)
SOA-C02 的考題會以過去式、現在式或假設式來表述問題——這個文法就是你的提示。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html
AWS Trusted Advisor 安全檢查
Trusted Advisor 是跨服務的 AWS 最佳實踐審查員。SOA-C02 特別點名安全檢查:
- Root 帳號的 MFA — 標記任何 root user 缺少 MFA 的帳號。
- IAM 使用 — 標記 root user 是唯一憑證的帳號(建議建立 IAM user / role)。
- IAM 密碼政策 — 標記缺少或薄弱的密碼政策。
- 安全群組,特定連接埠不受限制 — 標記對 0.0.0.0/0 開放 SSH(22)、RDP(3389)或其他敏感連接埠的安全群組。
- S3 bucket 權限 — 標記具有公開讀取/寫入或「Authenticated AWS Users」授予的 bucket。
- CloudTrail 日誌記錄 — 標記 CloudTrail 未在所有 region 啟用的帳號。
- 外洩的 access key — 掃描公開 GitHub 上屬於你帳號的 AWS access key 外洩情況。
- 公開快照 — 標記公開共享的 EBS 或 RDS 快照。
Trusted Advisor 的檢查分為成本優化、效能、安全性、容錯和服務限制五類。完整的安全檢查集需要 Business 或 Enterprise Support 方案;免費方案只顯示一小部分。
操作模式:在 EventBridge 設置規則,監聽 Trusted Advisor Check Item Refresh Notification 事件,將安全類別的檢查變更路由到 SNS,使 SysOps 團隊在新 bucket 公開暴露或 MFA 設備被移除的瞬間收到通知。
透過 SCP 進行 Region 和服務合規限制
SOA-C02 的常見合規場景:資料落地要求工作負載只能在核准 region 執行,或只允許特定服務。SCP 是 SOA-C02 認可的強制執行方式。
Region 限制 SCP
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyOutsideApprovedRegions",
"Effect": "Deny",
"NotAction": [
"iam:*", "organizations:*", "route53:*",
"cloudfront:*", "support:*", "sts:*",
"waf:*", "wafv2:*", "shield:*", "globalaccelerator:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["ap-southeast-1", "ap-east-1"]
}
}
}]
}
NotAction 豁免至關重要——全域服務(IAM、Organizations、Route 53、CloudFront、STS)沒有區域端點,或以 us-east-1 作為其主 region。若未豁免這些服務,整個帳號就會損壞。
服務限制 SCP
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyDisallowedServices",
"Effect": "Deny",
"Action": ["sagemaker:*", "comprehend:*", "rekognition:*"],
"Resource": "*"
}]
}
適用於「此 OU 用於合規限制的工作負載——在法務核准之前不得使用 AI/ML 服務」。
強制加密 SCP
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyUnencryptedS3Uploads",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}]
}
即使開發者的 identity policy 允許 s3:PutObject,SCP 也會拒絕任何未使用 KMS 加密的上傳。
SOA-C02 的持久干擾項是提供一個「使用 SCP 授予服務存取」的答案。SCP 無法授予。它們只篩選其他政策(identity、resource)能授權的範圍。要新增一個權限,將其附加到主體的 identity policy;SCP 只是不能擋住它。參考:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html
情境模式:「使用者 X 無法讀取 S3 bucket Y」— 疑難排解順序
這是 SOA-C02 的標準疑難排解情境。從上到下走完評估鏈。
- 取得確切的錯誤訊息。 CLI 的
AccessDenied通常包含主體 ARN、動作和資源。CloudTrail 有更多細節(errorCode=AccessDenied、errorMessage="...")。錯誤訊息通常能將問題定位到特定的政策層。 - 執行 IAM Policy Simulator,輸入主體、動作(
s3:GetObject)和資源(arn:aws:s3:::bucket/object)。Simulator 返回決策和匹配(或未匹配)的政策。大多數 SOA-C02 疑難排解題都將 simulator 視為第一個工具。 - 檢查 SCP,若主體在 Organizations OU 中。SCP 是最令人意外的阻擋因素,因為它在 org 層級設定,從帳號層面看不到。
- 檢查 resource policy——是同帳號還是跨帳號請求?跨帳號時,bucket policy 必須明確允許該主體。同帳號時,bucket policy 仍可能透過帶條件的
Effect: Deny封鎖。 - 檢查 identity policy——user/role/group 是否有附加允許該動作的政策?
- 檢查 permissions boundary——若 role 有 boundary,它是否允許該動作?
- 檢查 session policy——若請求來自帶有 session policy 的 assumed role,session policy 是否允許?
- 檢查 condition key——
aws:SourceVpc、aws:SourceIp、aws:MultiFactorAuthPresent、s3:x-amz-server-side-encryption——任何一個都可能導致請求失敗。 - 檢查加密——bucket 可能要求 SSE-KMS,但請求使用了 SSE-S3 或沒有加密標頭。
- 查看 IAM Access Analyzer,確認 bucket policy 是否允許該主體存取。
SOA-C02 模擬情境中最常見的根本原因:OU 層級的 SCP 拒絕了該動作,而開發者只看了 identity policy 和 bucket policy,沒有看 SCP。
情境模式:「稽核人員詢問誰對 logs bucket 有寫入存取」
這是現在式的稽核情境。正確工具是 IAM Access Analyzer,而不是 CloudTrail。
CloudTrail 告訴你誰曾寫入——過去式。稽核人員問的是誰能寫入——現在式。Access Analyzer 的外部存取發現會列出根據目前 bucket policy,能寫入該 bucket 的每個主體(跨帳號或外部)。對於內部主體,答案是枚舉帳號中所有 IAM user 和 role,找出那些 identity policy 允許對該 bucket 執行 s3:PutObject 的——透過 iam:GetAccountAuthorizationDetails 加上離線模擬以程式化方式完成。
完整的操作答案:
- 對外部(跨帳號)寫入存取:在 bucket 上執行 IAM Access Analyzer 外部存取發現。
- 對內部寫入存取:列出帳號中的 IAM user + role,對每個人使用 Policy Simulator 以
s3:PutObject對該 bucket 進行模擬,收集允許的結果。 - 對歷史寫入記錄:在 CloudTrail trail 上啟用 S3 data event(預設關閉),查詢對該 bucket 的
eventName=PutObject。
SOA-C02 的題目若以「誰能存取」或「誰有存取」來表述,是現在式——Access Analyzer。題目若以「誰存取過」或「誰確實存取了」來表述,是過去式——CloudTrail。題目若以「如果使用者 X 嘗試做 Y,是否會成功」來表述,是假設式——Policy Simulator。題目的文法決定了工具。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html
常見陷阱:明確拒絕永遠優先
這是最常被考測的 IAM 規則。任何層的明確 Effect: Deny(SCP、identity、resource、permissions boundary、session policy)都會覆蓋其他所有地方的所有 Allow。沒有例外、沒有覆蓋,也沒有「但 bucket policy 允許」這種情況。
操作後果:若開發者儘管擁有 AdministratorAccess 仍被拒絕某個動作,原因幾乎總是明確拒絕——通常在 SCP 中,偶爾在 bucket policy 或 permissions boundary 中。IAM Policy Simulator 會直接顯示匹配的拒絕 statement。
常見陷阱:Permissions Boundary 的範圍常被誤解
Permissions boundary 是 user 或 role 能擁有的最大權限——不是保證允許。Boundary 像過濾器一樣運作:有效權限是 identity policy 和 boundary 的交集。若 identity policy 授予 S3 讀取,但 boundary 不包含 S3,使用者在 S3 上什麼都得不到。
SOA-C02 常見陷阱:考生附加 permissions boundary 並期望它授予權限。它不會。Boundary 只限制其他政策能授予的上限。要授予,需要在 boundary 允許的範圍內附加 identity policy。
常見陷阱:Session Policy 是最大範圍,而非最小範圍
在 AssumeRole 時傳入的 session policy 只能縮小 assumed session 的範圍,永遠無法擴大。若 role 的 identity policy 授予 s3:*,而 session policy 授予 ec2:*,有效權限是交集——為空(S3 和 EC2 都沒有)。考生有時試圖使用 session policy 來授予額外權限;這從來不會生效。
常見陷阱:SCP 不授予存取——只限縮
SCP 是過濾器,不是授予。將 FullAWSAccess SCP 附加到 OU,並不會給那個 OU 中的主體任何存取——他們仍然需要 identity policy。SCP 取代或補充 AWS 在 root 附加的預設 FullAWSAccess SCP;若沒有那個預設值,一個只列出特定允許項的自訂 SCP 會靜默地阻斷其他一切。
正確的心智模型:SCP 回答「這個 OU 中的任何主體最多能被允許做什麼」。Identity 和 resource policy 回答「這個主體實際上被允許做什麼」。兩者的交集才是有效權限。
常見陷阱:Management Account 不受 SCP 約束
AWS Organizations 的 management account(舊稱 master account)不受任何 SCP 約束——即使你將 SCP 附加到 root 或包含 management account 的 OU 也無效。AWS 設計了這個豁免,以確保 management account 在緊急情況下永遠能夠恢復 organization。
操作後果:永遠不要在 management account 中執行生產工作負載。它只用於 AWS Organizations 管理、帳單和 break-glass 程序。真正的工作負載屬於 SCP 適用的 member account。
SOA-C02 干擾項:「安全團隊在 root 套用了一個拒絕所有 S3 動作的 SCP,但 management account 中的開發者仍然可以建立 bucket」。考生去找 SCP 的設定錯誤;答案是 management account 被豁免了。SOA-C02 要求你知道這個豁免以及操作上的緩解措施:讓 management account 保持無工作負載。參考:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html
SOA-C02 vs SAA-C03:IAM 的操作視角
兩個認證都考 IAM,但視角不同。
| 題目類型 | SAA-C03 視角 | SOA-C02 視角 |
|---|---|---|
| 選擇政策類型 | 「哪種 IAM 政策類型讓 SaaS 能存取客戶帳號?」 | 「在 trust policy 加上 ExternalId 條件以防止 confused deputy。」 |
| 跨帳號存取 | 「在帳號 B 使用 resource policy。」 | 「帳號 A 的主體有 identity policy,帳號 B 的 bucket policy 也允許他們,但仍是 AccessDenied——檢查 SCP、condition key、KMS key policy。」 |
| MFA | 「在 root 帳號啟用 MFA。」 | 「撰寫一個在 aws:MultiFactorAuthPresent 為 false 時拒絕除自助 MFA 設定以外所有動作的 IAM policy。」 |
| 聯合身份 | 「企業 AD 使用者用 SAML 2.0。」 | 「設定 SAML provider、帶有 SAML:aud 條件的 role trust policy、IdP 端的群組到 role 映射。」 |
| Permissions boundary | 「用於委派管理。」 | 「撰寫強制新 role 攜帶 boundary 的 iam:PermissionsBoundary 條件。」 |
| Access Analyzer | 「識別外部存取。」 | 「區分外部存取發現和未使用存取發現;封存 vs 修復的工作流程。」 |
| Policy Simulator | 很少考。 | 「開發者回報 AccessDenied;simulator 顯示 implicitDeny;缺少允許的是哪個關卡?」 |
| SCP | 「在 OU 層級限制 region。」 | 「撰寫帶有全域服務 NotAction 豁免和 aws:RequestedRegion 條件的 SCP。」 |
| Role chaining | 不考。 | 「儘管 MaxSessionDuration=12h,腳本每小時過期——role chaining 觸及 1 小時上限。」 |
| 稽核 | 「CloudTrail 記錄 API 呼叫。」 | 「稽核人員想知道誰能存取——Access Analyzer;誰曾存取——CloudTrail;誰會存取——Simulator。」 |
SAA 考生選擇政策類型。SOA 考生撰寫政策、用 simulator 除錯拒絕情況、用 Access Analyzer 稽核存取路徑,並執行輪換、聯合身份和 break-glass 程序。
考試信號:如何識別 Domain 4.1 的題目
SOA-C02 的 Domain 4.1 題目遵循可預測的形態。認出它們,答案通常就是三四個標準工具之一。
- 「AccessDeniedException」 — 答案涉及先使用 IAM Policy Simulator,然後走評估鏈(SCP、resource、identity、boundary、session、condition)。
- 「Bucket / role / KMS key 對外共享」 — 答案是 IAM Access Analyzer 外部存取發現。
- 「將企業使用者聯合到 AWS」 — 答案是 SAML 或 OIDC identity provider + 帶有 audience 條件的 IAM role trust policy。
- 「委派管理而不提升權限」 — 答案是 permissions boundary 加上強制 boundary 附加到所建 role 的
iam:PermissionsBoundary條件。 - 「在組織層級限制 region / 服務」 — 答案是帶有
aws:RequestedRegion或服務動作過濾的 SCP。 - 「對敏感動作要求 MFA」 — 答案是條件
aws:MultiFactorAuthPresent加上aws:MultiFactorAuthAge。 - 「第三方 SaaS 需要跨帳號存取」 — 答案是帶有
sts:ExternalId條件的 role。 - 「稽核人員想要有存取權限的主體清單」 — 現在式,Access Analyzer。
- 「合規團隊想要 API 呼叫清單」 — 過去式,CloudTrail。
- 「新政策的部署前驗證」 — Policy Simulator。
- 「過期憑證和金鑰輪換稽核」 — IAM 憑證報告。
- 「Trusted Advisor 對 root MFA / 公開 bucket 的紅色警示」 — Trusted Advisor 安全檢查 + 修復。
Domain 4 佔 SOA-C02 的 16%,而 TS 4.1 涵蓋了其中的大部分。預期這個範圍有 8 至 10 道題。最常考的兩個工具是 IAM Policy Simulator 和 IAM Access Analyzer;最常考的 condition key 是 aws:MultiFactorAuthPresent、aws:RequestedRegion 和 sts:ExternalId。參考:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html
決策矩陣 — 每個 SysOps 目標的 IAM 構件
在考試中使用這個查詢表。
| 操作目標 | 主要構件 | 備注 |
|---|---|---|
| 讓 200 名企業員工存取 AWS | SAML 2.0 聯合身份 + IAM role | 永遠不要逐一建立 IAM user。 |
| 讓 CI/CD pipeline 存取 AWS | OIDC 聯合身份(如 GitHub Actions)+ IAM role | 不需長期存取金鑰。 |
| 讓行動應用程式使用者存取 AWS | Cognito identity pool + IAM role | 每個使用者的短期憑證。 |
| 讓 EC2 instance 呼叫 AWS API | IAM instance profile | 自動輪換的憑證。 |
| 讓 Lambda function 呼叫 AWS API | Lambda 執行角色 | 每次呼叫自動輪換的憑證。 |
| 跨帳號唯讀存取 | 來源帳號的 identity policy + 目標帳號的 resource policy | 兩者都需要。 |
| 第三方 SaaS 跨帳號存取 | 帶有 sts:ExternalId 條件的 role |
防止 confused deputy。 |
| 將 OU 限制在特定 region | 帶有 aws:RequestedRegion 的 SCP |
全域服務要有 NotAction 豁免。 |
| 強制上傳加密 | 帶有 s3:x-amz-server-side-encryption 條件的 SCP |
全組織護欄。 |
| 委派 IAM 管理給資深開發者 | Permissions boundary + 強制 boundary 附加到所建 role 的條件 | 防止權限提升。 |
| 對敏感 API 要求 MFA | 帶有 aws:MultiFactorAuthPresent + aws:MultiFactorAuthAge 的 identity policy |
每個 API 強制執行。 |
| 識別外部可存取的資源 | IAM Access Analyzer 外部存取發現 | 現在式稽核。 |
| 識別未使用的權限 | IAM Access Analyzer 未使用存取發現 | 推動最小權限。 |
除錯 AccessDenied |
IAM Policy Simulator | 走評估鏈。 |
| 列出昨天執行動作 X 的人 | CloudTrail 事件查詢 | 過去式稽核。 |
| 稽核 MFA、金鑰輪換、密碼年齡 | IAM 憑證報告 | CSV 匯出,每週排程。 |
| 偵測外洩的 access key | Trusted Advisor 外洩 access key 檢查 | 掃描公開 GitHub。 |
| 無停機輪換 access key | 兩對 access key,逐步切換 | 分發新金鑰,停用舊金鑰,觀察期後刪除。 |
| 在維護期間暫停某個動作 | 帶有 aws:CurrentTime 的條件式 Allow |
或暫時解除附加政策。 |
| 跨帳號 role chaining | AssumeRole 兩次 | 上限 1 小時,計劃輪換。 |
| 部署前驗證新政策 | IAM Policy Simulator + Access Analyzer 政策驗證 | 雙工具組合。 |
| 基於 tag 的存取控制(ABAC) | Session tag + aws:PrincipalTag/key 條件 |
比逐隊伍建立 role 更具擴展性。 |
常見陷阱總整理 — IAM 身份、政策與存取稽核
每次 SOA-C02 考試都會看到兩三個這樣的干擾項。
陷阱 1:Permissions boundary 授予權限
不會。Boundary 只限制 identity policy 能授予的上限。有效權限是 identity policy 和 boundary 的交集。
陷阱 2:Session policy 能擴大 session 範圍
不能。Session policy 只能縮小。若 session policy 授予超出 role identity policy 的範圍,多出的部分被忽略。
陷阱 3:SCP 授予存取
SCP 只限縮。要新增一個權限,將其附加到 identity 或 resource policy;SCP 只是不能擋住它。
陷阱 4:Management account 受 SCP 約束
不受。Management account 被豁免。永遠不要在那裡執行真實的工作負載。
陷阱 5:跨帳號存取只需要來源帳號的 identity policy
需要兩者:來源帳號的 identity policy 和目標帳號的 resource policy。
陷阱 6:Role chaining 繼承目標 role 的 MaxSessionDuration
不繼承。Role chaining 無論如何都限制在 1 小時。要獲得更長的 session,需消除鏈式或定期重新整理。
陷阱 7:存取的詳細監控預設存在於 CloudTrail data event 中
不是。S3 data event 和 Lambda 呼叫事件在 CloudTrail trail 中預設關閉——你必須為每個資源明確啟用。許多「我們沒有稽核日誌」的問題都源於此。
陷阱 8:Access Analyzer 涵蓋所有資源類型
它只涵蓋特定清單(S3、IAM role、KMS key、Lambda、SQS、Secrets Manager、EFS、RDS 快照、EBS 快照、ECR 儲存庫)。其他資源需要不同的稽核工具。
陷阱 9:aws:MultiFactorAuthPresent 不需要 BoolIfExists 就能運作
在某些 session 上下文中可能失敗。在 deny 規則中為了安全起見使用 BoolIfExists。
陷阱 10:聯合使用者有 IAM user 記錄
沒有。聯合使用者有一個由 role 支撐的 session;沒有持久的 IAM user 記錄。不要在 IAM user console 中尋找他們。
陷阱 11:iam:PassRole 在你能建立資源時是隱式的
不是。以帶有 role 的方式建立 Lambda function 或 EC2 instance,需要對那個 role ARN 有明確的 iam:PassRole 權限。許多「我能建立資源但部署失敗」的問題都源於缺少 PassRole。
陷阱 12:Inline policy 與 managed policy 等效
在評估上等效,但在操作上不等效。Inline policy 不能被重用、使稽核複雜化,並且佔用主體的政策大小預算。預設使用 managed policy。
FAQ — IAM 身份、政策與存取稽核
Q1:開發者回報 AccessDeniedException 在 s3:GetObject 上。我應該先看哪裡?
第一個工具是 IAM Policy Simulator。輸入開發者的主體 ARN、動作 s3:GetObject 和確切的資源 ARN。Simulator 返回決策和哪個關卡拒絕。若決策是 explicitDeny,匹配的 statement 就是原因——通常是 SCP 或 bucket policy 的 Deny。若決策是 implicitDeny,沒有 statement 允許此動作——檢查 identity policy,然後是 bucket policy(若跨帳號),接著是 permissions boundary,再是 SCP。Simulator 讓你不必在 5 個 IAM 畫面中點擊 10 次。當 simulator 因為 session tag 或 simulator 未包含的 condition value 而與實際請求不符時,CloudTrail 的 errorMessage 欄位也很有用。
Q2:Permissions boundary 和 SCP 有什麼不同?
兩者都限制最大權限,但在不同層面。SCP 存在於 AWS Organizations,適用於 OU 或帳號中的所有主體;由 org 管理員控制。Permissions boundary 附加到特定 IAM user 或 role;由帳號內的 IAM 管理員控制。SCP 的範圍是 OU/帳號;permissions boundary 的範圍是單一 IAM user 或 role。常見組合:org 管理員在 OU 設定 region 限制 SCP;帳號管理員在每個開發者建立的 role 上設定 permissions boundary 以防止權限提升;兩者共同形成多層限制,任何 identity policy 都無法突破。SOA-C02 關於帳號內委派管理的問題使用 permissions boundary;關於全組織護欄的問題使用 SCP。
Q3:什麼時候應該使用 session policy 而非 identity policy?
當範圍是每個 session 特有且只在執行時才知道時,使用 session policy。範例:SaaS 應用程式 assume 客戶 role,傳入只列出當前交易所需操作的 session policy;身份仲介根據每個使用者的屬性限定存取範圍;CLI 腳本透過 aws sts assume-role --policy '...' 執行一次性受限操作。Identity policy 用於 role 在所有 session 中的固定權限。Session policy 是「進一步縮小這個特定 session 的權限,比 role 一般允許的更小」的正確工具;它永遠不是授予權限的正確工具,因為它只能取交集。
Q4:如何稽核「過去 90 天內誰能寫入 logs bucket」?
這其實包含兩個問題。對於外部(跨帳號)寫入存取,對 bucket 執行 IAM Access Analyzer 外部存取發現;報告列出 bucket policy 允許寫入的每個跨帳號主體。對於內部寫入存取(同帳號的主體),透過 iam:GetAccountAuthorizationDetails 枚舉 IAM user 和 role,並對每個人使用 IAM Policy Simulator 以 s3:PutObject 對 bucket 進行模擬;收集允許的結果。要回答「誰曾寫入」,在 CloudTrail trail 上啟用 S3 data event(預設關閉),查詢 eventName=PutObject。稽核人員的實際問題通常是某種組合——先問清楚他們要的是現在式的能力還是過去式的活動,然後選擇工具。
Q5:如何防止擁有 iam:CreateRole 的開發者建立 admin role?
使用 permissions boundary 加上 iam:PermissionsBoundary 的條件。建立一個 boundary 政策 DeveloperBoundary,列出開發者建立的任何 role 所能擁有的最大權限。給開發者附加 identity policy,授予 iam:CreateRole、iam:AttachRolePolicy 等,但加上條件 StringEquals: { iam:PermissionsBoundary: "arn:aws:iam::...:policy/DeveloperBoundary" }。現在開發者可以自由建立 role,但他們建立的每個 role 都必須攜帶 boundary,而 boundary 限制了 role 的有效權限。即使開發者給他們的新 role 附加 AdministratorAccess,boundary 也會將其截斷。這是 SOA-C02「委派管理而不提升權限」的標準答案。
Q6:我的 CI/CD job 的 AssumeRole session 在 MaxSessionDuration=12h 的情況下仍在 1 小時後過期。為什麼?
你遇到了 role chaining 1 小時上限。Role chaining 是當一個已 assumed role 的 session 再次呼叫 AssumeRole——第二次 AssumeRole 被硬性限制在 1 小時,不論目標 role 的 MaxSessionDuration 是多少。AWS 將此上限作為限制透過鏈式角色提升權限的安全邊界。兩種修復方式:(a) 透過 SAML 或 OIDC 聯合身份讓 CI/CD 直接 assume 最終 role 以消除鏈式(單一 AssumeRoleWithSAML / AssumeRoleWithWebIdentity,無鏈式);(b) 在腳本中每 50 分鐘從原始聯合 session 重新呼叫 AssumeRole 以刷新憑證。選項 (a) 更乾淨,也是 SOA-C02 偏好的答案。
Q7:如何要求 AWS console 使用 MFA,但服務間 API 呼叫不需要?
服務間呼叫使用 IAM role(instance profile、Lambda 執行角色、ECS task role),永遠不會有人工輸入的 MFA 代碼,所以 aws:MultiFactorAuthPresent 對它們永遠是 false。模式是:將你的 MFA 強制執行政策的範圍限定在人類 IAM user / 聯合使用者,而不是 role。將 MFA 強制政策附加到一個包含 IAM user 和聯合使用者 role 的群組 Humans。不要附加到 instance profile、Lambda 執行角色或 service-linked role。對於 SAML/OIDC 聯合人類,IdP 在驗證過程中強制執行 MFA,產生的 AWS session 繼承 MFA-present 上下文——所以如果你的 SAML assertion 包含 MFA 屬性(如 ADFS 的 AuthnContextClassRef 設定為多因素參考),aws:MultiFactorAuthPresent=true。正確設定 IdP,AWS 端的條件就自然生效。
Q8:IAM Access Analyzer 實際上做了 Policy Simulator 做不到的什麼?
Access Analyzer 使用自動化推理(對政策邏輯的數學證明)來枚舉所有能存取資源的主體,基於當前政策。它是窮舉的——不會遺漏任何組合。Policy Simulator 回答單一假設:「主體 X 是否被允許對 Z 執行 Y?」——不是窮舉。當問題是「列出所有能執行 X 的人」時,使用 Access Analyzer,因為 simulator 需要你預先指定主體,無法做到。當問題是「這個特定主體是否會成功」時,使用 Simulator,因為 Access Analyzer 不針對單一主體。兩個工具回答不同的問題,互為補充;SOA-C02 有時會要求你為情境選擇正確的工具。
Q9:ExternalId 條件如何防止 confused deputy 問題?
Confused deputy 問題是當 SaaS 提供商(代理人)被欺騙,代表惡意呼叫者使用其權限。沒有 ExternalId 的情況:SaaS 的惡意客戶,擁有自己的 AWS 帳號並設定了 SaaS 整合,知道 SaaS 的 role assume 模式(SaaS 用自己的 AWS 帳號作為主體,assume 客戶帳號中的 role)。惡意客戶在自己的帳號建立一個信任 SaaS 的 role,然後要求 SaaS 對你的 AWS 帳號 ARN 執行操作。SaaS 看到目標 ARN,試圖 assume 你的 role——這會失敗,因為你的 trust policy 列的是 SaaS,不是惡意客戶。有 ExternalId 的情況:SaaS 為每個客戶分配唯一的 ExternalId(通常是客戶的 tenant ID),並在每次 AssumeRole 時傳入這個 ExternalId。你的 trust policy 要求特定的 ExternalId。惡意客戶的 AWS 帳號需要知道你的 ExternalId 才能偽造請求——他們不知道,因為 SaaS 只有在呼叫你的 role 時才使用你的 ExternalId。結果:惡意客戶無法欺騙 SaaS 存取你的帳號。
Q10:Management account 為什麼忽略 SCP?我應該怎麼做?
AWS 將 management account 設計為始終可恢復——安全團隊可以隨時登入 management account 並修復任何全組織的錯誤設定,即使粗心大意的 SCP 否則會鎖定所有人。因此,不論 management account 在 OU 樹中的位置,SCP 都不適用於它。操作後果:永遠不要在 management account 中執行生產工作負載。只用它做 AWS Organizations 管理、帳單匯總和 break-glass 程序。所有真實的工作負載存在於 SCP、Control Tower 護欄和 Config 規則正常適用的 member account 中。SOA-C02 經常用「安全團隊在 root 套用了一個拒絕所有 S3 動作的 SCP,但 management account 中的開發者仍然可以建立 bucket」這樣的情境來考測這個豁免——答案是 management account 豁免,修復措施是將開發者的工作負載移出 management account。
延伸閱讀與相關操作模式
- AWS IAM User Guide — Introduction
- IAM Policies and Permissions
- IAM Policy Evaluation Logic
- IAM Permissions Boundaries
- Service Control Policies — AWS Organizations
- Session Policies
- Multi-Factor Authentication in AWS
- IAM Account Password Policy
- SAML 2.0 Federation
- Cross-Account AssumeRole
- STS AssumeRole API Reference
- Testing IAM Policies with the Policy Simulator
- IAM Access Analyzer
- AWS Global Condition Context Keys
- AWS Trusted Advisor Security Checks
- AWS CloudTrail User Guide
- AWS SOA-C02 Exam Guide v2.3 (PDF)
IAM 就緒之後,下一個操作層是:Multi-Account Strategy with Organizations and Control Tower,用於全組織強制執行本筆記中 SCP 和聯合身份模式;Data Protection: KMS, ACM, Secrets Manager,提供補充 IAM 存取控制的加密層;CloudTrail and AWS Config for Audit and Compliance,提供配置記錄和以規則為基礎的偵測,將 IAM 事件轉化為可行動的信號;以及 VPC Configuration and Connectivity,提供與 IAM condition key(aws:SourceVpc、aws:SourceVpce)結合的網路層存取控制,限制 API 呼叫的來源。
- Multi-Account Strategy with Organizations and Control Tower — SOA-C02 Study Notes
- Data Protection: KMS, ACM, Secrets Manager — SOA-C02 Study Notes
- CloudTrail and AWS Config for Audit and Compliance — SOA-C02 Study Notes
- VPC Configuration, Subnets, NACLs, and Private Connectivity — SOA-C02 Study Notes