🗺️ GCP 服務地圖
安全與身分・身分與存取・ACE/PCA/PCSE

資源階層與 IAM:權限怎麼往下繼承

同一個角色,授予在機構、資料夾、專案或單一值區,影響範圍可以差上百倍;下層也收不回上層給的權限。這一頁讓你看懂有效權限是怎麼疊出來的、拒絕政策怎麼擋,並替每個需求挑出最小又夠用的角色與層級。

繼承模擬器:允許+拒絕政策 最小權限分診:10 個情境 控制台・gcloud・Terraform 授權

💡 先搞懂問題

虛構公司「青松物流」把訂單系統搬上 Google Cloud 的第一個月,為了趕上線,IT 主管在專案上把五位工程師都設成 Editor,外包廠商也拿到同樣的權限;部署管線則用一把下載下來的服務帳戶金鑰,放在程式碼儲存庫的設定檔裡。上線第二個月,一位工程師在清理測試資料時刪錯了值區,正式環境的出貨單 PDF 全部消失;資安顧問掃描儲存庫時又發現那把金鑰已經被推到公開的分支上。稽核要求「每個人只拿工作需要的權限」,團隊卻不知道該從哪裡收:Editor 拿掉了,某些人照樣能改,因為他們在資料夾或機構層級還有別的授權。

新手在 Google Cloud 最常卡住的有三件事。第一,不知道授權放在哪一層差多少:同一個角色授予在資料夾上,底下現在與未來的每個專案、每個值區都適用。第二,想用「在下層把權限拿掉」來收斂,結果發現做不到,因為允許政策只會往下加,不會往下減。第三,把「誰能做」和「能不能這樣設定」混在一起,例如想用 IAM 禁止全公司建立服務帳戶金鑰,或想用 IAM 規定資源只能開在台灣,這些其實是機構政策的工作。

Google Cloud 處理「誰能對什麼做什麼」的服務叫 Cloud IAM(Identity and Access Management)。它的核心是掛在資源上的允許政策(allow policy),政策裡是一筆筆角色繫結(role binding):把一個角色(role),也就是一組權限,授予一或多個主體(principal),例如 Google 帳戶、Google 群組或服務帳戶(service account)。允許政策可以掛在資源階層(resource hierarchy)的任何一層:機構(organization)、資料夾(folder)、專案(project),以及支援 IAM 的個別資源,例如 Cloud Storage 的值區(bucket)或 Compute Engine 的 VM。

集團門禁(比喻) Google Cloud 資源階層 青松集團(總部) 物流事業群 台中分公司 倉庫裡的堆高機、檔案櫃 機構 Organizationqingsong.example 資料夾 Folderfld-prod(正式環境) 專案 Projectqs-order-prod(訂單系統) 資源:值區、VMqs-order-docs、vm-order-01 集團規章:能怎麼裝修、放哪裡 機構政策:資源能怎麼設定
左邊是比喻,右邊是本頁虛構的青松物流在 Google Cloud 的四層結構。灰色箭頭代表授權往下延伸:在物流事業群給的門禁,台中分公司和倉庫自然都能進;只在倉庫給的,就只管那幾台設備。下方的虛線框是另一套東西:它不管誰能進門,而是規定進門後能怎麼做。

生活比喻:集團門禁卡

青松集團底下有物流、零售幾個事業群,每個事業群有好幾間分公司,分公司倉庫裡有堆高機、檔案櫃這些設備。總務處發門禁時,不會一台設備一台設備設定,而是決定這張卡「在哪一層有效」:集團稽核主任的卡在總部層級生效,所有事業群、所有分公司都刷得過;物流事業群的值班主管只在物流事業群生效,旗下每間分公司都能進,但進不了零售事業群;倉庫的堆高機操作員只拿到那幾台設備。卡片權限也分等級,有的卡只能進門看,有的能操作設備,總務處的人還能替別人發卡。

同一個人可以同時從好幾個地方拿到權限:他所屬的「倉儲組」在事業群層級有一張卡,他自己又被加上某間分公司的卡,他能進的地方就是兩者的總和。這時候在分公司把他的卡收回,他還是刷得進去,因為事業群那張卡沒動。總部若真的要擋,只能發一道禁令:「除了保全組,任何人都不准進機房」,不管手上有幾張卡,禁令都優先。另外,集團還有一本規章,規定倉庫不准加蓋夾層、檔案櫃只能放在台灣的據點,這和門禁無關,就算你是能進門的主管也得照規章來。

