iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 5 篇

Day 5|明明已經 Allow,為什麼還是 AccessDenied?

  • 分享至 

  • xImage
  •  

上一篇提到,Control Tower 與 AWS Organizations 可以透過 Controls、SCP 等機制建立帳號層級的治理邊界,不過帳號允許使用某項 AWS 服務,不代表其中每個 IAM User 或 Role 都能直接操作該服務。

假設某位工程師需要把部署檔上傳到指定的 S3 Bucket,他檢查部署使用的 IAM Role,確認 Policy 已經允許 s3:PutObject:

{
  "Effect": "Allow",
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::company-release-prod/*"
}

但實際上傳檔案時,仍然收到 AccessDenied。

既然已經有 Allow,AWS 為什麼還是不允許這次操作?

IAM 不會找到 Allow 就停止判斷

AWS 收到請求後,不會只檢查其中一份 Policy,而是根據呼叫身分、操作、資源、條件,以及所有適用的政策一起判斷結果。

最基本的規則可以先記成三句:

  1. 沒有符合的 Allow,預設就是拒絕。
  2. 有符合的 Allow,請求才有可能通過。
  3. 只要任何適用的政策出現明確的 Deny,最後仍然是拒絕。

一次請求可能同時受到以下政策影響:

政策類型 主要用途 是否能直接授予權限
Identity-based Policy 定義 IAM User 或 Role 可以執行哪些操作 可以
Resource-based Policy 從 S3 Bucket、SQS Queue 等資源端決定誰可以存取 可以
Permissions Boundary 限制 IAM User 或 Role 最多能取得哪些權限 不會
Session Policy 限制這一次暫時憑證工作階段的權限 不會
SCP 限制成員帳號中的身分最多可以執行哪些操作 不會
RCP 限制組織內資源最多可以接受哪些存取 不會

Permissions Boundary、Session Policy、SCP 與 RCP 比較像權限的上限,它們不會主動把權限授予某個 Role,只會進一步限制原本可以使用的範圍。

因此,即使 Identity-based Policy 已經有 Allow,只要這項操作超出其他政策允許的範圍,最後仍然會被拒絕。

https://ithelp.ithome.com.tw/upload/images/20260919/20183052aY9HZkNnNq.png

圖:IAM 身分的有效權限,是 Identity-based Policy、Permissions Boundary 與 SCP 共同允許的範圍。此圖為簡化示意,未包含 Session Policy、Resource-based Policy 與 RCP;任何適用的明確 Deny 仍會優先拒絕請求。

先確認是哪一層拒絕了這次操作

看到 AccessDenied 時,不能只根據 Role Policy 裡已經有 Allow,就直接判斷是哪一份政策出了問題。

同樣是 s3:PutObject 失敗,可能的原因包括:

  • 實際發出請求的不是預期中的 IAM Role。
  • Identity-based Policy 的 Action、Resource 或 Condition 不符合。
  • Permissions Boundary、Session Policy 或 SCP 限縮了可用權限。
  • Bucket Policy 或 VPC Endpoint Policy 拒絕了這次請求。
  • Bucket 使用 SSE-KMS 加密,但呼叫身分缺少需要的 KMS 權限。

因此,我會先確認實際發出請求的身分:

aws sts get-caller-identity

接著核對錯誤中的 Action、Resource 與完整訊息。有些 AccessDenied 訊息會進一步指出,是 Identity-based Policy 沒有允許、Permissions Boundary 限制了操作,或 SCP 中存在明確的 Deny;但並非所有服務都會提供相同程度的說明。

如果訊息只有簡短的 AccessDenied,就要回頭確認這次請求實際經過哪些政策與服務,而不是繼續在同一份 Role Policy 裡增加 Allow。

同樣是權限不足,背後可能代表完全不同的事情:可能是 Role 根本沒有取得權限,也可能是組織刻意限制這項操作,還可能是資源本身不接受這次存取。

這些政策看起來都在處理「權限」,實際上負責的問題並不相同:Identity-based Policy 回答的是「這個身分可以做什麼」;Permissions Boundary 與 SCP 設定的是「最多不能超過哪裡」;Resource-based Policy 與 RCP 則從資源端決定「這個資源願意接受誰的存取」。

因此,處理權限需求時,不能只問 Policy 裡有沒有 Allow,也不能看到 AccessDenied 就隨便挑一份政策放寬,更重要的是先判斷:這項規則要授予誰權限、限制多大的範圍,以及應該由身分端、組織端還是資源端負責。

一項權限應該放在哪一層?

不同政策解決的是不同範圍的問題,我通常會先確認這項規則是在授予工作需要的權限,還是在設定不能跨越的邊界,舉幾個簡單的例子來說明,當然實現方式有很多,這邊也分享一下我的作法。

權限需求 適合放置的位置 原因
部署 Role 可以把檔案上傳到指定 S3 Bucket Identity-based Policy 屬於特定 Role 完成工作需要的權限
某個 IAM Role 最多只能操作核准的服務 Permissions Boundary 限制這個 Role 能取得的權限上限
所有成員帳號都不能停止 CloudTrail SCP 屬於整個組織都不能違反的限制
集中日誌 Bucket 不得接受組織外部存取 RCP,必要時搭配 Bucket Policy 從資源端限制可以接受的存取範圍
單一 Bucket 只允許指定 Role 存取 Bucket Policy 規則只和該資源有關,不必影響整個組織

可以把判斷方式簡化成以下幾個方向:

  • 只影響一個 IAM User 或 Role,優先從 Identity-based Policy 處理。
  • 要限制某個 User 或 Role 最多能取得什麼權限,使用 Permissions Boundary。
  • 所有成員帳號中的身分都不能違反,才提升到 SCP。
  • 規則是保護整個組織內的資源,考慮 RCP。
  • 規則只和某個 Bucket、Queue 或 KMS Key 有關,通常放在該資源的 Resource-based Policy。

規則放得越上層,涵蓋範圍越大,但例外也越難處理;規則越靠近特定 Role 或資源,調整比較靈活,但一致性需要由各團隊自行維持。

例如,「所有成員帳號都不能停止 CloudTrail」可以優先放在 SCP,因為它不會隨不同 Role 改變,但如果只是某個部署 Role 需要上傳檔案,把 Bucket 名稱與 s3:PutObject 寫進 SCP,就會讓組織政策混入應用程式細節,未來 Bucket 更名或部署方式改變時,也必須修改影響範圍更大的組織政策。

相反地,如果「不能停止 CloudTrail」只寫在個別 Role Policy,其他 Role 仍然可能取得這項權限,也無法真正形成組織層級的邊界。

政策不是放得越集中越好,而是要放在和影響範圍相符的位置。

回到一開始的案例,s3:PutObject 只屬於部署 Role 的工作權限,因此我會選擇放在 Identity-based Policy,而不是把特定 Bucket ARN 寫進影響整個組織的 SCP 或 RCP。

如果這個 Role 還套用了 Permissions Boundary,該操作也必須落在 Boundary 允許的範圍內;但 Boundary 只負責限制上限,不會取代 Identity-based Policy 授予權限。

換句話說,工作所需的權限盡量放在靠近身分或資源的位置;所有帳號都不能違反的規則,才提升到 Organizations 層。 規則放得越上層,影響範圍越大,例外也越難處理。

AccessDenied 不一定代表權限給得不夠多,更可能代表另一層政策不允許這次請求,真正要確認的不是還能在哪裡補一條 Allow,而是哪一層正在限制它,以及那項限制是否符合原本的設計。

今天討論的仍然是組織內部如何判斷與放置權限,如果呼叫端與資源分屬不同帳號,除了呼叫者本身要有權限,目標帳號也必須願意接受這次存取。下一篇會繼續拆解跨帳號存取,看看 AssumeRole、Trust Policy 與 Resource-based Policy 分別解決什麼問題。

參考資料


上一篇
Day 4|多帳號治理該自己做,還是交給 Control Tower?
下一篇
Day 6|跨帳號存取,該用 AssumeRole 還是 Resource-based Policy?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言