AWS企業帳號代理 AWS Lambda權限配置錯誤排查
第一章:錯誤訊息不是答案,但能指向方向
很多人一看到「AccessDeniedException」或「Unable to assume role」就立刻去改 IAM Policy,結果往往越改越亂。實務上,權限問題通常不是單點故障,而是「信任(trust policy)」「授權(permission policy)」「資源範圍(resource)」或「條件(condition)」,其中一環不符合才會失敗。你需要的不是猜測,而是一套能把線索整理成決策的排查順序。
我建議你把錯誤訊息拆成三部分來看:
- 誰失敗:是 Lambda 自己執行時被拒?還是服務在觸發時無法假設角色?
- 拒絕的動作是什麼:例如
lambda:InvokeFunction、s3:GetObject、kms:Decrypt、sts:AssumeRole。 - 在哪個階段失敗:事件源觸發前、初始化期間、還是程式邏輯呼叫 AWS API 的時候。
這三點對應到兩個常見的權限面:角色信任與角色授權。只要你能判斷它是哪一類,後續就會少走很多冤枉路。
第二章:最常見的四類 Lambda 權限錯誤
下面整理出在真實專案中最常遇到的四種權限配置錯誤。每一種都對應不同的排查路徑。
1)信任關係錯誤:Trust policy 沒讓「該服務」假設角色
錯誤形式常見是 AccessDenied 或 Not authorized to perform sts:AssumeRole,而動作是 sts:AssumeRole。這通常意味著:
- 你以為 Lambda 角色是給 Lambda 用的,但它其實是讓某個服務(例如 API Gateway、EventBridge、S3)去觸發。
- 或者你反過來:Lambda 要去存 S3,但你把需要的是 permission policy 的動作寫成了 trust policy。
- 最常見還有:Principal 寫錯(服務沒有列入),或 SourceArn/SourceAccount 條件不匹配。
信任錯誤的重點不是「你給了什麼權限」,而是「誰被允許假設這個角色」。
2)授權動作錯誤:Policy 裡的 action 或條件不符合實際呼叫
典型表現是看到 AccessDeniedException 指向某個 API 動作,例如:
s3:ListBucket沒有,導致你在程式中列舉物件失敗。s3:GetObject沒有,導致下載物件失敗。kms:Decrypt沒有,導致你解密環境變數或加密物件失敗。
很多人只給了看起來「差不多」的權限,卻漏掉真正用到的那個動作。還有一種狀況是條件(例如 StringEquals、ArnLike)與事件來源或資源 ARN 的格式不一致,導致明明寫了 action 仍然被拒絕。
3)資源範圍錯誤:Resource 寫死或寫錯 ARN
IAM 的 Resource 寫錯是權限錯誤的另一個大宗。尤其是:
- 你給了
arn:aws:s3:::my-bucket/path/*,但程式讀的是另一個 prefix。 - 你給了某個特定的 KMS key ARN,但你其實用的是另一把 key,或是 S3 端自動使用了預設的 SSE-KMS key。
- 你在不同環境(dev/stage/prod)共用同一份 policy,結果 ARN 指向錯誤帳號或錯誤區域。
這類錯誤的特徵是錯誤訊息會清楚指出「被拒絕的資源」是什麼,對應地你就能回頭驗證 policy 的 Resource 是否覆蓋。
4)網路與存取路徑錯誤:Lambda 在 VPC,卻缺少必要的 egress 或端點
如果你的 Lambda 配在 VPC,權限問題有時候看起來像「存取被拒絕」,但實際上是網路層阻斷,或 AWS API 呼叫根本沒能送到 AWS。此時錯誤可能不是 AccessDenied,而是超時、DNS 解析失敗等。
雖然這是「網路」而非純 IAM,但它常被歸在「權限配置錯誤排查」的範疇:因為你通常會同時檢查 IAM 和 VPC 設定。判斷方式是先看 CloudWatch Log 的具體錯誤類型;若是權限拒絕就去 IAM,若是連線失敗就回頭查子網、路由表、NAT 或 VPC 端點。
第三章:建立排查清單:先縮小範圍,再動到設定
排查權限錯誤最怕「跳步」。我通常用以下清單,按順序做,確保每一步都能排除大片可能性。
AWS企業帳號代理 步驟 1:回到 CloudWatch 的錯誤行
第一件事是找到具體錯誤堆疊,特別是 AWS SDK 呼叫的那一行。很多人只看 Console 的紅字摘要,卻忽略了更精準的 API 名稱。
你要找的是:
- 錯誤碼(如
AccessDeniedException、UnrecognizedClientException、InvalidClientTokenId、KMSAccessDeniedException) - 動作名稱(錯誤訊息通常會包含
not authorized to perform: X) - 失敗在程式哪個階段(初始化、取得配置、呼叫某個服務)
有了這些,你就能決定要看角色授權還是信任,甚至能直接定位到某一個 policy fragment。
步驟 2:確認 Lambda 執行角色(Execution Role)是否正確
在 Console 檢查 Lambda 的 Configuration > Permissions,確認 Execution role 指向你預期的那個 IAM Role。這看似瑣碎,但在實務上非常常見:
- 複製函式後角色沒換
- 環境切換後角色指回錯誤帳號
- 用 IaC 部署時 variable 沒代入成功
只要角色不同,後面的排查全都可能是錯方向。
步驟 3:判斷是「AssumeRole」還是「API 呼叫被拒絕」
如果錯誤訊息出現 sts:AssumeRole,優先檢查 trust policy。若錯誤指向 s3:GetObject、logs:CreateLogGroup、kms:Decrypt 等,優先檢查 permission policy。
你可以把這一步當成「切換排查分支」。信任錯誤的修復方式與授權錯誤完全不同,別混在一起改。
步驟 4:檢查 Resource 與條件(Condition)是否真的覆蓋
授權 policy 看起來寫了正確 action,但只要 Resource 沒覆蓋或條件不成立,仍會被拒。排查時請直接對照錯誤訊息中的 resource ARN。
特別注意這些常見陷阱:
- 區域與帳號寫死,造成跨區或跨帳號不匹配。
- 用
ArnLike或ArnEquals時,ARN 的格式(是否包含尾端:、是否包含萬用字元)不一致。 - 為了安全加上
aws:SourceArn限制,但事件來源實際 ARN 跟你預期不同(例如規則名或 stage 不同)。
第四章:分情境排查(用你會遇到的真實案例思路)
接下來用幾個常見情境示範「你應該看哪裡」。這不是要你背模板,而是讓你掌握排查思路:錯在哪一層、就回到那一層。
情境 A:S3 觸發 Lambda,卻說沒有假設角色或沒法呼叫
這類通常牽涉到兩段授權:
- S3 作為事件源,需要能觸發 Lambda(通常涉及 Lambda 的資源型權限,例如
lambda:InvokeFunction給 S3)。 - AWS企業帳號代理 Lambda 內部程式需要存取 S3 物件(
s3:GetObject等)。
你要先分辨錯誤來自哪一段。
若錯誤出現 sts:AssumeRole:多半是 trust policy 或事件觸發的權限設定不完整。此時你要檢查「讓 S3 觸發 Lambda」那段設定。
若錯誤出現 s3:GetObject 被拒:那就不是觸發層問題,而是 Lambda 執行角色缺少對應的 s3:GetObject 或 Resource prefix 不包含目標物件。
情境 B:EventBridge 觸發 Lambda,偶爾失敗但多數時候正常
這種「間歇性」常見原因是條件過度精細。例如你在觸發權限中加了 aws:SourceArn 限制,但規則在不同事件或不同環境會生成不同 ARN;又或你使用萬用字元太保守,導致某些目標沒有被匹配。
排查時做兩件事:
- 查看失敗那次的事件來源(rule ARN、target ARN)實際值。
- 對照你寫的條件(Condition)是否真的涵蓋這次的 ARN。
如果你看不到 rule 觸發的實際來源 ARN,你可以先放寬條件做驗證:用更廣的匹配確認事件流程能打通,再逐步收緊以符合最小權限。
情境 C:加密相關失敗:KMSAccessDenied 或解密失敗
KMS 是權限錯誤最容易令人挫折的地方,因為你常以為只要給了 Lambda 存取 S3 的權限就夠了,但 KMS 解密是另一個授權鏈。常見情形:
- AWS企業帳號代理 Lambda 需要讀取被 SSE-KMS 加密的 S3 物件,程式呼叫
s3:GetObject,但真正卡在kms:Decrypt。 - Lambda 環境變數使用 KMS key 加密,初始化時就需要解密。
此時排查重點是兩層:
- IAM permission policy:Lambda 執行角色要有對 KMS key 的
kms:Decrypt、必要時還有kms:DescribeKey。 - KMS key policy:key policy 也要允許該角色使用(或允許 AWS service 與條件匹配)。
很多人只改 IAM,不改 key policy,結果仍然失敗。相反,也有人只改 key policy,卻忘了 IAM 角色本身沒有 kms:Decrypt。
情境 D:VPC 配置導致「看起來像權限問題」
AWS企業帳號代理 如果錯誤是超時、連線失敗或 DNS 錯誤,你要把排查從 IAM 拉回網路。Lambda 在私有子網時要能連到需要的端點:
- 若要連公網服務,通常要 NAT Gateway。
- AWS企業帳號代理 若你限制只走 AWS 私有網路,則可能要配 VPC Interface Endpoint(例如 S3、KMS、STS、CloudWatch Logs 等)。
如何快速判斷?看錯誤是不是明確提到「not authorized to perform」。若不是,優先查網路。
第五章:把權限拆成「信任」與「授權」兩張地圖
理解 Lambda 權限其實就等於理解兩張圖:一張是「誰可以假設這個角色」,另一張是「角色可以做什麼」。你可以把它們視為信件的信封與信件內容。
角色 Trust policy:只回答「誰能進來」
Trust policy 決定外部主體能不能使用 sts:AssumeRole。常見 Principal 包含:
- 某個 AWS 服務(如
lambda.amazonaws.com、events.amazonaws.com、apigateway.amazonaws.com、s3.amazonaws.com) - 或特定帳號/角色(跨帳號時常見)
若你加了 Condition(例如 aws:SourceArn),務必確認它真的會在當前情境中產生對應值。這也是間歇性或環境切換失敗的核心原因之一。
角色 Permission policy:回答「能做哪些事、對哪些資源」
Permission policy 決定 action 與 resource 的覆蓋範圍。排查時我會用「三問」方式:
- 程式需要的 action 是什麼?(看錯誤訊息)
- 我 policy 裡有沒有包含它?(包含與否)
- 資源 ARN 是否覆蓋?(resource 是否剛好命中)
很多錯誤不是缺 action,而是缺 resource 覆蓋;或 action 有了,但 resource 只覆蓋了某個 prefix。
第六章:用最小權限原則,但不要被最小權限綁死
理想狀態是最小權限。但現場最怕的是:你每修一次就要精準調整,結果花了兩天還沒有修好。
我的建議是「先打通,再收緊」。做法如下:
- 先放寬以驗證路徑:把暫時缺失的 action 加上,或把 resource 改成對應的同 bucket/同 key 範圍。
- 驗證能否成功:看同一段流程是否通過(例如同一個事件、同一個 S3 物件、同一個 KMS key)。
- 再收緊到最小:確認真正用到的 prefix、key、條件值。
這不是放任,而是把風險控制在「短時間、可追蹤、可回滾」的範圍內。你要的是速度與可控性,而不是一開始就完美。
第七章:實用技巧:讓排查變快的幾個抓手
技巧 1:直接用錯誤訊息的 action 與 resource 回推
AWS企業帳號代理 不要只看「AccessDenied」。把完整錯誤行中的 not authorized to perform: X on resource: Y 抄下來,你就知道要加什麼 action、resource 是否覆蓋。這能避免你在 policy 上做猜測。
技巧 2:同時檢查 CloudWatch Logs 權限(初始化也可能失敗)
有時候你以為程式跑不動,但其實連 log 都打不出來。尤其是 Lambda 需要把錯誤寫進 CloudWatch。若缺少:
logs:CreateLogGrouplogs:CreateLogStreamlogs:PutLogEvents
AWS企業帳號代理 可能導致你看不到真正的失敗細節。排查初期可以先確認基本日誌權限是否存在,否則你會陷入「沒有證據」的狀態。
技巧 3:用不同環境的 ARN 差異來解釋「為什麼 dev 能跑 prod 不能」
權限錯誤最愛出現在環境切換。原因通常是:
- Resource 中的 ARN 指向 dev bucket,但 prod 物件在另一個 bucket。
- Condition 的 SourceArn 使用了 dev 的 rule 名稱。
- KMS key 指向 dev 的 key。
所以你要做的是把「差異」找出來:同一份模板在兩環境中究竟渲染出什麼 ARN。只要差異在,那權限就一定會跟著出問題。
技巧 4:跨帳號時,別只改對方給你的 policy
跨帳號最常見漏點是:你只在目標帳號的角色上加了權限,卻沒在信任或 key policy 上允許源帳號的主體。結果就是:
- AssumeRole 失敗(trust policy)
- 或 AssumeRole 成功,但後續對資源操作失敗(permission policy / resource / KMS key policy)
你必須同時確認「兩端」:你要用誰、對方允不允許你用。
第八章:一份可直接使用的排查流程(你可以照著跑)
最後我把整篇的思路收斂成一份流程。當你下一次遇到 Lambda 權限配置錯誤,只要照順序做,通常 30 分鐘到幾小時內就能定位到原因。
流程 1:確認錯誤類型
- AWS企業帳號代理 若看到
sts:AssumeRole:先看 trust policy(角色的信任關係)。 - 若看到具體 AWS API 動作被拒:先看 permission policy(角色的授權與 resource)。
- 若是超時/連線失敗:先看 VPC 網路或 endpoint,不要一開始就當成 IAM 錯。
流程 2:鎖定錯誤行與動作資源
- 從 CloudWatch 的堆疊抓出
not authorized to perform的 action 與 resource ARN。 - 把它對照到你寫的 policy 片段:action 是否包含,resource 是否覆蓋。
流程 3:核對角色與環境一致性
- 確認 Lambda 的 Execution role 就是你以為的那個。
- 確認 dev/stage/prod 的 ARN 是否一致(bucket、prefix、rule、key)。
流程 4:若涉及 KMS,檢查 IAM 與 key policy 都要允許
- IAM:需要
kms:Decrypt(以及必要的 Describe)。 - KMS key policy:需要允許該角色/帳號與條件匹配。
流程 5:必要時先放寬驗證,再收緊到最小
- AWS企業帳號代理 先補上缺的 action 或覆蓋正確資源範圍。
- 跑通流程後再逐步收縮。
第九章:把經驗寫進制度,讓下一次不再重來
權限錯誤之所以反覆出現,往往不是工程師不努力,而是缺少「可重複」的檢查機制。你可以把排查結果固化成團隊制度:
- 為每種常見事件源(S3、EventBridge、API Gateway)建立驗證清單:觸發權限與執行權限是否分開檢查。
- 模板化 policy 時,保證 action、resource、condition 的參數化正確,並在部署後用腳本或手動核對渲染結果。
- 針對 KMS、VPC 這種高風險元件,在變更流程中加入固定的覆核步驟。
當你把「錯誤訊息如何指向政策」這件事制度化,排查就會從碰運氣變成推理。久而久之,你會發現權限問題不是不可預測的災難,而是可以被規律拆解的工程任務。
結語:權限不是障礙,是讓系統更可控的契約
Lambda 權限配置錯誤排查最重要的不是記住多少條 IAM 規則,而是理解 AWS 在每一次拒絕時都留下了明確線索:是 trust 沒通、permission 沒覆蓋、resource 不匹配、還是 KMS/VPC 在暗中切斷路徑。你只要照著「先判斷錯誤類型→再鎖定 action 與 resource→最後在正確層級修復」的節奏走,修復會變得可預期。
下次再遇到 AccessDenied,把焦點從「我到底缺了什麼」轉成「AWS 具體拒絕了什麼」。答案通常就在錯誤訊息裡,只差你用對方式讀它。


