<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cloud-Iam on Tarragon</title><link>https://tarrragon.github.io/blog/tags/cloud-iam/</link><description>Recent content in Cloud-Iam on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 18 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/cloud-iam/index.xml" rel="self" type="application/rss+xml"/><item><title>AWS IAM</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/</guid><description>&lt;p>AWS IAM 是 AWS 的 cloud resource permission engine — 它回答的問題是「這個身份能對哪一個 AWS resource 做哪一個 API call」。它不是 workforce IdP、也不負責「這個人類是誰」的判定。所有 AWS API 流量（無論來自 console 操作、CI pipeline、Lambda、EC2、跨帳號 partner）最終都要經過 IAM 的 policy 評估、IAM 是 AWS 安全模型的根。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>AWS IAM 是 &lt;em>cloud resource permission engine&lt;/em>、人類 workforce 的 SSO 與 lifecycle 應該走 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center&lt;/a> 或外部 IdP（&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak&lt;/a>）。Identity Center 把人類映射到 &lt;em>Permission Set&lt;/em>、Permission Set 在每個目標帳號裡實際上是 AWS-Reserved IAM Role — 也就是說：人類登入走 Identity Center、實際的 API 授權判斷一定回到 IAM。兩層責任分清楚、policy 才不會錯放在「誰是誰」的地方。&lt;/p>
&lt;p>AWS IAM 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &amp;#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&amp;#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC&lt;/a> 在 policy model 上設計差異很大。AWS 的表達力最強 — identity-based policy、resource-based policy、Service Control Policy（SCP）、Permission Boundary、Session Policy 是五個獨立的層、最終結果由 &lt;em>Explicit Deny &amp;gt; Org SCP &amp;gt; Resource-based &amp;gt; Identity-based &amp;gt; Permission Boundary &amp;gt; Session Policy&lt;/em> 的評估順序決定。表達力換來的代價是 &lt;em>最容易設定錯&lt;/em>：S3 bucket policy 設錯 = public、KMS key policy 漏一個 condition = 跨帳號可以解密、Trust Policy 沒設 ExternalID = confused deputy 攻擊面。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>哪些 IAM first-class concept（User / Group / Role / Policy / STS）對應到自己的場景、哪些要避免（例如：給人類發 IAM User access key）&lt;/li>
&lt;li>跨帳號信任、CI / 第三方 SaaS 連進 AWS、service-to-service 認證該走 Role assumption / OIDC trust 還是 Roles Anywhere&lt;/li>
&lt;li>SCP、Permission Boundary、resource-based policy 三層上限的疊加方式、何時用哪一層&lt;/li>
&lt;li>CloudTrail + Access Analyzer 的稽核 baseline、出事時的最短取證路徑&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷一個 AWS 帳號的 IAM 配置是否健康、最少看四件事：&lt;/p></description><content:encoded><![CDATA[<p>AWS IAM 是 AWS 的 cloud resource permission engine — 它回答的問題是「這個身份能對哪一個 AWS resource 做哪一個 API call」。它不是 workforce IdP、也不負責「這個人類是誰」的判定。所有 AWS API 流量（無論來自 console 操作、CI pipeline、Lambda、EC2、跨帳號 partner）最終都要經過 IAM 的 policy 評估、IAM 是 AWS 安全模型的根。</p>
<h2 id="服務定位">服務定位</h2>
<p>AWS IAM 是 <em>cloud resource permission engine</em>、人類 workforce 的 SSO 與 lifecycle 應該走 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a> 或外部 IdP（<a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / <a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak</a>）。Identity Center 把人類映射到 <em>Permission Set</em>、Permission Set 在每個目標帳號裡實際上是 AWS-Reserved IAM Role — 也就是說：人類登入走 Identity Center、實際的 API 授權判斷一定回到 IAM。兩層責任分清楚、policy 才不會錯放在「誰是誰」的地方。</p>
<p>AWS IAM 跟 <a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a> 在 policy model 上設計差異很大。AWS 的表達力最強 — identity-based policy、resource-based policy、Service Control Policy（SCP）、Permission Boundary、Session Policy 是五個獨立的層、最終結果由 <em>Explicit Deny &gt; Org SCP &gt; Resource-based &gt; Identity-based &gt; Permission Boundary &gt; Session Policy</em> 的評估順序決定。表達力換來的代價是 <em>最容易設定錯</em>：S3 bucket policy 設錯 = public、KMS key policy 漏一個 condition = 跨帳號可以解密、Trust Policy 沒設 ExternalID = confused deputy 攻擊面。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>哪些 IAM first-class concept（User / Group / Role / Policy / STS）對應到自己的場景、哪些要避免（例如：給人類發 IAM User access key）</li>
<li>跨帳號信任、CI / 第三方 SaaS 連進 AWS、service-to-service 認證該走 Role assumption / OIDC trust 還是 Roles Anywhere</li>
<li>SCP、Permission Boundary、resource-based policy 三層上限的疊加方式、何時用哪一層</li>
<li>CloudTrail + Access Analyzer 的稽核 baseline、出事時的最短取證路徑</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一個 AWS 帳號的 IAM 配置是否健康、最少看四件事：</p>
<ul>
<li><strong>誰能 assume 哪個 Role</strong>：所有 Role 的 Trust Policy（誰能呼叫 <code>sts:AssumeRole</code>）、有沒有跨帳號 trust、跨帳號 trust 是否帶 ExternalID、有沒有 <code>*</code> 在 Principal 裡</li>
<li><strong>Resource-based policy 暴露面</strong>：S3 bucket policy、KMS key policy、Lambda function policy、SNS / SQS policy 是否有 <code>Principal: *</code> 或來自非預期帳號；用 <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html">IAM Access Analyzer</a> 找 <em>unintended external access</em></li>
<li><strong>Permission Boundary 與 SCP 是否生效</strong>：開發者建的 Role 是否 attach Permission Boundary（防止 admin 自己給自己升權）、Organization 是否 attach SCP 做整個 OU 的上限</li>
<li><strong>CloudTrail 是否完整、是否進 SIEM</strong>：management event 跟 data event 都開、跨 region、跨帳號、保留期符合稽核要求、特定事件（<code>AssumeRole</code> 失敗、root login、<code>CreateAccessKey</code>）接 <a href="/blog/backend/knowledge-cards/alert-runbook/" data-link-title="Alert Runbook" data-link-desc="說明告警如何連到可執行的排障與恢復流程">alert runbook</a></li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 與 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Role 設計（cross-account / service / OIDC trust）</strong>：所有 <em>持續性</em> 的身份都應該是 Role、不是 IAM User。Service Role（給 EC2 / Lambda / ECS task）是 AWS 內部 service-to-service；Cross-account Role 給 partner 帳號或自家其他帳號用 <code>sts:AssumeRole</code> 進來；OIDC trust 是現代 CI 必備路徑（GitHub Actions / GitLab / 自管 K8s 用短期 OIDC token 換 AWS STS 短期憑證、不在 secret store 存 long-lived access key）。</p>
<p><strong>Policy 種類分工</strong>：identity-based policy attach 在 User / Group / Role 上、回答「這個身份能做什麼」。Resource-based policy attach 在 resource 上（S3 bucket、KMS key、SNS topic、Lambda function）、回答「誰能對這個 resource 做什麼」— 同帳號內 identity-based 跟 resource-based 任一個 allow 就通過、跨帳號 <em>兩邊都要 allow</em>。SCP 是 Organization 層級的上限、不是 grant — SCP allow 不會給任何權限、SCP deny 會擋掉整個 OU 的所有 identity。Permission Boundary 是 <em>user 角度的上限</em>、給 admin 用來限制「我把 admin 權限委派給 developer 後、developer 自己建的 role 不能超過這條線」。</p>
<p><strong>STS 與臨時憑證</strong>：所有 cross-account、service-to-service、人類 console federation 都應該走 STS — <code>sts:AssumeRole</code>（跨帳號 / 跨 role）、<code>sts:AssumeRoleWithSAML</code>（SAML IdP）、<code>sts:AssumeRoleWithWebIdentity</code>（OIDC）、<code>sts:GetFederationToken</code>（外部 broker）。Session 預設 1 小時、最長可設 12 小時（依 Role 設定）。Debug 起手式：<code>aws sts get-caller-identity</code> 確認當前 caller 是誰、是 User、Role 還是 federated session。</p>
<p><strong>Access Key 治理</strong>：IAM User 的 long-lived access key 是 <em>最後手段</em>、用於 break-glass 或無法跑 IMDS / Roles Anywhere 的 legacy。所有 access key 走 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a>、定期 rotation、IAM Access Analyzer 的 unused access finding 找閒置 key。</p>
<p><strong>CloudTrail / Access Analyzer baseline</strong>：CloudTrail organization trail 開到所有帳號、management event 必開、data event（S3 object level、Lambda invoke）依資料敏感度開。Access Analyzer 至少跑 <em>external access</em>（找 resource-based policy 把資源暴露給外部帳號）跟 <em>unused access</em>（找閒置 Role、user、permission）。</p>
<p><strong>Trust Policy / ExternalID</strong>：第三方 SaaS（監控、CSPM、備份服務）要進你的 AWS 帳號時、其 Trust Policy 必須要求 ExternalID — 否則攻擊者只要知道 Role ARN 就能假冒第三方 SaaS 的呼叫端、走 confused deputy 攻擊面（<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html">AWS confused deputy 官方說明</a>）。自家跨帳號 trust 不一定要 ExternalID、第三方一定要。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS IAM</th>
          <th>Google Cloud IAM</th>
          <th>Azure RBAC</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>基本單位</td>
          <td>Policy（attach 到 identity 或 resource）</td>
          <td>Role Binding（principal + role + resource）</td>
          <td>Role Assignment（scope + principal + role）</td>
      </tr>
      <tr>
          <td>隔離邊界</td>
          <td>Account（root）+ Organization SCP</td>
          <td>Project / Folder / Org（階層 inherit）</td>
          <td>Subscription / Management Group（階層 inherit）</td>
      </tr>
      <tr>
          <td>Policy 表達力</td>
          <td>高 — identity / resource / SCP / boundary / session 五層</td>
          <td>中 — Conditional IAM + Organization Policy</td>
          <td>中 — RBAC + Azure Policy 兩層</td>
      </tr>
      <tr>
          <td>Resource-based</td>
          <td>多 service 支援（S3 / KMS / SNS / SQS / Lambda&hellip;）</td>
          <td>較少（GCS / Pub/Sub / KMS 等）</td>
          <td>較少、多走 RBAC 統一</td>
      </tr>
      <tr>
          <td>設定錯誤代價</td>
          <td>高 — bucket / key policy 設錯就 public</td>
          <td>中 — 較統一但精細度也較低</td>
          <td>中 — 階層 inherit 容易誤放</td>
      </tr>
  </tbody>
</table>
<p>AWS IAM 是 <em>表達力最強、最容易設定錯</em> 的雲端 IAM。Google Cloud IAM 設計較統一、policy model 易讀但精細度有限。Azure RBAC 走 inheritance + scope、靠 Management Group 結構治理。三家都不能直接互換、跨雲環境需要在每家自己的 IAM 模型裡建等價的 least-privilege baseline。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Service Control Policy（SCP）</strong>：Organization 層級的上限、用來宣告「整個 OU 永遠不能做什麼」 — 例如禁止 root user 操作、禁止關閉 CloudTrail、禁止在非允許 region 建 resource。SCP 是 <em>deny-list 防護網</em>、不是日常授權；日常授權交給 identity-based policy。SCP 過嚴會擋住合法操作、過鬆等於沒設、設計時要對齊 organization 的安全政策骨幹。</p>
<p><strong>Permission Boundary</strong>：用在 <em>委派 admin</em> 場景 — 公司想讓 platform team 自己建 IAM Role 給應用、但又不想讓他們建出 admin role。Admin 給 platform team 一個 Permission Boundary policy、platform team 建的所有 Role 都會被這個 boundary 限制 <em>上限</em>、就算 attach 了 <code>AdministratorAccess</code> 也只能在 boundary 範圍內生效。</p>
<p><strong>ABAC（attribute-based / tag-based access control）</strong>：大規模 multi-account 環境、每個 service 一個 Role 會 Role 爆炸。ABAC 用 <em>tag</em>（principal tag、resource tag、request tag）做 policy condition — 例如「Role 上有 <code>team=payments</code> tag 的人能操作 <code>team=payments</code> tag 的 resource」。設計成立的前提是 tag 來源可信、不能讓使用者自己改 principal tag。</p>
<p><strong>IAM Roles Anywhere</strong>：給 AWS 之外的 workload（地端 K8s、其他雲、邊緣設備）用 X.509 憑證換 STS 短期憑證。前提是有一個可信的 PKI（自管 CA 或公開 CA）跟 trust anchor。比起把 IAM User access key 放在地端 secret store、Roles Anywhere 是更安全的設計。</p>
<p><strong>OIDC trust（GitHub Actions / GitLab CI / 第三方 CI）</strong>：CI / CD 連 AWS 的標準做法。在 AWS 建一個 OIDC identity provider 指向 CI 的 OIDC issuer、Role 的 Trust Policy condition 限制 <code>repo:org/repo:ref:refs/heads/main</code>、CI workflow 直接 <code>aws sts assume-role-with-web-identity</code>。完全不需要在 CI secret store 存 long-lived AWS access key、token TTL 隨 job 結束自動失效。</p>
<p><strong>Resource-based policy 跨帳號設計</strong>：S3 bucket policy、KMS key policy、SNS / SQS / Lambda policy 都支援跨帳號授權。設計時兩件事必查：Principal 是否包含預期的帳號 / Role ARN、condition 是否限制來源（<code>aws:SourceAccount</code>、<code>aws:SourceArn</code>、<code>aws:PrincipalOrgID</code>）。漏了 condition、就可能讓任何拿到「假裝是某個 service」身份的人都能呼叫 — Capital One 2019 事件本質就是 SSRF 取得 EC2 IMDS 的 Role credential、再用該 Role 的權限去 S3 列舉跟讀取資料、揭示 <em>resource-based policy + identity-based policy 沒有最小化、就會在事故時最大化</em>。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong><code>AccessDenied</code> 但 policy 看起來 allow</strong>：先用 <a href="https://policysim.aws.amazon.com/">IAM Policy Simulator</a> 或 <code>aws iam simulate-principal-policy</code> 重算、確認是 SCP 擋、Permission Boundary 擋、resource-based policy 沒 allow、還是 condition key 不匹配。Explicit Deny 永遠贏。</li>
<li><strong>跨帳號 <code>sts:AssumeRole</code> 失敗</strong>：兩邊都要設 — caller 帳號的 identity-based policy 要 allow <code>sts:AssumeRole</code> 到目標 Role ARN、目標 Role 的 Trust Policy 要 allow caller 的 Principal。漏其一就失敗。</li>
<li><strong>S3 bucket 不小心 public</strong>：用 Access Analyzer 的 external access finding 找、用 <em>Block Public Access</em> 帳號級別開關擋掉（即使 bucket policy 寫了 public、Block Public Access 也會擋）。常見根因：bucket policy 寫 <code>Principal: *</code> 沒加 condition、或 ACL 殘留歷史設定。</li>
<li><strong>Role / access key 殘留</strong>：用 Access Analyzer 的 unused access finding、或 IAM credential report 找超過 90 天沒用的 user / role、配 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a> 的分域分批 rotation 流程清理</li>
<li><strong>第三方 SaaS Role 缺 ExternalID</strong>：稽核第三方 vendor 的 onboarding 文件、若沒要求 ExternalID 是 vendor 自己安全模型有破口、自己這邊也要拒絕這種 onboarding</li>
<li><strong>CloudTrail 落地不全</strong>：Organization trail 沒覆蓋新建帳號、data event 沒開、log 沒進 SIEM、保留期不足 — 這四件事都會讓事故發生時拿不到證據</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>人類員工 SSO 進 AWS</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a></td>
      </tr>
      <tr>
          <td>多雲 / SaaS app 統一 SSO</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / <a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak</a></td>
      </tr>
      <tr>
          <td>Customer / B2C identity</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0</a></td>
      </tr>
      <tr>
          <td>Google Cloud resource 權限</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a></td>
      </tr>
      <tr>
          <td>Azure resource 權限</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></td>
      </tr>
      <tr>
          <td>Secret / API key 治理</td>
          <td><a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
      <tr>
          <td>Key lifecycle / envelope encryption</td>
          <td>AWS KMS vendor 頁（S2 批次撰寫中）+ <a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
      <tr>
          <td>事件偵測（CloudTrail 以外）</td>
          <td>04 SIEM / detection 工具與 07 SIEM 章節</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>IAM policy JSON 語法完整 reference 與所有 condition key 清單</li>
<li>每個 AWS service 的細部 IAM 動作對照</li>
<li>AWS Organization、Control Tower、Landing Zone 完整建置流程</li>
<li>KMS / Secrets Manager / Certificate Manager 的內部細節（見對應 vendor 頁）</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 AWS IAM 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/microsoft-storm-0558-signing-key-2023/" data-link-title="7.C4 Microsoft：Storm-0558 簽章金鑰事件" data-link-desc="簽章金鑰事件如何回寫 identity 信任邊界與觀測證據鏈。">Microsoft Storm-0558 Signing Key 2023</a></td>
          <td>雖是 Microsoft Entra / Exchange Online 事件、對 AWS <em>cross-account role assumption signing chain</em> 提供對照：ExternalID 設計、HSM-bound key、跨帳號 token 驗證一致性</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>IAM User access key、STS session、Role trust 的 rotation 必須分域分批、不能單一指令打全部</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain (red-team)</a></td>
          <td>對 IAM Roles Anywhere / OIDC trust 的 signing material 治理啟示：trust anchor、key custody、跨環境驗證</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a>、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a>、<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>（AWS KMS vendor 頁 S2 批次撰寫中）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（CloudTrail / Access Analyzer 訊號如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/">AWS IAM User Guide</a>、<a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/">AWS IAM Identity Center User Guide</a></li>
</ul>
]]></content:encoded></item><item><title>Google Cloud IAM</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-iam/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-iam/</guid><description>&lt;p>Google Cloud IAM 是 GCP 的 cloud resource permission engine、把 &lt;em>誰能對哪個 resource 做什麼&lt;/em> 統一成一個模型：Principal + Role + Resource scope 三件事拼成一個 &lt;em>role binding&lt;/em>。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> 等 IdP 是兩層責任 — Okta 回答「這個人是誰」、Google IAM 回答「這個身份能對 GCP resource 做什麼」。設計上比 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> 統一、沒有 resource-based policy vs identity-based policy 雙軌、也沒有 SCP / Permission Boundary 多層覆蓋、policy 評估路徑短而可預測。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Google Cloud IAM 的核心抽象是 &lt;em>role binding on a resource scope&lt;/em>：把 role grant 給 principal、生效範圍是某個 Organization / Folder / Project / 個別 resource、沿 resource hierarchy 向下繼承。同一個 principal 在不同 scope 可以有不同 role、有效權限是所有 binding 的 union。這跟 AWS IAM 的「identity policy + resource policy + SCP + boundary 多層 intersect / union」相比、推理成本低、但也意味著 &lt;em>guardrail 必須走 Organization Policy 這另一個系統&lt;/em> — 不是 IAM grant 的一部分。&lt;/p>
&lt;p>跟 Azure RBAC 相比、兩者都是 scope-based、都靠 hierarchy 繼承。差異在 &lt;em>Service Account 是 GCP 的 first-class identity&lt;/em>：有自己的 email、可被 impersonate、可以 grant role 給它也可以 grant &lt;code>iam.serviceAccountUser&lt;/code> 讓人類 act-as 它。Azure 的對應是 Managed Identity、語義接近但 impersonation chain 的表達更隱晦。選 GCP（= 用 Google Cloud IAM）的核心訴求通常是：BigQuery / Vertex AI / GKE workload、想用 Workload Identity Federation 取代 long-lived key、團隊偏好較統一的 policy 模型。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>Google Cloud IAM 該承擔哪一段權限（resource access、service-to-service、cross-cloud federation）、哪一段該交給 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> / IdP&lt;/li>
&lt;li>Role 的選擇順序（Predefined &amp;gt; Custom &amp;gt; Basic）與 IAM Conditions 何時補上&lt;/li>
&lt;li>Service Account / Workload Identity Federation 的信任邊界、何時不該再發 service account key&lt;/li>
&lt;li>何時改走 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &amp;#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&amp;#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC&lt;/a> / Organization Policy / VPC Service Controls&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷一個 GCP project 的 IAM 配置是否健康、最少看五件事：&lt;/p></description><content:encoded><![CDATA[<p>Google Cloud IAM 是 GCP 的 cloud resource permission engine、把 <em>誰能對哪個 resource 做什麼</em> 統一成一個模型：Principal + Role + Resource scope 三件事拼成一個 <em>role binding</em>。它跟 <a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> 等 IdP 是兩層責任 — Okta 回答「這個人是誰」、Google IAM 回答「這個身份能對 GCP resource 做什麼」。設計上比 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 統一、沒有 resource-based policy vs identity-based policy 雙軌、也沒有 SCP / Permission Boundary 多層覆蓋、policy 評估路徑短而可預測。</p>
<h2 id="服務定位">服務定位</h2>
<p>Google Cloud IAM 的核心抽象是 <em>role binding on a resource scope</em>：把 role grant 給 principal、生效範圍是某個 Organization / Folder / Project / 個別 resource、沿 resource hierarchy 向下繼承。同一個 principal 在不同 scope 可以有不同 role、有效權限是所有 binding 的 union。這跟 AWS IAM 的「identity policy + resource policy + SCP + boundary 多層 intersect / union」相比、推理成本低、但也意味著 <em>guardrail 必須走 Organization Policy 這另一個系統</em> — 不是 IAM grant 的一部分。</p>
<p>跟 Azure RBAC 相比、兩者都是 scope-based、都靠 hierarchy 繼承。差異在 <em>Service Account 是 GCP 的 first-class identity</em>：有自己的 email、可被 impersonate、可以 grant role 給它也可以 grant <code>iam.serviceAccountUser</code> 讓人類 act-as 它。Azure 的對應是 Managed Identity、語義接近但 impersonation chain 的表達更隱晦。選 GCP（= 用 Google Cloud IAM）的核心訴求通常是：BigQuery / Vertex AI / GKE workload、想用 Workload Identity Federation 取代 long-lived key、團隊偏好較統一的 policy 模型。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>Google Cloud IAM 該承擔哪一段權限（resource access、service-to-service、cross-cloud federation）、哪一段該交給 <a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / IdP</li>
<li>Role 的選擇順序（Predefined &gt; Custom &gt; Basic）與 IAM Conditions 何時補上</li>
<li>Service Account / Workload Identity Federation 的信任邊界、何時不該再發 service account key</li>
<li>何時改走 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a> / Organization Policy / VPC Service Controls</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一個 GCP project 的 IAM 配置是否健康、最少看五件事：</p>
<ul>
<li><strong>Principal 級別</strong>：誰是 Owner / Editor / Viewer（Basic Role 應該幾乎為空）、Service Account 是否獨立列管、有沒有 user 直接 grant 沒走 group</li>
<li><strong>Role 種類</strong>：Predefined Role 是 baseline、Custom Role 收斂 least privilege、Basic Role 視為待修；user-managed Service Account key 是否存在（理想是 0）</li>
<li><strong>Impersonation chain 展平稽核</strong>：誰有 <code>iam.serviceAccountTokenCreator</code> / <code>iam.serviceAccountUser</code> 對哪個 SA、間接 chain（A → B → C）展平後 <em>誰最終能 act as 高權限 SA</em>。這是 GCP IAM 最容易漏稽核的一條 — 直接 binding 看 Role、但 lateral movement 走 impersonation chain</li>
<li><strong>IAM Conditions</strong>：高敏 resource（prod bucket、KMS key、BigQuery dataset）是否用 condition expression 補 attribute-level 限制（resource name prefix、request time、IP）</li>
<li><strong>Audit Logs</strong>：Admin Activity 預設開、Data Access logs 在 sensitive resource 是否手動開、System Log 是否同步到 SIEM 並 alert role 變更與 service account key 建立</li>
</ul>
<p>五件事任一缺失、就是 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 與 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Role 選擇順序</strong>：Predefined Role 是 baseline、覆蓋 80% 場景；Custom Role 用於收斂 least privilege（例如只給 <code>bigquery.dataViewer</code> 的特定子集）；Basic Role（Owner / Editor / Viewer）幾乎不該再用 — Editor 預設帶寫權限到幾乎所有資源類型、Owner 還能改 IAM policy 本身、粒度過粗。Project 建立預設給的 Owner role 是 <em>人類自己 grant 自己</em>、不是無法避免的 baseline。</p>
<p><strong>Principal type</strong>：人類用 Google Workspace user / external user，群組走 Google Group（grant 給 group 比 grant 給 user 更穩、離職 lifecycle 由 IdP / HRIS 推 group 變更即可）。Service Account 是 <em>第一級身份</em>、跟 user 同等、有自己的 email（<code>name@project.iam.gserviceaccount.com</code>）、可被 grant role 也可被 impersonate。Workload identity（K8s SA、外部 OIDC subject）是 federation 層、不在 IAM 內直接列管、但 <em>最後仍 impersonate 一個 Service Account 來拿 GCP 權限</em>。</p>
<p><strong>IAM Conditions</strong>：在 role binding 上加 attribute-based 條件、補純 RBAC 不足。常見 expression：<code>resource.name.startsWith(&quot;projects/_/buckets/prod-&quot;)</code>、<code>request.time &lt; timestamp(&quot;2026-12-31T00:00:00Z&quot;)</code>、<code>resource.type == &quot;storage.googleapis.com/Bucket&quot;</code>。適合 <em>temporary access</em>、<em>resource name 範圍限定</em>、<em>環境隔離</em>；不適合複雜 ABAC 規則（會難以稽核、且 condition 只能用在支援的 resource type 上）。</p>
<p><strong>Service Account impersonation</strong>：人類或另一個 Service Account 透過 <code>iam.serviceAccountTokenCreator</code> role 借用目標 SA 的權限、不需要 SA key。impersonation chain 可以串（A 可 impersonate B、B 可 impersonate C）— 這條鏈是 lateral movement 風險、稽核時要展平看 <em>誰最終能 act as 高權限 SA</em>。對應 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a> 的教訓：rotation 沒分域時、單點 SA compromise 會跨環境擴散。</p>
<p><strong>Workload Identity Federation（WIF）</strong>：GCP 接受外部 OIDC / SAML issuer（GitHub Actions、AWS、Azure、自管 K8s OIDC、CircleCI 等）發的 token、在 Workload Identity Pool 設 attribute mapping 後、外部 token 換成 short-lived GCP credential、最後 impersonate 指定 Service Account。是 <em>取代 SA JSON key 的 modern best practice</em>、CI / 跨雲 / 邊緣 workload 都該優先用。Trust 條件要鎖 <em>issuer + audience + subject</em>（例：<code>assertion.repository == &quot;myorg/myrepo&quot;</code>）— 缺一個就可能被同 issuer 下其他 subject 借用，這是 <a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain</a> 對 external OIDC 信任的提醒：發 token 的 issuer 一旦被攻破、所有信任它的 audience 都跟著受害。</p>
<p><strong>Service Account key（避免）</strong>：user-managed JSON key 是 long-lived credential、無 TTL、無 IP 限制、外洩偵測難。應該以 Workload Identity Federation 或 Service Account Impersonation 取代；若必須用、走 Organization Policy <code>iam.disableServiceAccountKeyCreation</code> 預設禁用、例外申請走 ticket、key 進 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a>、季度盤點未使用 key 刪除。</p>
<p><strong>Organization Policy（guardrail）</strong>：跟 IAM 完全不同層 — 不是 grant、是 <em>限制可以做什麼設定</em>。常用 constraint：<code>iam.disableServiceAccountKeyCreation</code>、<code>iam.allowedPolicyMemberDomains</code>（限制只能 grant 給特定 domain 的 principal）、<code>compute.vmExternalIpAccess</code>（限制 VM external IP）、<code>storage.publicAccessPrevention</code>。Org Policy 在 Organization / Folder / Project 層設定、IAM 即使想 grant 也擋得住。</p>
<p><strong>Audit / handoff</strong>：Admin Activity Log 預設開、不能關、保留 400 天免費；Data Access Log 預設關、開了會大量 log（也大量計費）— 對 sensitive resource（KMS key access、BigQuery dataset read、Secret Manager access）應該手動開；System Event Log 補基礎設施事件。三類都接 Cloud Logging sink 推到 SIEM、特別 alert 三件事 — IAM policy 變更、Service Account key 建立 / 上傳、Workload Identity Pool / Provider 變更。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Google Cloud IAM</th>
          <th>AWS IAM</th>
          <th>Azure RBAC</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Policy 模型</td>
          <td>Role binding on resource scope、單軌</td>
          <td>Identity policy + resource policy + SCP + boundary</td>
          <td>Scope-based、Management Group 階層</td>
      </tr>
      <tr>
          <td>表達力</td>
          <td>中等、IAM Conditions 補 attribute</td>
          <td>最高、policy language 表達 ABAC / 條件 / 否決</td>
          <td>中等、Azure Policy 補 ABAC</td>
      </tr>
      <tr>
          <td>Guardrail 機制</td>
          <td>Organization Policy（獨立系統、constraint）</td>
          <td>SCP（policy 同語法、separate plane）</td>
          <td>Azure Policy（獨立系統、constraint）</td>
      </tr>
      <tr>
          <td>Machine identity</td>
          <td>Service Account first-class + WIF</td>
          <td>IAM Role + STS AssumeRole + OIDC trust</td>
          <td>Managed Identity + Workload Identity Federation</td>
      </tr>
      <tr>
          <td>Cross-cloud federation</td>
          <td>WIF 接外部 OIDC 是 modern best practice</td>
          <td>OIDC trust on IAM Role、表達力強</td>
          <td>Federated credentials、近年補齊</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>較緩、模型統一</td>
          <td>陡、policy 評估順序複雜</td>
          <td>中等、scope inheritance 直覺</td>
      </tr>
      <tr>
          <td>推理 / 稽核成本</td>
          <td>低 — binding union、Org Policy 獨立看</td>
          <td>高 — 多層 intersect / union、需 policy simulator</td>
          <td>中 — scope 繼承明確、policy 分散</td>
      </tr>
  </tbody>
