examlab .net 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 38 分鐘

IAM 政策、MFA、SCP 與存取問題排查

7,600 字 · 約 38 分鐘閱讀 ·

SOA-C02 IAM 操作指南:使用者、群組、角色、聯合身份、五種政策類型(identity、resource、SCP、permissions boundary、session)、MFA 強制執行、密碼政策,以及透過 CloudTrail、IAM Access Analyzer 和 IAM Policy Simulator 進行存取稽核。

立即做 20 題練習 → 免費 · 不用註冊 · SOA-C02

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 SimulatorIAM 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:SourceVpcaws: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 keyCondition 區塊內的 JSON key(aws:SourceIpaws:MultiFactorAuthPresentaws:SourceVpcaws:RequestedRegionaws:PrincipalTag/...),根據請求上下文決定某個 statement 是否生效。
  • STS(Security Token Service):透過 AssumeRoleAssumeRoleWithSAMLAssumeRoleWithWebIdentityGetFederationToken 簽發臨時憑證的 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:MultiFactorAuthPresentaws:SourceIpaws: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:AssumeRolests: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 — 在 AssumeRoleAssumeRoleWithSAMLAssumeRoleWithWebIdentityGetFederationToken 時內嵌傳入。效果:進一步縮小 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 policyAmazonS3ReadOnlyAccessAmazonRDSFullAccess 等),客戶也可建立 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:StopLoggingcloudtrail:DeleteTrail
  • Root user 鎖定:拒絕 root user 執行基本管理以外的動作。

Management account 不受 SCP 約束——這是重要的 SysOps 陷阱(詳見下文)。

Permissions boundary — 委派管理的安全網

Permissions boundary 限制 user 或 role 的最大權限。典型使用案例:SysOps 工程師想讓資深開發者為自己團隊的 Lambda function 建立新 IAM role——但不希望這些新 role 能夠提升權限。模式如下:

  1. 建立 permissions boundary 政策 DeveloperBoundary,列出這位開發者所建 role 能擁有的最大權限。
  2. 給開發者附加 identity policy,授予 iam:CreateRoleiam:AttachRolePolicy 等——但加上條件:他們建立的 role 必須將 DeveloperBoundary 附加為 permissions boundary。
  3. 開發者現在可以自由建立 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 依序通過以下關卡評估請求。只要任一關卡拒絕,請求即被拒絕。要允許,每個適用的關卡都必須允許(或以允許解析的方式保持靜默)。

  1. 明確拒絕——任何地方優先。若任何範圍內的政策(SCP、identity、resource、permissions boundary、session)有 Effect: Deny 匹配到該動作和資源,請求即被拒絕。後續關卡無法逆轉此結果。
  2. SCP — 若主體所在 OU 有 SCP,SCP 必須允許該動作。SCP 在允許清單模式下預設拒絕一切,在拒絕清單模式下預設允許一切。AWS 提供的預設 SCP FullAWSAccess 允許所有動作;自訂 SCP 可取代或補充它。
  3. Resource policy — 若資源有 resource policy 且主體來自不同帳號,resource policy 必須允許該動作。對同帳號請求,resource policy 本身可以足夠(例如 S3 bucket policy 可單獨授予同帳號使用者——但更安全的心智模型是要求兩者都允許)。
  4. Identity policy — 附加到主體的至少一個 identity policy 必須允許該動作。
  5. Permissions boundary — 若主體有 permissions boundary,boundary 必須允許該動作。
  6. Session policy — 若請求來自帶有 session policy 的 assume role session,session policy 必須允許該動作。

這些層的 condition 評估屬於該層的允許檢查的一部分。條件失敗的行為就像未匹配——該 statement 不允許此動作,但可能有其他 statement 允許。

「明確拒絕優先」規則的細節

SOA-C02 最常考的規則:任何層的明確 Effect: Deny 會覆蓋其他所有地方的所有 Allow。常見的操作後果:開發者的 identity policy 授予了 AdministratorAccess,但 OU 層級的 SCP 有一個 Denyiam:CreateUser。無論如何,開發者都無法建立 IAM user,因為 SCP 的明確拒絕勝出。

跨帳號請求——兩側都必須允許

