Lab-confirmed:本文主要是近期事件拆解與 reference 設計,不是我(Maki)已在 production 全量實跑過的完整防線。Code snippet 為 reference 設計,非實際在跑的版本。
你看到的是 managed service,攻擊者看到的是一個預先綁好的身份
很多 builder 對 managed AI service 的直覺是安全外包。
平台幫你 patch。
平台幫你 deploy。
平台幫你接 IAM。
聽起來都合理。
但平台幫你管的方向,常常是 functionality,不是 minimum privilege。
所以最危險的地方,不一定是你手動加的權限。
而是平台在你背後替你綁上的那個 service identity。
UI 不一定會把它講清楚。
文件也不一定一開始就寫得夠直白。
等你真的去看 metadata、IAM policy、Artifact Registry access path。
你才會發現 agent 能走的,比你以為的遠很多。
Managed 在這裡不是 least-privilege 的同義詞。
它只是把過寬權限包成比較順手的預設值。
Service-Agent Overprivilege:你不知道的 effective reach 才是攻擊面
Case:
主:2026-03-31,Palo Alto Networks Unit 42 發布 Double Agents: Exposing Security Blind Spots in GCP Vertex AI。研究員在 Vertex AI Agent Engine 與 ADK 部署的 agent 上,發現與 agent 綁定的 Google 管理 P4SA service agent 帶有過寬的預設權限。靠這組預設權限,他們能提取 service-<PROJECT-ID>@gcp-sa-aiplatform-re.iam.gserviceaccount.com 的憑證,並以該身份行動。
第一段:Unit 42 指出,從 agent 執行環境拿到的資訊不只包含 project 與 identity,還包含機器的 OAuth scopes。研究員後續專章說明,這些 scope 預設過寬,而且不可編輯;理論上可把 blast radius 從 GCP 資源延伸到 Google Workspace API,如 Gmail、Calendar 與 Drive。雖然還需要對應 IAM permission 才能真正存取,但 scope 本身已經偏離 least privilege。
第二段:研究員使用被提取的 service-agent 憑證,從 agent execution context pivot 到 consumer project,取得對該專案 Google Cloud Storage bucket 的廣泛讀取能力。之後又進一步碰到 Google 管理的 producer project,下載 restricted Artifact Registry 內的 reasoning-engine image,並接觸到 Google 內部 source code 與平台 artifact。
後續:SecurityWeek 2026-04-01 報導 Google 已修訂官方文件,並明確建議使用 BYOSA,也就是 Bring Your Own Service Account。Google 沒有發 CVE,而是把它視為 managed identity 設計與文件透明度問題。Google 也告訴 SecurityWeek,平台已有不可覆寫控制,避免 service agent 修改 production images。
核心問題:builder 平常看到的是 declared architecture。
攻擊者真正利用的是 effective permissions。
這兩者不一樣。
尤其在 managed service。
你不能只問「我有沒有手動把 agent 接到某個 bucket」。
你還要問「平台預設替它帶了哪些 identity、哪些 scope、哪些橫向可達性」。
Rule:上線前先盤 effective reach,再盤 declared intent。
| 失敗模式 | Mitigation | Builder 行動 |
|---|---|---|
| Managed agent 繼承過寬 OAuth scope | 盤點 effective permissions 與 default scopes,不只看 UI 宣告 | 部署前先做 identity inventory |
| Service identity 跨 project lateral movement | 限制 cross-project resource access,補 VPC-SC / private endpoint 隔離 | 不讓 agent 預設碰到別的 project |
| 平台沒給 scope 編輯介面 | 用 BYOSA 或 wrapper layer,把 platform agent 放在自控身份後面 | 不直接 expose platform identity |
| 不知道哪些 scope 是 effective | 每次 deployment 都做 scope review,搭配短期憑證與稽核 | 把 deployment 當成 IAM 變更事件 |
Reference 實作(示意非 production code,依你環境調整):
import json
import subprocess
def _gcloud_json(*args):
raw = subprocess.check_output(["gcloud", *args, "--format=json"], text=True)
return json.loads(raw)
def audit_service_agent_scopes(project_id: str, visible_projects: list[str]) -> list[dict]:
service_accounts = _gcloud_json("iam", "service-accounts", "list", f"--project={project_id}")
report = []
for sa in service_accounts:
email = sa["email"]
effective_projects = []
for target in visible_projects:
policy = _gcloud_json("projects", "get-iam-policy", target)
if f"serviceAccount:{email}" in json.dumps(policy):
effective_projects.append(target)
report.append({
"service_account": email,
"declared_home": project_id,
"effective_projects": effective_projects,
"cross_project_access": [p for p in effective_projects if p != project_id],
"needs_review": any(p != project_id for p in effective_projects),
})
return report
這段 code 故意保守。
它先盤 effective reach。
而不是假裝只靠一個 UI 畫面就看得完 managed service 的真實權限。
如果你連跨 project 存取都沒有 inventory。
least privilege 其實還沒開始。
對應 OWASP:這篇先看哪幾條
LLM06:2025 Excessive Agency:平台替 agent 準備過大的可達範圍,等於在底層默默放大 agency。ASI03 Identity and Privilege Abuse:整起研究的核心就是 service-agent identity 被提取並濫用。ASI02 Tool Misuse:builder 原本只想部署 agent,結果平台工具鏈與預設身份被拿來做 cloud pivot。
想動手做? 這篇文的概念可以接著看: 權限邊界
如果你想把 per-agent RBAC、approval gate、token scope 設計成完整流程,直接接: 權限邊界 101 →
再往暴露面與平台預設值延伸,接著看: 攻擊面邊界