</table>
<p>選 Google Cloud IAM 的核心訴求：<em>已在 GCP 上、或想用 BigQuery / Vertex AI / GKE</em>、團隊偏好較統一的 policy 模型、跨雲場景靠 WIF 對外發 trust 而不維護多套 key。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Workload Identity Federation 的深層應用</strong>：除了 GitHub Actions、AWS、Azure 這類常見 issuer、WIF 也支援自管 K8s OIDC issuer（OSS K8s cluster 跑 GKE workload identity 等價物）、SaaS（Snowflake、Terraform Cloud）發的 OIDC token。trust 設定要鎖 issuer URL、audience、subject pattern 三件事 — 任何一個太寬都是同 issuer 下別人借用你 SA 的入口。</p>
<p><strong>Organization Policy 的 dry-run / 例外</strong>：constraint 可以先設 <code>dryRun</code> 觀察會擋掉哪些操作再 enforce；例外用 <em>exception folder</em>（特定 folder 不繼承上層 constraint）或 <em>condition</em>（特定 resource pattern 不擋）。直接全 org 一次 enforce 通常會打掉既有 workload、要分階段。</p>
<p><strong>IAM Conditions 的有限性</strong>：condition 只能用在支援的 resource type 上、不是全 GCP 通用；複雜 expression 難稽核（CEL 語法、不易讀）；condition 不能否決 — 只能限制 binding 的生效範圍、不能像 AWS policy 那樣寫 <code>Deny</code>。複雜 ABAC 場景該走 Organization Policy + 應用層授權邊界、不是把所有規則塞進 IAM Conditions。</p>
<p><strong>Service Account Impersonation chain 的稽核</strong>：列出 <em>有 <code>serviceAccountTokenCreator</code> 的 principal</em> 是基本；展平 chain（A → B → C）需要 graph walk 工具或 Policy Analyzer；高權限 SA（owner-equivalent custom role、跨 project 寫權限）的 impersonation 來源應該是 <em>寫死的少數 admin SA + break-glass</em>、不該開放給 CI / 一般 service。</p>
<p><strong>VPC Service Controls（資料邊界、跟 IAM 互補）</strong>：在 IAM 之外加 <em>資料 perimeter</em> — 即使 principal 有 IAM 權限、如果請求不是來自 perimeter 內（VPC、特定 IP、特定 service account），仍然會被擋。適合 BigQuery / GCS / Secret Manager 這類存資料的 service、防 <em>合法 credential 從外部 exfiltrate 資料</em>（<a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a> 場景的下游補位：identity 控制面失守時、資料層仍有獨立 perimeter）。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Basic Role 還在用</strong>：Project Owner / Editor 散落、新人 onboard 直接 Editor — 改 group + Predefined Role、Basic Role 改成 break-glass 限定</li>
<li><strong>Service Account key 散落</strong>：CI 用 JSON key、key 進 git 或環境變數、無 rotation — 改 WIF（GitHub Actions / GitLab CI 都支援）、Org Policy 禁用 SA key 建立</li>
<li><strong>WIF trust 太寬</strong>：只鎖 issuer 沒鎖 subject、同 GitHub org 任何 repo 都能借用 SA — trust 要含 <code>assertion.repository</code>、<code>assertion.ref</code>（main branch only）等 condition</li>
<li><strong>IAM Conditions 越寫越多</strong>：condition expression 過度複雜、稽核時沒人讀得懂 — 簡化條件、把複雜規則上移到應用層或 Org Policy</li>
<li><strong>Data Access Logs 沒開</strong>：sensitive resource 出事時只有 Admin Activity、看不到 <em>誰讀了什麼</em> — KMS key、Secret Manager、BigQuery 高敏 dataset 必開 Data Access Log</li>
<li><strong>Impersonation chain 失控</strong>：太多人有 <code>serviceAccountTokenCreator</code> 到高權限 SA — 用 Policy Analyzer 展平、收斂到必要 admin + break-glass</li>
<li><strong>Org Policy 沒設</strong>：root org 沒有 baseline constraint、新建 project 預設可建 SA key / public IP / public bucket — 至少設 <code>disableServiceAccountKeyCreation</code> + <code>publicAccessPrevention</code> + <code>allowedPolicyMemberDomains</code></li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>人類身份的 SSO / MFA / lifecycle</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / IdP</td>
      </tr>
      <tr>
          <td>AWS resource permission</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a></td>
      </tr>
      <tr>
          <td>Azure resource permission</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></td>
      </tr>
      <tr>
          <td>跨雲 unified IAM</td>
          <td>沒有單一答案 — 各雲 IAM + Workload Identity Federation 對接、或外部 PAM（Teleport / Boundary）</td>
      </tr>
      <tr>
          <td>Secret / Service Account key 治理</td>
          <td><a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
      <tr>
          <td>資料分類 / DLP / 匯出控制</td>
          <td><a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 資料保護與遮罩治理</a></td>
      </tr>
      <tr>
          <td>Workload runtime detection（容器、syscall）</td>
          <td>04 + Falco / Cilium Tetragon 類工具</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>各 Predefined Role 的完整權限清單與細部 permission 差異</li>