回到 Google Cloud:總部、事業群、分公司、設備對應的就是機構、資料夾、專案、資源;「這張卡發給誰」是主體,「進門後能做什麼」是角色,例如只能看的 Viewer、能操作 VM 的 roles/compute.instanceAdmin.v1、能替別人授權的 Owner;把角色授予主體就是一筆角色繫結,一層上所有繫結合起來是那一層的允許政策。門禁往下延伸是繼承,多張卡取總和就是官方說的有效允許政策(effective allow policy)是聯集;總部的禁令是拒絕政策(deny policy),IAM 一定先檢查它;集團規章則是機構政策服務(Organization Policy Service):IAM 管「誰(who)」能做,機構政策管「什麼(what)設定」被允許。
允許政策(掛在專案 qs-order-prod 上) 一份政策=多筆角色繫結;權限不能直接給主體,一定要透過角色 繫結 1 角色:roles/compute.instanceAdmin.v1 主體:group:ops-team@example.com 條件:無(一直有效) 繫結 2 角色:roles/storage.objectViewer 主體:serviceAccount:order-reader@… 條件(選用):request.time < 2027-01-01(示意)
這就是控制台「授予存取權」背後真正存下來的東西。考題寫「讓某群組能管理某專案的 VM」時,其實在問三格:角色挑哪一個、主體填誰、掛在哪一層的允許政策上。IAM 條件(IAM Conditions)是選用的第四格,可以讓繫結只在某段時間或某些資源上有效,但不能加在 Owner、Editor、Viewer 這三個舊版基本角色上。

比喻有幾個地方和 Google Cloud 不一樣,剛好也是最常考錯的地方。第一,實體門禁可以單獨把某人從某樓層「除名」,但 Google Cloud 的允許政策只能加、不能減:上層給了,下層的允許政策再怎麼寫都收不回來,要擋只能用拒絕政策,或把授權從上層移掉重新設計。第二,門禁系統通常同時管員工名冊;Google Cloud 的使用者帳號不在 IAM 裡建立,而是來自 Google 帳戶、Cloud Identity 或 Google Workspace,IAM 只負責授權。第三,堆高機不會自己刷卡,但雲端裡的程式會:程式要用的身分是服務帳戶,它既是能被授權的主體,本身也是一個資源,「誰能借用這個服務帳戶」同樣要用 IAM 管。

志明的請求 建立 VM 位置:us-central1 IAM 問:「誰」能做? 他有 compute.instances.create (來自專案上的角色繫結) ✓ 通過 機構政策 問:能「這樣設定」嗎? 資源位置限制條件 只允許 asia-east1 ✕ 擋下 兩道關卡都要通過,請求才會成功;誰的權限再大,機構政策都照樣適用
同一個請求要過兩道關卡。IAM 看身分與權限;機構政策不看是誰,只看這個設定值准不准,例如資源位置、是否允許外部 IP、能不能建立服務帳戶金鑰。所以「全公司都不准建立服務帳戶金鑰」這類需求,答案是機構政策,不是在每個專案收回權限。

🎮 互動實驗室一:繼承模擬器

「資源樹與有效權限」是青松物流的資源階層(桌機在右邊,手機在下方)。先在左邊選主體與角色,再點樹上的節點當作授予層級,按「新增角色繫結」。樹上每個節點會即時標出這個主體在那裡的有效權限:綠色是可以、灰色刪除線是不行、紅色是被拒絕政策擋下、藍色是靠 IAM 條件才有效。下方可以打開兩條拒絕政策,看看它們怎麼壓過允許政策。上方有四個任務,做完按「檢查任務」;點樹上的節點,下方會依「先拒絕、後允許」的順序說明這個權限從哪裡來。

新增角色繫結(允許政策)