從帳號 A 向帳號 B 的資源發出請求時:

  1. 帳號 A 的 IAM identity policy 必須允許該動作。
  2. 帳號 B 的 resource policy 必須允許帳號 A 的主體。
  3. 帳號 A 的 SCP 和 permissions boundary 必須允許該動作。
  4. (帳號 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,正是為了支援無中斷輪換:

  1. 建立第二個 access key(此時兩個都是有效的)。
  2. 將新金鑰分發給應用程式並重新部署。
  3. 透過舊金鑰的 Last used 時間戳記確認——它應該停止被使用。
  4. 停用(而非刪除)舊金鑰,保留一段觀察期。
  5. 觀察期結束後,刪除舊金鑰。

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 使用。操作設定步驟:

  1. 設定 IdP:將 AWS 登錄為 service provider,定義 SAML assertion 的 claim(NameID、透過 https://aws.amazon.com/SAML/Attributes/Role claim 的角色映射)。
  2. 建立 IAM SAML identity provider:上傳 IdP 的 metadata XML 到 IAM。產生 SAML provider ARN。
  3. 建立 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"
      }
    }
  }]
}
  1. 在 IdP 中將 IdP 群組映射到 IAM role(通常每個 IdP 群組對應一個 IAM role)。
  2. 使用者在 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)。操作設定步驟:

  1. 建立 IAM OIDC identity provider,使用 IdP 的 issuer URL 和 TLS 憑證的指紋。
  2. 建立 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"
      }
    }
  }]
}
  1. 工作負載向 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 透過 AssumeRoleTags 參數傳入(或自動映射自 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=PutBucketPolicyDeleteBucketPolicy
  • 「本季度是誰以 root user 登入?」 — 查詢該期間的 userIdentity.type=Root
  • 「過去 90 天內哪些主體存取了 logs bucket?」 — 查詢該 bucket 的 S3 data event(必須在 trail 中單獨啟用;預設關閉)。
  • 「有人停用 CloudTrail 本身嗎?」 — 查詢 eventName=StopLoggingDeleteTrail

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)並返回:

  • 決策:allowedexplicitDenyimplicitDeny
  • 匹配的政策 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 的標準疑難排解情境。從上到下走完評估鏈。

  1. 取得確切的錯誤訊息。 CLI 的 AccessDenied 通常包含主體 ARN、動作和資源。CloudTrail 有更多細節(errorCode=AccessDeniederrorMessage="...")。錯誤訊息通常能將問題定位到特定的政策層。
  2. 執行 IAM Policy Simulator,輸入主體、動作(s3:GetObject)和資源(arn:aws:s3:::bucket/object)。Simulator 返回決策和匹配(或未匹配)的政策。大多數 SOA-C02 疑難排解題都將 simulator 視為第一個工具。
  3. 檢查 SCP,若主體在 Organizations OU 中。SCP 是最令人意外的阻擋因素,因為它在 org 層級設定,從帳號層面看不到。
  4. 檢查 resource policy——是同帳號還是跨帳號請求?跨帳號時,bucket policy 必須明確允許該主體。同帳號時,bucket policy 仍可能透過帶條件的 Effect: Deny 封鎖。
  5. 檢查 identity policy——user/role/group 是否有附加允許該動作的政策?
  6. 檢查 permissions boundary——若 role 有 boundary,它是否允許該動作?
  7. 檢查 session policy——若請求來自帶有 session policy 的 assumed role,session policy 是否允許?
  8. 檢查 condition key——aws:SourceVpcaws:SourceIpaws:MultiFactorAuthPresents3:x-amz-server-side-encryption——任何一個都可能導致請求失敗。
  9. 檢查加密——bucket 可能要求 SSE-KMS,但請求使用了 SSE-S3 或沒有加密標頭。
  10. 查看 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 加上離線模擬以程式化方式完成。

完整的操作答案:

  1. 對外部(跨帳號)寫入存取:在 bucket 上執行 IAM Access Analyzer 外部存取發現。
  2. 對內部寫入存取:列出帳號中的 IAM user + role,對每個人使用 Policy Simulator 以 s3:PutObject 對該 bucket 進行模擬,收集允許的結果。
  3. 對歷史寫入記錄:在 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:MultiFactorAuthPresentaws:RequestedRegionsts: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:開發者回報 AccessDeniedExceptions3: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 Simulators3:PutObject 對 bucket 進行模擬;收集允許的結果。要回答「誰寫入」,在 CloudTrail trail 上啟用 S3 data event(預設關閉),查詢 eventName=PutObject。稽核人員的實際問題通常是某種組合——先問清楚他們要的是現在式的能力還是過去式的活動,然後選擇工具。

Q5:如何防止擁有 iam:CreateRole 的開發者建立 admin role?

使用 permissions boundary 加上 iam:PermissionsBoundary 的條件。建立一個 boundary 政策 DeveloperBoundary,列出開發者建立的任何 role 所能擁有的最大權限。給開發者附加 identity policy,授予 iam:CreateRoleiam: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。

延伸閱讀與相關操作模式

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:SourceVpcaws:SourceVpce)結合的網路層存取控制,限制 API 呼叫的來源。

官方資料來源

更多 SOA-C02 主題