<li>IAM Conditions CEL 語法的完整 spec</li>
<li>Workload Identity Federation 跟特定 issuer（GitHub / AWS / Azure）的逐步設定教學</li>
<li>BigQuery / GCS / KMS 等服務的 service-specific IAM 行為細節</li>
<li>GCP 計費 / SKU 對 Audit Log 開關的影響</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 Google Cloud IAM 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a></td>
          <td>Identity 控制面故障不直接打到 Google IAM、但設計啟示是 IAM evaluation 路徑必須 HA、且 VPC Service Controls 等資料 perimeter 是 identity 失守時的下游補位</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>Service Account key、WIF provider 的 rotation 必須分域 — 跨 project / 跨環境的 SA 共用是 blast radius 放大器</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain</a></td>
          <td>對 WIF 的提醒 — 信任 external OIDC issuer 時、issuer 自己被攻破會打到所有 audience；trust condition 必須鎖 issuer + audience + subject 三件事</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a>、<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a>、<a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a>、<a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>（Google Secret Manager / Google Cloud KMS 個別 vendor 頁 S2 批次撰寫中）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（GCP IAM 事件如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://cloud.google.com/iam/docs">Google Cloud IAM Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>Azure RBAC + Entra ID</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-rbac/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-rbac/</guid><description>&lt;p>Azure 的身份與權限體系是 &lt;em>雙層&lt;/em> — Entra ID（前 Azure AD）是 IdP，承擔人類與 workload 的身份來源、SSO、MFA 與 Conditional Access；Azure RBAC 是 cloud resource 的 permission engine，把 role 指派到 scope（Management Group / Subscription / Resource Group / Resource）上的 principal。兩層責任不同、設定介面不同、出事故時的徵兆也不同 — 把兩者寫成同一件事是 Azure 治理最常見的混淆來源。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Entra ID 是 &lt;em>Microsoft 自有的 workforce IdP&lt;/em>、跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> 是直接競爭者。M365 / Azure-heavy 的組織通常直接用 Entra ID 當主 IdP；Okta-first 的組織可以把 Entra ID 當下游 SP（federation）、也可以雙 IdP 並存、但雙 IdP 的 break-glass 跟 lifecycle 路徑要重新設計。Entra ID 同時承擔 &lt;em>consumer-side 跟 partner-side 的 multi-tenant app&lt;/em> 信任、跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0&lt;/a> 在 B2C 場景有交集。&lt;/p>
