理解 Google Cloud 中的服務帳戶 (Service Accounts)
在 Google Cloud 的世界裡,並非所有的使用者都是人類。應用程式、虛擬機 (VM) 和自動化指令碼也需要身分來存取資源,這就是 服務帳戶 (Service Accounts) 的用武之地。對於 Associate Cloud Engineer (ACE) 來說,理解服務帳戶的特殊性、如何安全地管理金鑰以及如何執行「身分切換」(Impersonation) 是考試中關於安全性最深的部分。
服務帳戶既是一種 身分 (Identity),同時也是一種 資源 (Resource)。這意味著它可以擁有權限,也可以被其他人管理。
白話文解釋
1. 公司用公務車 (瑞士刀類比)
- 服務帳戶: 就像公司的一輛公務車。這輛車有自己的通行證(權限),可以用來送貨(存取 Storage)。
- 使用者 (User): 就像司機。司機自己可能沒有進入倉庫的權限,但只要他開著這輛公務車(使用服務帳戶),他就能進去。
- 身分切換 (Impersonation): 司機拿到了公務車的鑰匙,合法地代表公司去開車。
2. 智慧家庭的掃地機器人 (工地類比)
- 服務帳戶: 掃地機器人。它有權限進入家裡的各個房間掃地(執行任務)。
- 金鑰 (Keys): 機器人的啟動密碼。如果密碼流出去了,鄰居也可以控制你的機器人。
- 範圍 (Scopes): 機器人的活動範圍限制(例如:只准在客廳掃,不准進臥室)。
3. 圖書館的自動還書機 (圖書館類比)
- 服務帳戶: 還書機。它不需要讀者證,但它有權限修改圖書館的資料庫(標記書籍已歸還)。
- 由 Google 管理的金鑰 (Google-managed Keys): 圖書館員負責維護機器人的內部系統。
- 由使用者管理的金鑰 (User-managed Keys): 你自己帶了一台機器人來,並手動輸入帳號密碼。
建立與管理服務帳戶
服務帳戶的電子郵件格式通常為:[NAME]@[PROJECT_ID].iam.gserviceaccount.com。
服務帳戶類型
- 使用者管理 (User-managed): 你手動建立的帳戶。
- 預設 (Default): 當你啟用某些服務(如 Compute Engine)時,Google 自動建立的帳戶(通常權限較大,建議謹慎使用)。
- Google 管理 (Google-managed): Google 內部服務使用的帳戶,你無法直接管理。
預設的 Compute Engine 服務帳戶通常被授予 '編輯者' (Editor) 角色。基於「最小權限原則」,強烈建議為不同的應用程式建立自定義的服務帳戶,並只授予必要的精確角色。 Source ↗
指派服務帳戶權限
賦予服務帳戶權限的方式與普通使用者完全相同:在專案或資源層級將角色綁定到服務帳戶的電子郵件地址。
雙重性質
- 作為身分 (As an Identity): 服務帳戶被授予角色(例如
roles/storage.objectViewer)。 - 作為資源 (As a Resource): 使用者被授予對該服務帳戶的角色(例如
roles/iam.serviceAccountUser),讓使用者可以「使用」這個帳戶。
服務帳戶身分切換 (Impersonation) 最佳實踐
身分切換 (Impersonation) 讓一個使用者能在不下載金鑰檔案的情況下,暫時獲得服務帳戶的權限。這是管理跨服務存取最安全的方法。 Source ↗
為什麼要切換身分?
- 不會外洩金鑰: 不需要處理危險的 JSON 金鑰檔案。
- 短效性: 權限是臨時的(透過短效權杖/Token)。
- 可稽核性: 日誌會記錄是「哪個使用者」切換到了「哪個服務帳戶」。
安全管理服務帳戶金鑰
金鑰 (Keys) 是服務帳戶的靈魂,也是最大的安全隱患。
使用者管理金鑰 (User-managed Keys)
考試陷阱:將服務帳戶金鑰下載為 JSON 檔案並存儲在代碼庫中是非常危險的行為。如果你必須使用金鑰,請使用 Secret Manager,並定期進行金鑰輪換 (Key Rotation)。 Source ↗
Google 管理金鑰 (Google-managed Keys)
Google 自動處理金鑰的輪換與存儲。當你在 Google Cloud 內部(如 VM, GKE, App Engine)執行程式碼時,應始終優先使用這種方式。
服務帳戶範圍 (Scopes) vs IAM 角色
這是一個歷史遺留問題,但考試常考。
- IAM 角色: 現代的權限控制方式(誰能做什麼)。
- 範圍 (Scopes):舊式的權限限制方式,僅適用於 Compute Engine 實例。
現在的最佳實踐是將實例設定為 'Allow full access to all Cloud APIs' (允許存取所有雲端 API),然後完全依賴 IAM 角色來控制權限。 Source ↗
工作負載身分 (Workload Identity, GKE 專用)
在 GKE 中,Workload Identity 是將「Kubernetes 服務帳戶」與「Google Cloud 服務帳戶」綁定的最安全方式。它消除了在 Pod 中管理金鑰檔案的需求。
ACE 考試遇到「工作負載如何驗證身分而不下載 JSON 金鑰」的情境時,標準答案的優先順序為:先用附掛在 GCE/GKE/Cloud Run 上的服務帳戶,其次 GKE Pod 採用 Workload Identity,最後本機開發或 CI/CD 才透過 roles/iam.serviceAccountTokenCreator 進行身分切換取得短效憑證。選擇「建立並下載使用者管理金鑰」幾乎一定是錯誤答案。
Source ↗
透過 gcloud CLI 管理服務帳戶
# 建立服務帳戶
gcloud iam service-accounts create my-app-sa \
--display-name="My App Service Account"
# 授予權限
gcloud projects add-iam-policy-binding my-project \
--member="serviceAccount:[email protected]" \
--role="roles/storage.objectAdmin"
# 允許使用者使用此服務帳戶
gcloud iam service-accounts add-iam-policy-binding \
[email protected] \
--member="user:[email protected]" \
--role="roles/iam.serviceAccountUser"
使用 gcloud iam service-accounts create 在專案中初始化新的非人類身分。
Source ↗
服務帳戶安全最佳實踐
- 避免使用預設服務帳戶 (Default Service Accounts):建立專用帳戶。
- 禁止下載金鑰:優先使用身分切換 (Impersonation) 或 Workload Identity。
- 定期審計:使用
gcloud iam service-accounts list檢查不使用的帳戶。 - 精確角色:不要給予
編輯者(Editor),只給予如storage.objectViewer這樣的精確角色。
ACE 考試的常見場景
- 情境:你開發的一個程式需要從本地電腦存取 Google Cloud,但你不想在電腦上存儲 JSON 金鑰。
- 解決方案:使用
gcloud auth application-default login使用你的人類帳號登入,或設定服務帳戶身分切換。
- 解決方案:使用
- 情境:你需要在 VM 上執行一個指令碼,這個指令碼需要讀取 Cloud Storage。
- 解決方案:建立一個具有
roles/storage.objectViewer角色的服務帳戶,並在建立 VM 時將其指派給 VM。
- 解決方案:建立一個具有
常見問題 (FAQ)
Q1: 服務帳戶有密碼嗎? 答:沒有。它使用公開金鑰加密技術(金鑰對)來進行身分驗證。
Q2: 我可以恢復已刪除的服務帳戶嗎? 答:在 30 天內可以嘗試恢復,但超過時間後將永久消失,且無法建立一個同名帳戶來恢復舊權限(因為每個帳戶有唯一的唯一 ID/Unique ID)。
Q3: 服務帳戶可以跨專案使用嗎? 答:可以。你可以在專案 A 中建立服務帳戶,並在專案 B 中授予它權限。
Q4: 什麼是 iam.serviceAccountUser 角色?
答:這是「使用」服務帳戶的權限。沒有這個角色,即便你是專案管理員,也不能將服務帳戶指派給 VM。
Q5: 服務帳戶的權限會繼承嗎? 答:是的。如果服務帳戶在組織層級被授予了角色,它在所有子專案中都擁有該角色。
ACE 總結清單
- 理解服務帳戶既是「身分」也是「資源」。
- 掌握身分切換 (Impersonation) 的優點。
- 明白範圍 (Scope) 與 IAM 角色之間的關係。
- 知道如何處理遺失或外洩的金鑰(立刻停用帳戶)。
- 熟悉
gcloud iam service-accounts指令群。