授予層級(點資源樹上的節點選擇)
這個主體目前的角色繫結
    拒絕政策(對所有主體評估)

    資源樹與有效權限

    可以 有權限不行 沒權限拒絕 被拒絕政策擋下條件 靠 IAM 條件
      點樹上的節點,這裡會說明這個主體在該節點的權限從哪裡來。
      任務完成 0 / 4
      畫面說明:載入中。

      🎮 互動實驗室二:最小權限情境分診

      每張卡是一個虛構公司的需求。先挑「做法」,再挑「授予或設定的層級」,按「確認」。兩個都要對:做法要夠用但不多給,層級要涵蓋需求但不擴散。有些需求根本不是「給誰什麼角色」的問題,而是要用機構政策、拒絕政策,或用 Workload Identity Federation 換掉服務帳戶金鑰。答完會說明原因,選錯時也會說明你選的那個什麼時候才適合。

      兩項全對 0 / 0
      連續全對 0
      ① 做法
      ② 授予或設定的層級
      畫面說明:先問三個問題:這是「誰能做」還是「能不能這樣設定」?身分是人還是程式,程式跑在 Google Cloud 裡面還是外面?需求提到的東西最小落在哪一層?

      🛠️ 操作教學:授予角色並建立服務帳戶

      情境:青松物流要讓「維運組」群組能管理訂單專案的 VM,並替報表程式建立一個只能讀取值區物件的服務帳戶。左邊是簡化的控制台,照步驟填欄位、按「下一步」;右邊的 gcloud CLI 與 Terraform 會跟著你填的專案 ID、主體、角色、條件與服務帳戶 ID 即時更新,目前步驟對應的那幾行會用底色標出來。可以故意把專案 ID 或服務帳戶 ID 打錯,或替基本角色加上條件,看看驗證訊息。

      示意畫面:簡化重繪,只保留和本主題有關的欄位;實際畫面以 Google Cloud 控制台為準。
      ☁ 雲端主控台my-project-id🔍 搜尋資源、服務與文件🔔

      換一個層級:資料夾授權與自訂角色

      上面的步驟都授予在專案。要讓稽核群組看得到整個正式環境資料夾底下所有專案的 IAM 政策,就把繫結放在資料夾;要讓外包人員只能檢視、啟動、停止 VM,預先定義角色又都太大時,才建立自訂角色。注意自訂角色只能建在機構或專案,不能建在資料夾;建在專案的自訂角色,也只能在那個專案裡授予。

      # 在資料夾授權:底下所有子資料夾、專案與資源都會繼承
      gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \
        --member="group:auditors@example.com" \
        --role="roles/iam.securityReviewer"
      
      # 在專案建立自訂角色(角色 ID 不能有連字號)
      gcloud iam roles create vmOperator \
        --project=my-project-id \
        --title="VM Operator" \
        --description="檢視、啟動與停止 Compute Engine VM" \
        --permissions=compute.instances.get,compute.instances.list,compute.instances.start,compute.instances.stop \
        --stage=GA
      
      # 授予自訂角色時,要寫完整路徑 projects/專案 ID/roles/角色 ID
      gcloud projects add-iam-policy-binding my-project-id \
        --member="group:contractors@example.com" \
        --role="projects/my-project-id/roles/vmOperator" \
        --condition=None
      terraform {
        required_providers {
          google = {
            source = "hashicorp/google"
          }
        }
      }
      
      provider "google" {
        project = var.project_id
        region  = "asia-east1"
      }
      
      variable "project_id" {
        type        = string
        description = "專案 ID(例如 my-project-id)"
      }
      
      variable "folder_id" {
        type        = string
        description = "資料夾 ID,格式 folders/FOLDER_ID"
      }
      
      # 在資料夾授權:底下所有子資料夾、專案與資源都會繼承
      resource "google_folder_iam_member" "auditors_security_reviewer" {
        folder = var.folder_id
        role   = "roles/iam.securityReviewer"
        member = "group:auditors@example.com"
      }
      
      # 專案層級的自訂角色:只能檢視、啟動與停止 VM
      resource "google_project_iam_custom_role" "vm_operator" {
        project     = var.project_id
        role_id     = "vmOperator"
        title       = "VM Operator"
        description = "檢視、啟動與停止 Compute Engine VM"
        stage       = "GA"
        permissions = [
          "compute.instances.get",
          "compute.instances.list",
          "compute.instances.start",
          "compute.instances.stop",
        ]
      }
      
      # 自訂角色只能在建立它的專案內授予
      resource "google_project_iam_member" "contractors_vm_operator" {
        project = var.project_id
        role    = google_project_iam_custom_role.vm_operator.name
        member  = "group:contractors@example.com"
      }

      Terraform 的 _member、_binding、_policy 差在哪

      Terraform 的 Google provider 對每一種能掛允許政策的資源,都提供三種寫法,差別在「Terraform 認為自己管多大範圍」。google_project_iam_member 是非權威式(non-authoritative),只負責加上自己這一位主體,同一個角色的其他主體保留;google_project_iam_binding 對「某一個角色」是權威式,清單以外的人會被移出這個角色;google_project_iam_policy 對整份允許政策是權威式,會用你寫的內容取代專案上既有的整份政策。官方文件特別提醒:_policy 不能和 _binding、_member 混用,否則會互相覆蓋;誤用 _policy 可能把自己鎖在專案外,刪除這個資源還會移除所有沒有機構層級權限的人的存取權,所以一般只用在完全由 Terraform 管理的專案,而且要先匯入既有政策。_binding 和 _member 可以一起用,前提是兩者不要授予同一個角色。

      variable "project_id" {
        type = string
      }
      
      # _member:非權威式,只新增這一位主體,同一角色的其他主體保留
      resource "google_project_iam_member" "sre_log_viewer" {
        project = var.project_id
        role    = "roles/logging.viewer"
        member  = "group:sre@example.com"
      }
      
      # _binding:對「這個角色」是權威式,清單以外的主體會被移出這個角色
      resource "google_project_iam_binding" "monitoring_viewers" {
        project = var.project_id
        role    = "roles/monitoring.viewer"
        members = [
          "group:sre@example.com",
          "group:auditors@example.com",
        ]
      }

      自己動手時要注意

      權限:要在專案上新增角色繫結,需要能修改專案允許政策的權限(resourcemanager.projects.setIamPolicy),常見的是 Project IAM Admin(roles/resourcemanager.projectIamAdmin)或 Owner;在資料夾授權則要資料夾層級的對應權限,例如 Folder IAM Admin。建立服務帳戶需要 Create Service Accounts(roles/iam.serviceAccountCreator),建立自訂角色需要 Role Administrator(roles/iam.roleAdmin),建立拒絕政策則要在機構上有 Deny Admin(roles/iam.denyAdmin)。只有 Editor 的人照著做到「授予存取權」就會被擋,因為 Editor 不能修改允許政策,這是正常的。

      API 與生效時間:用 gcloud 或 Terraform 操作前,專案要啟用 IAM API 與 Cloud Resource Manager API(gcloud services enable iam.googleapis.com cloudresourcemanager.googleapis.com)。IAM API 是最終一致的,授權或建立服務帳戶後,可能要等一分鐘以上才會在存取檢查生效,自動化腳本要有重試。

      費用:授予角色、建立服務帳戶、自訂角色與拒絕政策本身不會建立任何計費的運算或儲存資源;但如果你接著用這些權限建立 VM、值區,就會依用量計費。用免費試用帳戶練習時,留意試用帳戶的限制(例如不能申請提高配額)。

      清理:練習完把繫結、服務帳戶與自訂角色移除;如果整個專案都只是練習用,最乾淨的做法是直接刪除專案,專案會先進入關閉狀態,30 天後才永久刪除,期間可以還原。用 Terraform 建立的,terraform destroy 會刪除它建立的服務帳戶、角色繫結與自訂角色。刪除的自訂角色在一段期間內(官方文件寫 44 天的刪除流程)不能重複使用同一個角色 ID。

      # 移除練習用的角色繫結(--all 會一併移除同一主體、同一角色的所有條件式繫結)
      gcloud projects remove-iam-policy-binding my-project-id \
        --member="group:ops-team@example.com" \
        --role="roles/compute.instanceAdmin.v1" --all
      
      # 刪除服務帳戶與自訂角色
      gcloud iam service-accounts delete order-reader@my-project-id.iam.gserviceaccount.com
      gcloud iam roles delete vmOperator --project=my-project-id
      
      # 用 Terraform 建立的資源
      terraform destroy
      
      # 整個練習專案都不要了:最乾淨
      gcloud projects delete my-project-id

      不要寫進範例的東西:本頁的專案 ID 用 my-project-id、資料夾用 FOLDER_ID、信箱用保留給範例的 example.com。真實的專案 ID、機構 ID、同事信箱不要貼進公開的儲存庫或教學文件。也不要建立或下載服務帳戶金鑰:在 Google Cloud 裡執行的程式,把服務帳戶附加到 VM、Cloud Run 等資源,由應用程式預設憑證(Application Default Credentials)自動取得短期權杖;在自己電腦上操作,用 gcloud auth login 的使用者憑證,必要時以模擬(impersonation)暫時借用服務帳戶;跑在其他雲或 CI/CD 平台上的工作負載,用 Workload Identity Federation。2024 年 5 月 3 日以後建立的機構,預設就會強制禁止建立服務帳戶金鑰。

      ☁️ 對照 AWS 與 Azure 的做法:
      AWS:用 AWS Organizations 的組織單位與帳戶分層,權限寫在附加於 IAM 使用者、群組、角色或資源上的 JSON 政策裡,政策本身就能寫 Deny,評估時明確拒絕優先;整個帳戶的權限上限則交給 SCP。程式用 IAM 角色取得暫時憑證。AWS 版互動教學:IAM 政策評估 ↗
      Azure:管理群組、訂用帳戶、資源群組、資源四層,Azure RBAC 的角色指派同樣往下繼承、權限累加;拒絕指派由 Azure 建立與管理,客戶不能直接建立。程式用受控識別。Azure 版互動教學:資源階層與 RBAC ↗

      📘 原理補完

      資源階層:每個資源剛好一個父層

      Google Cloud 的資源階層由上到下是機構、資料夾、專案,最下面是各服務的資源,例如值區、VM、BigQuery 資料集。官方文件的說法是除了最上層的資源之外,每個資源都剛好有一個父層。機構是根節點,前提是要有 Google Workspace 或 Cloud Identity 帳戶;資料夾是選用的分組層,可以巢狀,最多 10 層,一個父資料夾底下最多 300 個子資料夾;專案是「最基本的組織單位」,API 在專案上啟用、費用依專案記到帳單帳戶,使用 Google Cloud 一定要有專案(以上數字查證於 2026 年 10 月)。允許政策、拒絕政策與機構政策都會沿著這棵樹往下繼承。

      機構 qingsong.example 資料夾 fld-prod(正式) 資料夾 fld-dev(開發) 專案 qs-order-prod 專案 qs-order-dev 值區qs-order-docs VMvm-order-01 值區qs-dev-logs VMvm-dev-01 政策往下繼承 值區與 VM 也能有自己的允許政策;基本角色只能授予在專案或更上層 (名稱皆為虛構示意)
      這棵樹就是實驗室一用的資源樹。深色的機構與資料夾適合放「整個環境都要一致」的東西,例如稽核群組的唯讀角色、拒絕刪除專案的拒絕政策、資源位置限制;淺色的專案與資源適合放「某個應用或某個值區」的授權。

      有效權限怎麼算:先拒絕,再看允許的聯集

      當某個主體對某個資源呼叫 API 時,IAM 會先收集這個資源與它所有祖先上的拒絕政策。官方文件寫得很直接:IAM 一定先檢查相關的拒絕政策,再檢查允許政策。只要有一條拒絕規則命中這個主體與權限,而且主體不在例外清單,這個權限就不能用,不管他拿到幾個角色。拒絕政策可以掛在機構、資料夾或專案,每個資源最多 500 份、合計 500 條拒絕規則;規則可以設例外主體與例外權限,條件(denialCondition)只能用資源代碼(tag)判斷。不是每個權限都能被拒絕,要查官方的支援權限清單;權限寫法也和允許政策不同,是 cloudresourcemanager.googleapis.com/projects.delete 這種 v2 格式。

      通過拒絕政策之後,IAM 看允許政策:資源本身的、專案的、資料夾的、機構的全部加起來,官方稱為有效允許政策,是所有這些政策的聯集。只要有一筆繫結(條件成立時)給了需要的權限,請求就被允許;沒有任何一筆給,就預設拒絕。所以把某人在專案上的角色拿掉,如果他所屬的群組在資料夾上還有同樣的角色,他照樣能做。除此之外還有兩道選用的護欄:主體存取邊界政策(Principal Access Boundary,PAB)從「這些主體最多能碰哪些資源」畫邊界;VPC Service Controls 從 API 與網路情境畫服務邊界。它們都只會擋,不會給權限。

      檢視修改/啟停刪除 VM管理 IAM 繫結 A:Viewer授予在機構(繼承下來) 繫結 B:Editor授予在 qs-order-prod 允許政策聯集 拒絕政策 Bfld-prod,外包人員群組 最後的有效權限 ✓——— ✓✓✓— ✓✓✓— ✕ 擋 ✓✓✕—
      這是實驗室一任務 4 的結果。前兩列是兩筆繫結,第三列取聯集,只要一筆允許就算允許。第四列的拒絕政策只擋「刪除 VM」,但 IAM 先評估它,所以最後一列的刪除變成紅色。最右欄一直是灰色:Editor 和 Viewer 都不能修改允許政策。
      請求:主體+權限+資源 ① 拒絕政策(資源+所有祖先) 命中拒絕規則、不在例外主體 → 直接拒絕 拒絕 沒有命中 ② 允許政策聯集(資源+所有祖先) 有一筆繫結給了權限,且 IAM 條件成立? 允許 有 一筆都沒有 預設拒絕 另外的護欄 主體存取 邊界(PAB) VPC Service Controls
      兩個框的順序就是考點:拒絕在前、允許在後,允許的部分是聯集而不是「最近的那一層說了算」。左下的兩種護欄只會讓請求更難通過,任何一道沒過都會被拒絕;它們不會替任何人加權限。

      拒絕政策用 gcloud 建立時,先把規則寫成 JSON 檔,再指定掛載點(attachment point)。下面這份政策掛在專案上,除了平台組以外,任何人都不能刪除這個專案,就算他是 Owner 也一樣:

      {
        "displayName": "Only platform team can delete project",
        "rules": [
          {
            "denyRule": {
              "deniedPrincipals": ["principalSet://goog/public:all"],
              "exceptionPrincipals": ["principalSet://goog/group/platform-admins@example.com"],
              "deniedPermissions": ["cloudresourcemanager.googleapis.com/projects.delete"]
            }
          }
        ]
      }
      # 把上面的 JSON 存成 deny-project-delete.json 再建立(需要機構上的 Deny Admin 角色)
      gcloud iam policies create deny-project-delete \
        --attachment-point=cloudresourcemanager.googleapis.com/projects/my-project-id \
        --kind=denypolicies \
        --policy-file=deny-project-delete.json
      variable "project_id" {
        type = string
      }
      
      # 拒絕政策:除了平台組,任何人都不能刪除這個專案(即使有 Owner)
      resource "google_iam_deny_policy" "protect_project" {
        parent       = urlencode("cloudresourcemanager.googleapis.com/projects/${var.project_id}")
        name         = "deny-project-delete"
        display_name = "Only platform team can delete project"
      
        rules {
          description = "Block project deletion except platform admins"
          deny_rule {
            denied_principals    = ["principalSet://goog/public:all"]
            exception_principals = ["principalSet://goog/group/platform-admins@example.com"]
            denied_permissions   = ["cloudresourcemanager.googleapis.com/projects.delete"]
          }
        }
      }

      注意兩邊的寫法差異:gcloud 的 --attachment-point 直接寫斜線路徑,Terraform 的 parent 要用 urlencode() 編碼;主體也不是允許政策的 group: 寫法,而是 principalSet://goog/group/… 這種識別碼。

      三種角色怎麼選

      角色是權限的集合,權限的格式是「服務.資源.動作」,例如 storage.objects.get;權限不能直接授予主體,一定要包在角色裡。基本角色是很早期就有的 Owner、Editor、Viewer,權限橫跨幾乎所有服務,官方現在把它們稱為舊版基本角色(legacy basic roles),並建議正式環境除非沒有替代方案,不要授予;官方文件另列出新的基本角色 Admin、Writer、Reader(roles/admin 等),目前是 Preview。預先定義角色由各服務維護,名稱像 roles/storage.objectViewer、roles/compute.instanceAdmin.v1,服務新增功能時 Google 會更新它們,是日常授權的首選。自訂角色讓你自己挑權限,只能建在機構或專案,每個機構、每個專案各最多 300 個,而且新權限不會自動加進去,要自己維護。

      角色類型誰維護、粒度可以授予在哪IAM 條件典型用途與風險
      舊版基本角色
      Owner/Editor/Viewer
      Google 定義;橫跨幾乎所有服務,粒度最粗專案或更上層(Cloud Storage 文件寫明不能授予在單一值區)不能加條件個人沙箱、短期測試。Owner 還能修改允許政策;Viewer 透過值區預設政策的便利值,常常也能讀物件
      預先定義角色
      例:roles/storage.objectViewer
      各服務維護,隨新功能更新;粒度到單一服務的某類工作機構、資料夾、專案,或角色支援的最低層級資源(例如值區)可以日常授權首選;先找有沒有剛好的,再考慮自訂
      自訂角色
      例:projects/…/roles/vmOperator
      你自己維護;粒度到單一權限建在機構:機構內都能用;建在專案:只能在那個專案內授予。不能建在資料夾可以預先定義角色明顯過大時;權限不會自動更新,部分權限不支援自訂角色
      Editor(基本) instanceAdmin.v1(預先定義) vmOperator(自訂) ComputeStorageBigQueryPub/Sub…幾乎全部 Compute Engine 執行個體、 磁碟、映像等的管理 get、list、 start、stop 越往下越精準, 維護成本也越往你身上移
      同樣是「讓外包人員操作 VM」,三種角色給出去的範圍差很多。Editor 連值區、資料集都能改;instanceAdmin.v1 只碰 Compute Engine,但仍包含刪除;自訂的 vmOperator 只有四個權限,代價是 Compute Engine 新增功能時,你要自己決定要不要加權限。

      服務帳戶:程式的身分,重點是不要用金鑰

      服務帳戶是給工作負載用的身分,分三種:你自己建立的使用者管理服務帳戶;啟用 Compute Engine 等服務時自動建立的預設服務帳戶,歷史上常帶著 Editor 這類過大的權限;以及 Google 建立與管理、讓 Google 服務代你存取資源的服務代理(service agent)。服務帳戶同時是主體與資源:在專案上把角色授予它,決定它能做什麼;在它身上把 Service Account User(roles/iam.serviceAccountUser)授予某人,決定誰能把它附加到 VM 或 Cloud Run 上,等於誰能用它的身分做事,所以這個角色要謹慎發。

      服務帳戶取得憑證有好幾條路,安全性差很多。服務帳戶金鑰是可下載的長期憑證,外洩了很難察覺,也要自己輪替;在 Google Cloud 裡執行的程式,應該把服務帳戶附加到資源上,透過應用程式預設憑證自動拿到短期權杖;人需要暫時以服務帳戶身分操作,用模擬(impersonation);跑在 AWS、Azure、地端或 GitHub Actions 這類 CI/CD 平台的工作負載,用 Workload Identity Federation,拿自己環境發的憑證向 Security Token Service 換短期權杖。機構可以用機構政策禁止建立與上傳服務帳戶金鑰,舊版限制條件名稱是 iam.disableServiceAccountKeyCreation,新的 managed 版本是 iam.managed.disableServiceAccountKeyCreation。

      ✕ 下載服務帳戶金鑰 JSON 檔放在程式或設定裡 長期有效,要自己輪替 推上儲存庫、被複製都很難察覺 機構政策可以直接禁止建立 ✓ 附加到資源 VM、Cloud Run、GKE 上的程式 應用程式預設憑證(ADC) 自動取得、自動更新短期權杖 ✓ 模擬(impersonation) 人用自己的帳號登入 暫時借用服務帳戶身分 需要 Token Creator 一類的角色 ✓ Workload Identity Federation 其他雲、地端、GitHub Actions 用外部憑證向 STS 換短期權杖 屬性條件限定哪個儲存庫、分支
      左上是要淘汰的做法,其他三格是官方建議的替代方案。判斷的關鍵是「程式跑在哪裡」:在 Google Cloud 裡面就附加服務帳戶;在外面就用 Workload Identity Federation;是人在操作就用自己的帳號,必要時模擬。

      機構政策:管設定,不管人

      機構政策服務讓你在機構、資料夾或專案上設定限制條件(constraint),每份政策強制一個限制條件,預設往下繼承,下層可依規則覆寫;支援 dry-run,先記錄違規再正式強制。它和 IAM 是兩道獨立的關卡:IAM 說你有權限建立 VM,機構政策照樣可以說「這個 Region 不准」。常見的限制條件有資源位置(gcp.resourceLocations)、禁止建立服務帳戶金鑰、禁止 VM 有外部 IP。用 gcloud 設定時,先寫一份 YAML,再用 gcloud org-policies set-policy 套用:

      # key-policy.yaml:在整個機構禁止建立服務帳戶金鑰(布林型限制條件)
      name: organizations/ORGANIZATION_ID/policies/iam.disableServiceAccountKeyCreation
      spec:
        rules:
        - enforce: true
      # 需要機構上的 Organization Policy Administrator 角色
      gcloud org-policies set-policy key-policy.yaml

      判斷步驟:先選做法,再選層級

      1. 先問這是「誰能做」還是「能不能這樣設定」。後者(資源位置、外部 IP、服務帳戶金鑰)用機構政策,設在需要的機構、資料夾或專案。
      2. 是「誰能做」,再問要不要強制擋下某些操作、而且不管對方被授予什麼角色。是的話用拒絕政策,並設好例外主體。
      3. 要授權的是程式還是人。程式在 Google Cloud 裡:建立專用服務帳戶、附加到資源;程式在外面:Workload Identity Federation;人:授權給 Google 群組而不是個人。
      4. 挑角色:先找預先定義角色;明顯過大才建自訂角色;基本角色只用在沙箱或測試專案。
      5. 挑層級:需求所在的最小層級。一個值區就授予在值區,一個應用就授予在它的專案;整個環境(包含未來新增的專案)都要一致,才放在資料夾或機構。
      6. 需要臨時或限時的權限,用 IAM 條件設到期時間(基本角色不行);事後用 IAM Recommender 收斂長期沒用到的權限。
      要限制的是「設定值」嗎? 機構政策 要不管角色、強制擋下嗎? 拒絕政策 身分是程式嗎? 程式跑在 Google Cloud 外面嗎? Workload IdentityFederation 服務帳戶附加到資源 有剛好的預先定義角色嗎? 自訂角色 預先定義角色 是否 是否 是否(人) 是否 否是 最後一步:層級挑最小的
      從上往下一題一題問。前兩題是「不是授權問題」的出口,很多干擾選項就是在這裡設計的:把機構政策的需求寫得像授權問題,或把拒絕政策的需求寫成「把某人的角色拿掉」。走到下面幾題才是在挑角色,最後別忘了右下角:同一個角色,層級小一層,出事時的影響也小一層。
      專案的允許政策(列=角色,格=主體) roles/logging.viewer roles/monitoring.viewer roles/compute.instanceAdmin.v1 sre(其他人)(其他人) sreauditors(被移出) ops-team(其他人)(其他人) _member:只管自己這一格 _binding:管整列 _policy:管整張表 框越大,別人在控制台手動加的授權越容易在下次 apply 時被覆蓋掉
      中間那列寫著「被移出」:用 _binding 管 monitoring.viewer 時,清單外的人下次 apply 就會被拿掉。紅色外框的 _policy 更進一步,整份政策都以 Terraform 為準,所以官方提醒它不能和另外兩種混用,也容易把自己鎖在外面。多數團隊的預設選擇是 _member。

      容易考錯的地方

      下層收不回上層的權限:題目描述「在專案上把某人的 Editor 拿掉了,他還能改」,原因幾乎都是資料夾或機構上還有繫結,或他所屬的群組有。正解是去上層移除,或用拒絕政策擋,不是在專案上再加什麼。

      拒絕政策與機構政策常被對調:「不管是誰都不能建立服務帳戶金鑰」「資源只能建在台灣」是限制設定值,用機構政策;「除了平台組,誰都不能刪除專案」是限制某些主體使用某個權限,用拒絕政策。

      基本角色的兩個陷阱:基本角色不能加 IAM 條件,所以「讓外包人員的 Editor 月底自動失效」做不到,要換成預先定義角色再加條件;Viewer 看起來只能看,但透過值區預設政策的便利值,常常也讀得到物件。

      自訂角色的層級:選項出現「在資料夾建立自訂角色」一定是錯的;建在專案的自訂角色也不能拿到別的專案或資料夾授予。

      服務帳戶的情境題:程式在 VM 或 Cloud Run 上,答「附加服務帳戶」;在 GitHub Actions、AWS 或地端,答「Workload Identity Federation」;選項若出現「建立金鑰並存到 Secret Manager」,通常是比較差的做法。另外,授予 Service Account User 等於讓對方能以服務帳戶身分做事,題目問「誰能把這個服務帳戶附加到 VM」時就是在問它。

      Workload 和 Workforce 名字很像:Workload Identity Federation 給程式;Workforce Identity Federation 給人,讓員工用外部身分提供者直接登入 Google Cloud。

      這些內容在 ACE 的 Section 1(資源階層與機構政策、IAM 角色)與 Section 4(IAM 政策、角色繼承、自訂角色、服務帳戶、模擬、短期憑證、Workload Identity Federation)都有點名;PCSE 的 Configuring access 領域考服務帳戶金鑰的限制、IAM 條件、拒絕政策與預建、自訂機構政策;PCDOE 的 Bootstrapping 領域考資源階層、IAM 與機構政策、服務帳戶;CDL 則在成本與營運領域考資源階層的觀念。PCA 的 Designing for security and compliance 領域也點名 IAM、資源階層與職責分離,從架構設計的角度問同樣的取捨。

      ✅ 自我檢測

      以下 6 題都是原創題,選完會立即顯示對錯與解析,全部作答後會出現總分。目前得分:0 / 6