&lt;p>Azure RBAC 是 cloud resource permission engine、跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM&lt;/a> 同層 — 都在解「身份對 cloud resource 能做什麼」。差異在 &lt;em>scope hierarchy&lt;/em> — Azure 用 Management Group → Subscription → Resource Group → Resource 四層繼承、AWS 用 account + organization、Google 用 organization → folder → project。Azure RBAC 預期 &lt;em>role assignment 沿 scope 向下繼承&lt;/em>、這跟 AWS 在每個 account 重新指派的習慣不一樣、跨雲團隊轉過來常踩到。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>哪一段控制屬於 Entra ID（身份）、哪一段屬於 Azure RBAC（resource permission）、不要把兩層當同一件事&lt;/li>
&lt;li>Entra ID tenant 的最低稽核需求（Global Admin、App Registration、Conditional Access、Managed Identity）&lt;/li>
&lt;li>Azure RBAC 的 scope 設計、Custom Role 跟 PIM 何時必要&lt;/li>
&lt;li>Entra ID 控制面事故的降級路徑、跟 Azure RBAC 出事的徵兆差異&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Azure 雙層體系是否健康、要分兩層各看兩件事、跟「日常操作與決策形狀」段的兩層結構對齊。&lt;/p></description><content:encoded><![CDATA[<p>Azure 的身份與權限體系是 <em>雙層</em> — Entra ID（前 Azure AD）是 IdP，承擔人類與 workload 的身份來源、SSO、MFA 與 Conditional Access；Azure RBAC 是 cloud resource 的 permission engine，把 role 指派到 scope（Management Group / Subscription / Resource Group / Resource）上的 principal。兩層責任不同、設定介面不同、出事故時的徵兆也不同 — 把兩者寫成同一件事是 Azure 治理最常見的混淆來源。</p>
<h2 id="服務定位">服務定位</h2>
<p>Entra ID 是 <em>Microsoft 自有的 workforce IdP</em>、跟 <a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> 是直接競爭者。M365 / Azure-heavy 的組織通常直接用 Entra ID 當主 IdP；Okta-first 的組織可以把 Entra ID 當下游 SP（federation）、也可以雙 IdP 並存、但雙 IdP 的 break-glass 跟 lifecycle 路徑要重新設計。Entra ID 同時承擔 <em>consumer-side 跟 partner-side 的 multi-tenant app</em> 信任、跟 <a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0</a> 在 B2C 場景有交集。</p>
<p>Azure RBAC 是 cloud resource permission engine、跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a> 同層 — 都在解「身份對 cloud resource 能做什麼」。差異在 <em>scope hierarchy</em> — Azure 用 Management Group → Subscription → Resource Group → Resource 四層繼承、AWS 用 account + organization、Google 用 organization → folder → project。Azure RBAC 預期 <em>role assignment 沿 scope 向下繼承</em>、這跟 AWS 在每個 account 重新指派的習慣不一樣、跨雲團隊轉過來常踩到。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>哪一段控制屬於 Entra ID（身份）、哪一段屬於 Azure RBAC（resource permission）、不要把兩層當同一件事</li>
<li>Entra ID tenant 的最低稽核需求（Global Admin、App Registration、Conditional Access、Managed Identity）</li>
<li>Azure RBAC 的 scope 設計、Custom Role 跟 PIM 何時必要</li>
<li>Entra ID 控制面事故的降級路徑、跟 Azure RBAC 出事的徵兆差異</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Azure 雙層體系是否健康、要分兩層各看兩件事、跟「日常操作與決策形狀」段的兩層結構對齊。</p>
<p><strong>Entra ID 層</strong>（身份控制面）：</p>
<ul>
<li><strong>誰能做什麼</strong>：Global Admin / Privileged Role Administrator 的人數、是否走 <a href="#%e9%80%b2%e9%9a%8e%e4%b8%bb%e9%a1%8c">PIM</a> just-in-time、Conditional Access 是否強制 <a href="/blog/backend/knowledge-cards/authentication/" data-link-title="Authentication" data-link-desc="說明系統如何確認呼叫者身份">phishing-resistant 認證</a>、break-glass 帳號是否 <em>exclude</em> 自所有 CA policy 又單獨監控</li>
<li><strong>入口如何暴露</strong>：App Registration 是否限定 single-tenant、multi-tenant app 的 admin consent 流程是否經審查、Managed Identity 是否取代 service principal client secret</li>
</ul>
<p><strong>Azure RBAC 層</strong>（resource permission）：</p>
<ul>
<li><strong>誰能對 resource 做什麼</strong>：Owner / Contributor 在哪個 scope（Management Group 還是 Subscription）、production 環境是否用 Custom Role 收緊權限、有沒有 standing assignment 該改 PIM</li>
<li><strong>證據是否可回查</strong>：Entra ID Sign-in Log / Audit Log 是否同步到 SIEM、Azure Activity Log 是否設保留與 alert、admin consent / role assignment 變更是否觸發 <a href="/blog/backend/knowledge-cards/alert-runbook/" data-link-title="Alert Runbook" data-link-desc="說明告警如何連到可執行的排障與恢復流程">alert runbook</a></li>
</ul>
<p>兩層任一邊任一條缺失、就是 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 與 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<h3 id="entra-id-層">Entra ID 層</h3>
<p><strong>User / Group / lifecycle</strong>：HRIS 推 SCIM 進 Entra ID、Entra ID 同步到下游 SaaS 跟 Azure RBAC group。決策點是 <em>source of truth</em> — 多數組織把 HRIS 設為人員來源、Entra ID 當分發層、避免雙寫造成 stale account。</p>
<p><strong>Conditional Access 是 MFA <em>主要強制機制</em></strong>：MFA 不是設在 user 屬性上、是 Conditional Access policy 在登入時判斷 user / device / location / app / risk 後觸發。常見設定錯誤包含 <em>exclude legacy auth 沒做、break-glass 規則太寬、emergency access 帳號沒獨立監控</em>。Conditional Access 規則設計錯、就是高權限 bypass 的入口。</p>
<p><strong>App Registration vs Enterprise Application</strong>：開發者註冊 multi-tenant app 走 <em>App Registration</em>（app 的定義）、組織 admin 為某 app 設定 SAML SSO / admin consent 走 <em>Enterprise Application</em>（該 tenant 對 app 的信任）。兩者常被混講、但安全意義不同 — App Registration 是「我們做了一個 app」、Enterprise Application 是「我們信任這個 app 用我們的身份」。Consent phishing 攻擊就是針對後者。</p>
<p><strong>Managed Identity</strong>：Azure resource（VM、Function、AKS pod）自帶身份、不需要 service principal client secret、跟 <a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Workload Identity Federation</a> 同概念但 Azure-internal。System-assigned 跟 resource 生命週期綁定、resource 刪掉 identity 跟著刪；User-assigned 獨立、可跨 resource 共用。production 環境的服務存取 Key Vault / Storage 應走 Managed Identity、不該用 client secret。</p>
<p><strong>Workload Identity Federation</strong>：Entra ID 可以 <em>trust 外部 OIDC issuer</em>（GitHub Actions、AWS、Google）、讓外部 workload 直接拿 Entra ID token、不用儲存 client secret。CI/CD 的 OIDC 整合是這層的主用例、比把 client secret 塞進 CI variable 安全很多。</p>
<p><strong>Signing key 是 control plane 託管</strong>：Entra ID 不暴露 signing key、客戶沒有 rotate 它的能力。這層信任邊界一旦失守、客戶側 <em>直接修不了</em>、要等供應商發 patch 或公告 — Storm-0558 揭示了這條依賴的代價。客戶側能做的補強是 <em>下游檢查</em> 而非 <em>上游修復</em>：</p>
<ul>
<li>訂閱 Microsoft Security Advisory（MSRC）+ tenant-specific notification、讓事件公告第一時間進 IR pipeline、不要靠新聞才知道</li>
<li>SIEM alert <em>anomalous token issuance pattern</em>（跨租戶 token 在 Exchange / Graph API 出現異常存取序列）、不能只信 token signature valid</li>
<li>高敏 app 的 token validation 不只看 Entra ID 標準驗證、加 <em>issuer + tenant + audience + nonce</em> 多層比對、攻擊者偽造跨租戶 token 時可能漏掉某層</li>
<li>Conditional Access 配 <em>token protection</em>（token binding to device）、降低 stolen token replay 的命中率</li>
<li>IR playbook 預設 <em>signing key 事件</em> 一條 — 一旦供應商公告、強制 sign-out 高權限 user、token TTL 收短、回頭看 90 天 sign-in log 找異常</li>
</ul>
<h3 id="azure-rbac-層">Azure RBAC 層</h3>
<p><strong>Scope 設計</strong>：role assignment 沿 Management Group → Subscription → Resource Group → Resource 向下繼承。在 Management Group 給 Contributor、底下所有 subscription / RG / resource 都繼承 — 這既是優點（統一治理）也是風險（誤指派擴散範圍大）。設計原則是 <em>指派盡量低、不要對全 Management Group 給 Contributor</em>。</p>
<p><strong>Built-in role vs Custom Role</strong>：Owner（含 user access admin）/ Contributor（不含權限管理）/ Reader 是 built-in、通常太粗。production 環境需要 Custom Role 把 <code>Microsoft.Storage/storageAccounts/listKeys/action</code> 之類的高風險 action 收掉、只留 read。Custom Role 是 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">least privilege</a> 在 Azure 的落實工具、不做就是用 Contributor 當預設、權限過寬。</p>
<p><strong>Privileged Identity Management（PIM）</strong>：高權限角色（Global Admin、Subscription Owner、User Access Administrator）應走 just-in-time activation、需要 MFA 跟 approval、不該 permanent assignment。沒上 PIM 的組織通常會發現 <em>standing Global Admin 超過 10 個</em>、那是 phishing / token theft 的高價值靶。</p>
<p><strong>Service principal vs Managed Identity</strong>：service principal 是 app 在 Entra ID 的代表、可以用 client secret 或 certificate 認證；Managed Identity 是 service principal 的特殊形式、由 Azure 自動管 credential。能用 Managed Identity 就不用 service principal client secret — 後者要自己 rotate、要存 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">secret management</a>、容易 stale。</p>
<p><strong>Azure Policy 是 RBAC 的補位</strong>：RBAC 管 <em>principal 能不能對 resource 做這個 action</em>、Azure Policy 管 <em>允不允許這樣設定 resource</em>（例如 storage account 強制加密、VM 只能用認可的 image）。RBAC 給 Contributor 的人可以建 storage account、但 Azure Policy 可以拒絕未加密的 storage account 建立 — 兩層互補、缺一不可。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<p>Azure 雙層體系的取捨要分開看 — 一張表回答 <em>cloud resource permission 該選哪家</em>（Azure RBAC vs AWS IAM vs Google IAM）、一張表回答 <em>workforce IdP 該選哪家</em>（Entra ID vs Okta）。兩個決策獨立、可以混搭（例如：Okta 當 workforce IdP + federate 到 Entra ID + 走 Azure RBAC 管 Azure resource）。</p>
<h3 id="azure-rbac-vs-aws-iam-vs-google-cloud-iam">Azure RBAC vs AWS IAM vs Google Cloud IAM</h3>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Azure RBAC</th>
          <th>AWS IAM</th>
          <th>Google Cloud IAM</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Scope</td>
          <td>Management Group → Subscription → RG → Resource</td>
          <td>Account + Organization、policy attach</td>
          <td>Organization → Folder → Project</td>
      </tr>
      <tr>
          <td>繼承模型</td>
          <td>scope 向下繼承</td>
          <td>account boundary 強、跨 account 用 assume role</td>
          <td>scope 向下繼承、condition 強</td>
      </tr>
      <tr>
          <td>自訂角色</td>
          <td>Custom Role（JSON）</td>
          <td>Custom managed policy（JSON）</td>
          <td>Custom Role（YAML / API）</td>
      </tr>
      <tr>
          <td>JIT 機制</td>
          <td>Privileged Identity Management（PIM）內建</td>
          <td>無原生 JIT、要靠 IAM Identity Center / 第三方</td>
          <td>無原生 JIT、要靠 third-party / 自建</td>
      </tr>
      <tr>
          <td>Workload</td>
          <td>Managed Identity（內部）+ Workload Identity Fed</td>
          <td>IAM role + OIDC trust</td>
          <td>Workload Identity Federation</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Azure-heavy、M365 整合</td>
          <td>AWS-heavy、account isolation 模型成熟</td>
          <td>GCP-heavy、resource hierarchy 治理</td>
      </tr>
  </tbody>
</table>
<h3 id="entra-id-vs-oktaworkforce-idp">Entra ID vs Okta（workforce IdP）</h3>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Entra ID</th>
          <th>Okta</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主場</td>
          <td>M365 / Azure 原生、跟 RBAC 共生</td>
          <td>多雲 + SaaS、跨平台 SSO</td>
      </tr>
      <tr>
          <td>MFA 機制</td>
          <td>Conditional Access 觸發、Authenticator app / FIDO2</td>
          <td>Sign-On / Authentication Policy、多 factor 選擇</td>
      </tr>
      <tr>
          <td>Lifecycle</td>
          <td>SCIM + cross-tenant sync</td>
          <td>SCIM + Lifecycle Management、整合更廣</td>
      </tr>
      <tr>
          <td>Workload</td>
          <td>Managed Identity / Workload Identity Federation</td>
          <td>較弱、CI 通常 federate 到雲 IAM</td>
      </tr>
      <tr>
          <td>整合廣度</td>
          <td>M365 / Azure / Office app 深、外部 SaaS 比 Okta 少</td>
          <td>7000+ SaaS app 預建</td>
      </tr>
      <tr>
          <td>第三方風險</td>
          <td>Microsoft 控制面（Storm-0558、Midnight Blizzard）</td>
          <td>Okta 控制面（2022 / 2023 多起）</td>
      </tr>
  </tbody>
</table>
<p>選 Entra ID 的核心訴求：<em>M365 / Azure 重度使用、要跟 RBAC + Managed Identity 直接整合、能接受 Microsoft 控制面風險</em>；選 Okta 的核心訴求看 <a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta vendor 頁</a>。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Conditional Access 進階規則</strong>：除了 user / device / location 基本條件、進階場景包含 <em>risk-based</em>（Identity Protection 給的 user risk / sign-in risk）、<em>token protection</em>（token binding 到 device、防止 token replay）、<em>authentication strength</em>（強制 phishing-resistant factor）。production tenant 至少要有「Global Admin 必須走 phishing-resistant + compliant device」這條規則。</p>
<p><strong>Privileged Identity Management（PIM）的設計細節</strong>：activation 要求 MFA、approval（高權限角色）、justification、時限（預設 8 小時、最長 24）。Access Review 是 PIM 的配套 — 季度檢視 standing assignment 是否還需要、不需要的撤掉。沒做 Access Review 的 PIM 等於只把問題從 standing 推到 <em>誰申請就給</em> — 不是 least privilege。</p>
<p><strong>Workload Identity Federation 跨雲</strong>：Entra ID 可以 trust GitHub Actions / GitLab / AWS / Google 的 OIDC issuer、讓 CI 直接拿 Azure token。同向也成立 — Azure workload 可以拿 Google ID token federate 進 GCP。多雲 CI 不該存任何 client secret、走 federation 比較安全。</p>
<p><strong>Custom Role 設計實務</strong>：用 <code>Microsoft.Authorization/roleDefinitions</code> API 或 portal 定義、<code>actions</code> / <code>notActions</code> / <code>dataActions</code> 各自獨立 — <code>actions</code> 是 control plane、<code>dataActions</code> 是 data plane（讀寫 blob、key vault secret 內容）。常見錯誤是只收 <code>actions</code> 沒收 <code>dataActions</code>、結果 storage account 設定改不了但 blob 內容隨便讀。</p>
<p><strong>Azure Policy 跟 Initiative</strong>：Policy 是單一規則、Initiative 是 policy 的集合（用來組 baseline、例如 CIS、ISO 27001）。Policy effect 有 audit / deny / deployIfNotExists、後者可以自動補洞（例如自動加 diagnostic setting）。RBAC + Policy 一起設計才是完整的 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 邊界。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Global Admin 過多</strong>：standing Global Admin 超過 5 個就要警惕 — 上 PIM、把日常運維改用 Privileged Role Administrator + 特定 admin role group</li>
<li><strong>Conditional Access 規則漏 legacy auth</strong>：規則只 cover modern auth、IMAP / POP / SMTP 等 legacy protocol 不走 CA — 用「Block legacy authentication」baseline policy 補</li>
<li><strong>App Registration / Enterprise Application admin consent 沒審查</strong>：使用者自己 consent 把 mail.read 給三方 app、變 consent phishing 入口 — 關閉 user consent、改 admin consent workflow</li>
<li><strong>Service principal client secret 散落</strong>：CI / 服務裡有大量 client secret、rotate 沒節奏 — 改 Managed Identity（內部）或 Workload Identity Federation（跨雲 CI）</li>
<li><strong>Subscription Owner 太多</strong>：subscription 級 Owner 是高風險、應該收到 Management Group 級 Reader + 必要時 PIM activate Owner</li>
<li><strong>Azure Activity Log 沒進 SIEM</strong>：role assignment 變更、Key Vault access policy 變更只在 Azure portal 看得到、沒 alert — 用 Diagnostic Setting 推 Event Hub / Log Analytics、再進 SIEM</li>
<li><strong>Break-glass 帳號 exclude 自所有 CA policy、但沒監控</strong>：emergency access 帳號不能被 CA 鎖、但 <em>任何登入都該 alert</em> — 配對 Sign-in Log alert + 季度驗證可用</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>AWS-only 環境</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a></td>
      </tr>
      <tr>
          <td>GCP-only 環境</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a></td>
      </tr>
      <tr>
          <td>多雲 + 大量 SaaS、IdP 中心化</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a></td>
      </tr>
      <tr>
          <td>Customer / B2C identity</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0</a></td>
      </tr>
      <tr>
          <td>自管 IdP / 不接受 SaaS</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak</a></td>
      </tr>
      <tr>
          <td>Secret / Key 管理</td>
          <td><a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>（Azure Key Vault vendor 頁 S2 批次撰寫中）</td>
      </tr>
      <tr>
          <td>偵測訊號（不只 Entra ID 內部）</td>
          <td>07 SIEM 章節、04 observability</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>Entra ID 完整 SAML / OIDC / SCIM 規格細節</li>
<li>Azure RBAC built-in role 完整清單與 action 對照</li>
<li>Conditional Access policy template 細節</li>
<li>Azure Policy 內建 initiative 完整清單</li>
<li>Microsoft 365 / Defender for Identity 等周邊產品</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 Entra ID / Azure RBAC 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a></td>
          <td>Entra ID 控制面故障外溢到 Teams / SharePoint / Exchange、業務必須有降級與切換策略、不能完全依賴單一 IdP 可用性</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/microsoft-storm-0558-signing-key-2023/" data-link-title="7.C4 Microsoft：Storm-0558 簽章金鑰事件" data-link-desc="簽章金鑰事件如何回寫 identity 信任邊界與觀測證據鏈。">Microsoft Storm-0558 Signing Key 2023</a></td>
          <td>signing key 治理失效會跨租戶影響 token 驗證信任、客戶側只能等供應商修復（MSRC / CSRB 公開報告補充了 crash dump / Exchange Online 等具體外洩路徑、屬 case 檔之外的歷史 reference）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain (red-team)</a></td>
          <td>HSM-bound key 是 control plane 必要前提、跨租戶 token 異常要立即升級、不能等供應商先公告</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>Entra ID app secret 跟 Managed Identity 的 rotation 分域、不該把 service principal client secret 跟 user password 混在同一個 rotation policy</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a>、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a>、<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a>、<a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>（Entra ID / Managed Identity 之後的 secret / key 層、Azure Key Vendor 個別 vendor 頁 S2 批次撰寫中）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（Entra ID / Azure 事件如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://learn.microsoft.com/entra/">Microsoft Entra Documentation</a>、<a href="https://learn.microsoft.com/azure/role-based-access-control/">Azure RBAC Documentation</a></li>
</ul>
]]></content:encoded></item></channel></rss>