<?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>Release Gate on Tarragon</title><link>https://tarrragon.github.io/blog/tags/release-gate/</link><description>Recent content in Release Gate on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 11 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/release-gate/index.xml" rel="self" type="application/rss+xml"/><item><title>CI gate 與 workflow 邊界</title><link>https://tarrragon.github.io/blog/ci/ci-gate-workflow-boundary/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/ci-gate-workflow-boundary/</guid><description>&lt;p>CI gate 的核心責任是把「是否進入下一階段」變成明確條件。測試、建置、發布與人工審核可以分成不同 workflow 或 job，但只要它們共同決定同一次發布，就需要有清楚的 gate 關係。&lt;/p>
&lt;h2 id="gate-形式">Gate 形式&lt;/h2>
&lt;p>Gate 形式要依控制範圍選擇。PR 合併、job 執行順序、production 發布與 artifact 傳遞是四種不同責任，混在一起會讓紅燈的意義變模糊。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Gate 形式&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>判讀方式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/required-checks/" data-link-title="Required Checks" data-link-desc="說明 pull request 的必要檢查如何作為合併 gate">Required checks&lt;/a>&lt;/td>
 &lt;td>阻止未通過測試的 commit 合併&lt;/td>
 &lt;td>PR 或 branch protection 顯示必須通過&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Job &lt;code>needs&lt;/code>&lt;/td>
 &lt;td>讓 deploy 等 test / build&lt;/td>
 &lt;td>同一 workflow 內 deploy 依賴前置 job&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/environment-protection/" data-link-title="Environment Protection" data-link-desc="說明目標環境的審核、權限與放行條件如何保護發布">Environment protection&lt;/a>&lt;/td>
 &lt;td>控制 production / target environment 發布&lt;/td>
 &lt;td>部署環境需要審核或 required reviewers&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/artifact-handoff/" data-link-title="Artifact Handoff" data-link-desc="說明測試與部署如何共用同一份可追溯產物">Artifact handoff&lt;/a>&lt;/td>
 &lt;td>確保測試與發布使用同一份產物&lt;/td>
 &lt;td>test job 產生 artifact，deploy job 使用&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/required-checks/" data-link-title="Required Checks" data-link-desc="說明 pull request 的必要檢查如何作為合併 gate">Required checks&lt;/a> 適合保護主線。它讓測試結果成為合併條件，避免紅燈變更進入 &lt;code>main&lt;/code> 或 release branch（backend 延伸見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/ci-pipeline/" data-link-title="CI Pipeline" data-link-desc="說明持續整合流程如何在合併前驗證品質與相容性">CI Pipeline&lt;/a>）。&lt;/p>
&lt;p>Job &lt;code>needs&lt;/code> 適合同一條 workflow 內的發布管線。它讓 &lt;code>deploy&lt;/code> 必須等 &lt;code>test&lt;/code>、&lt;code>build&lt;/code> 或 &lt;code>package&lt;/code> 成功後才執行，避免 deploy job 先於驗證結果流動（platform 延伸見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/deployment-contract/" data-link-title="Deployment Contract" data-link-desc="說明服務與部署平台之間的生命週期約定">Deployment Contract&lt;/a>）。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/environment-protection/" data-link-title="Environment Protection" data-link-desc="說明目標環境的審核、權限與放行條件如何保護發布">Environment protection&lt;/a> 適合正式環境。即使 build 與測試通過，production 或其他目標環境仍可要求人工審核、特定分支或特定 reviewer 才能部署（治理延伸見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">Release Gate&lt;/a>）。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/artifact-handoff/" data-link-title="Artifact Handoff" data-link-desc="說明測試與部署如何共用同一份可追溯產物">Artifact handoff&lt;/a> 適合避免「測試一份、發布另一份」的漂移。較嚴謹的流程會讓 build job 產生 artifact，test job 驗證這份 artifact，deploy job 發布同一份 artifact（供應鏈延伸見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/artifact-provenance/" data-link-title="Artifact Provenance" data-link-desc="說明交付物的來源、完整性與簽章關聯如何建立信任">Artifact Provenance&lt;/a>）。&lt;/p>
&lt;h2 id="workflow-邊界">Workflow 邊界&lt;/h2>
&lt;p>Workflow 邊界的責任是決定哪些步驟共享同一條執行圖。放在同一條 workflow 裡的 job 可以用 &lt;code>needs&lt;/code> 建立顯式依賴；分散在不同 workflow 裡的流程，通常要靠 branch protection 或 environment protection 建立跨 workflow gate。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>結構&lt;/th>
 &lt;th>適合情境&lt;/th>
 &lt;th>常見風險&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>單一 workflow 多 job&lt;/td>
 &lt;td>test / build / deploy 緊密相依&lt;/td>
 &lt;td>YAML 變長，但依賴關係清楚&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>多 workflow&lt;/td>
 &lt;td>不同觸發條件或責任完全不同&lt;/td>
 &lt;td>跨 workflow gate 要靠 repo 設定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PR workflow + deploy&lt;/td>
 &lt;td>PR 驗證、main 發布分離&lt;/td>
 &lt;td>main push 若缺 required checks 會漏&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Artifact pipeline&lt;/td>
 &lt;td>同一份產物要被測試再發布&lt;/td>
 &lt;td>artifact 版本與權限要治理&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>多 workflow 的關鍵風險是順序假設。GitHub Actions 的 workflow 彼此獨立；跨 workflow 順序需要靠 repository 設定或 API 顯式串接。&lt;/p></description><content:encoded><![CDATA[<p>CI gate 的核心責任是把「是否進入下一階段」變成明確條件。測試、建置、發布與人工審核可以分成不同 workflow 或 job，但只要它們共同決定同一次發布，就需要有清楚的 gate 關係。</p>
<h2 id="gate-形式">Gate 形式</h2>
<p>Gate 形式要依控制範圍選擇。PR 合併、job 執行順序、production 發布與 artifact 傳遞是四種不同責任，混在一起會讓紅燈的意義變模糊。</p>
<table>
  <thead>
      <tr>
          <th>Gate 形式</th>
          <th>責任</th>
          <th>判讀方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/required-checks/" data-link-title="Required Checks" data-link-desc="說明 pull request 的必要檢查如何作為合併 gate">Required checks</a></td>
          <td>阻止未通過測試的 commit 合併</td>
          <td>PR 或 branch protection 顯示必須通過</td>
      </tr>
      <tr>
          <td>Job <code>needs</code></td>
          <td>讓 deploy 等 test / build</td>
          <td>同一 workflow 內 deploy 依賴前置 job</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/environment-protection/" data-link-title="Environment Protection" data-link-desc="說明目標環境的審核、權限與放行條件如何保護發布">Environment protection</a></td>
          <td>控制 production / target environment 發布</td>
          <td>部署環境需要審核或 required reviewers</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/artifact-handoff/" data-link-title="Artifact Handoff" data-link-desc="說明測試與部署如何共用同一份可追溯產物">Artifact handoff</a></td>
          <td>確保測試與發布使用同一份產物</td>
          <td>test job 產生 artifact，deploy job 使用</td>
      </tr>
  </tbody>
</table>
<p><a href="/blog/ci/knowledge-cards/required-checks/" data-link-title="Required Checks" data-link-desc="說明 pull request 的必要檢查如何作為合併 gate">Required checks</a> 適合保護主線。它讓測試結果成為合併條件，避免紅燈變更進入 <code>main</code> 或 release branch（backend 延伸見 <a href="/blog/backend/knowledge-cards/ci-pipeline/" data-link-title="CI Pipeline" data-link-desc="說明持續整合流程如何在合併前驗證品質與相容性">CI Pipeline</a>）。</p>
<p>Job <code>needs</code> 適合同一條 workflow 內的發布管線。它讓 <code>deploy</code> 必須等 <code>test</code>、<code>build</code> 或 <code>package</code> 成功後才執行，避免 deploy job 先於驗證結果流動（platform 延伸見 <a href="/blog/backend/knowledge-cards/deployment-contract/" data-link-title="Deployment Contract" data-link-desc="說明服務與部署平台之間的生命週期約定">Deployment Contract</a>）。</p>
<p><a href="/blog/ci/knowledge-cards/environment-protection/" data-link-title="Environment Protection" data-link-desc="說明目標環境的審核、權限與放行條件如何保護發布">Environment protection</a> 適合正式環境。即使 build 與測試通過，production 或其他目標環境仍可要求人工審核、特定分支或特定 reviewer 才能部署（治理延伸見 <a href="/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">Release Gate</a>）。</p>
<p><a href="/blog/ci/knowledge-cards/artifact-handoff/" data-link-title="Artifact Handoff" data-link-desc="說明測試與部署如何共用同一份可追溯產物">Artifact handoff</a> 適合避免「測試一份、發布另一份」的漂移。較嚴謹的流程會讓 build job 產生 artifact，test job 驗證這份 artifact，deploy job 發布同一份 artifact（供應鏈延伸見 <a href="/blog/backend/knowledge-cards/artifact-provenance/" data-link-title="Artifact Provenance" data-link-desc="說明交付物的來源、完整性與簽章關聯如何建立信任">Artifact Provenance</a>）。</p>
<h2 id="workflow-邊界">Workflow 邊界</h2>
<p>Workflow 邊界的責任是決定哪些步驟共享同一條執行圖。放在同一條 workflow 裡的 job 可以用 <code>needs</code> 建立顯式依賴；分散在不同 workflow 裡的流程，通常要靠 branch protection 或 environment protection 建立跨 workflow gate。</p>
<table>
  <thead>
      <tr>
          <th>結構</th>
          <th>適合情境</th>
          <th>常見風險</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>單一 workflow 多 job</td>
          <td>test / build / deploy 緊密相依</td>
          <td>YAML 變長，但依賴關係清楚</td>
      </tr>
      <tr>
          <td>多 workflow</td>
          <td>不同觸發條件或責任完全不同</td>
          <td>跨 workflow gate 要靠 repo 設定</td>
      </tr>
      <tr>
          <td>PR workflow + deploy</td>
          <td>PR 驗證、main 發布分離</td>
          <td>main push 若缺 required checks 會漏</td>
      </tr>
      <tr>
          <td>Artifact pipeline</td>
          <td>同一份產物要被測試再發布</td>
          <td>artifact 版本與權限要治理</td>
      </tr>
  </tbody>
</table>
<p>多 workflow 的關鍵風險是順序假設。GitHub Actions 的 workflow 彼此獨立；跨 workflow 順序需要靠 repository 設定或 API 顯式串接。</p>
<h2 id="發布阻擋判讀">發布阻擋判讀</h2>
<p>發布阻擋要同時看 YAML 與 GitHub repository 設定。YAML 說明 workflow 或 job 如何執行；跨 workflow 的「測試通過才發布」通常要靠 <a href="/blog/ci/knowledge-cards/branch-protection/" data-link-title="Branch Protection" data-link-desc="說明主線分支如何以規則保護合併與發布前置條件">Branch Protection</a>、required status checks 或 environment protection。</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>只看 YAML 能判斷嗎</th>
          <th>應檢查的位置</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>deploy 是否等 build</td>
          <td>可以</td>
          <td>同 workflow 的 <code>needs</code></td>
      </tr>
      <tr>
          <td>deploy 是否等另一條 test workflow</td>
          <td>通常要查設定</td>
          <td><a href="/blog/ci/knowledge-cards/branch-protection/" data-link-title="Branch Protection" data-link-desc="說明主線分支如何以規則保護合併與發布前置條件">Branch Protection</a> / <a href="/blog/ci/knowledge-cards/required-checks/" data-link-title="Required Checks" data-link-desc="說明 pull request 的必要檢查如何作為合併 gate">Required Checks</a></td>
      </tr>
      <tr>
          <td>PR 是否必須通過測試才能合併</td>
          <td>需要查 repo 設定</td>
          <td><a href="/blog/ci/knowledge-cards/branch-protection/" data-link-title="Branch Protection" data-link-desc="說明主線分支如何以規則保護合併與發布前置條件">Branch Protection</a></td>
      </tr>
      <tr>
          <td>目標環境是否需要人工審核</td>
          <td>需要查環境設定</td>
          <td>Environment protection</td>
      </tr>
      <tr>
          <td>測試與發布是否同一份 artifact</td>
          <td>可以部分判斷</td>
          <td>workflow artifact upload / download</td>
      </tr>
  </tbody>
</table>
<p>這個判讀順序能避免錯修。若測試紅燈但目標環境仍發布，問題通常在 deploy gate 尚未把測試狀態納入發布條件。</p>
<h2 id="常見反模式">常見反模式</h2>
<p>反模式的共同問題是讓 CI 綠燈與發布安全之間失去因果關係。CI 的目標是讓綠燈代表「這次變更在定義好的條件下可進下一階段」。</p>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>風險</th>
          <th>替代做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>deploy workflow 不等 test</td>
          <td>測試紅燈仍可能發布</td>
          <td>用 required checks 或 <code>needs</code></td>
      </tr>
      <tr>
          <td>CI 與本機命令不同</td>
          <td>本機通過但 CI 失敗</td>
          <td>把命令收斂到 Makefile / npm script</td>
      </tr>
      <tr>
          <td>測試與發布各自 build</td>
          <td>測試產物與發布產物漂移</td>
          <td>用 artifact handoff</td>
      </tr>
      <tr>
          <td>看到紅燈直接重跑</td>
          <td>掩蓋 flaky 或環境問題</td>
          <td>先看失敗 log，再決定是否重跑</td>
      </tr>
      <tr>
          <td>用 <code>--no-verify</code> 或跳過 CI</td>
          <td>把局部問題帶進主線</td>
          <td>修掉 gate 或明確記錄例外</td>
      </tr>
  </tbody>
</table>
<h2 id="tripwire">Tripwire</h2>
<p>Tripwire 的責任是提示什麼時候 workflow 結構需要重切，讓團隊從局部 patch 回到 gate 設計。</p>
<ul>
<li>測試紅燈仍發布：把 deploy gate 顯式化，使用 required checks 或同 workflow <code>needs</code>。</li>
<li>本機常常重現不出 CI：把命令收斂到 <code>Makefile</code> 或 <code>npm scripts</code>，減少 workflow 專屬命令。</li>
<li>測試常因 artifact 缺失失敗：建立 artifact handoff，讓測試與發布使用同一份產物。</li>
<li>workflow 說明與實作分叉：同步更新 workflow 文件與 YAML，讓維護入口保持可信。</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>CI 紅燈處理流程：讀 <a href="../github-actions-failure-flow/">CI 失敗到修復發布流程</a>。</li>
<li>靜態站部署案例：讀 <a href="../blog-project-deploy/">本 blog 專案部署</a>。</li>
<li>可靠性層的 release gate：讀 <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">6.8 Release Gate 與變更節奏</a>。</li>
</ul>
]]></content:encoded></item><item><title>6.24 規則推送安全閘門</title><link>https://tarrragon.github.io/blog/backend/06-reliability/rule-rollout-safety-gate/</link><pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/06-reliability/rule-rollout-safety-gate/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>規則推送安全閘門（rule rollout safety gate）的核心責任是防止控制面錯誤快速擴散到資料面。這個閘門是補上「規則與配置類變更」特有風險，跟既有 release gate 互補而非取代：變更體積小、覆蓋範圍大、擴散速度快。&lt;/p>
&lt;p>當變更屬於 WAF rule、routing policy、token/policy、或 Addressing API 相關設定時，判讀重點從程式碼正確性轉為擴散控制。這類變更即使 diff 很短，也可能在數十秒內影響跨區域流量與多產品控制面。&lt;/p>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>典型風險&lt;/th>
 &lt;th>為何需要獨立 gate&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>WAF / regex 規則更新&lt;/td>
 &lt;td>高計算成本規則拖垮 edge runtime&lt;/td>
 &lt;td>CI 綠燈無法代表 runtime 成本安全&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Routing / BYOIP 相關設定變更&lt;/td>
 &lt;td>prefix withdrawal 造成服務不可達&lt;/td>
 &lt;td>單一 API 查詢語意錯誤可全網擴散&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Token / policy 控制面變更&lt;/td>
 &lt;td>多產品授權連鎖失效&lt;/td>
 &lt;td>shared dependency 失效會誤導排障路徑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>共享控制面批次清理任務&lt;/td>
 &lt;td>批量誤刪或批量撤告&lt;/td>
 &lt;td>需要數量閘門與緊急停機機制&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="產業情境遊戲服務的規則推送安全">產業情境：遊戲服務的規則推送安全&lt;/h2>
&lt;p>遊戲的規則推送（平衡性調整、反作弊規則、賽季設定、經濟系統參數）有特殊的擴散特性：影響面是全體玩家、生效時機即時、且玩家行為會立刻適應規則變更。&lt;/p>
&lt;p>規則推送的 blast radius 預設是全體在線玩家。一次平衡性調整會立刻改變所有正在進行的比賽的角色強度、裝備數值或技能效果。跟一般 feature flag 的 percentage rollout 不同，遊戲平衡性需要所有玩家看到相同規則，否則同場比賽的公平性會被破壞。&lt;/p>
&lt;p>推送時機需要跟 match lifecycle 對齊。在進行中的比賽套用新規則會造成不公平 — 某隊在舊規則下建立的優勢可能在新規則下消失。安全做法是在 match boundary（比賽開始或結束時）切換，讓新規則只套用到新開始的比賽。這要求規則推送系統能區分「已開始的 match」和「即將開始的 match」。&lt;/p>
&lt;p>回退條件需要綁定遊戲特有的 KPI。active player count 下降超過門檻、match completion rate 異常降低（玩家中途離開）、player report rate 上升（玩家回報異常體驗）、in-game economy anomaly（虛擬貨幣或道具流通量異常）都是規則推送出問題的訊號。這些 KPI 的 feedback loop 比一般服務長 — 玩家行為的適應需要數小時到數天才會穩定，短窗觀察可能漏掉延遲暴露的問題。&lt;/p>
&lt;p>反作弊規則的推送有額外約束：規則內容本身是機密的，推送失敗後不能在 log 或 alert 中暴露規則細節，回退也必須在不洩漏偵測邏輯的前提下進行。&lt;/p>
&lt;h2 id="gate-檢查層">Gate 檢查層&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>層級&lt;/th>
 &lt;th>Gate 問題&lt;/th>
 &lt;th>不通過訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Query / API 語意&lt;/td>
 &lt;td>查詢參數有沒有安全預設與錯誤拒絕策略&lt;/td>
 &lt;td>空參數回傳全量、模糊布林語意&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rule 計算成本&lt;/td>
 &lt;td>規則是否通過代表性 payload 成本檢查&lt;/td>
 &lt;td>單一規則可造成 CPU 熱點&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推送策略&lt;/td>
 &lt;td>是否採分群 rollout 並設即時回退條件&lt;/td>
 &lt;td>一次推全域、無分區觀測閘門&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Withdrawal 限速&lt;/td>
 &lt;td>批次撤告 / 刪除是否有數量與速率限制&lt;/td>
 &lt;td>單次操作可影響大量 prefixes 或 bindings&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Shared dependency&lt;/td>
 &lt;td>是否識別跨產品共享控制點&lt;/td>
 &lt;td>多產品同時異常卻無 shared root 判讀&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Evidence 與回寫&lt;/td>
 &lt;td>事故後是否可回放決策、查證恢復路徑與狀態差異&lt;/td>
 &lt;td>決策只留結論，缺假設與驗證證據&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="判讀訊號">判讀訊號&lt;/h2>
&lt;ul>
&lt;li>控制面變更後，多區域同時出現 5xx / timeout / auth 失敗&lt;/li>
&lt;li>指標在秒級惡化，且與最新規則或 policy 變更高度同時&lt;/li>
&lt;li>回退後短時間明顯回穩，顯示變更與故障高度關聯&lt;/li>
&lt;li>部分服務可自助恢復、部分服務需人工修復，代表狀態損壞分層&lt;/li>
&lt;li>事故中出現「每個產品都在修自己的症狀」，代表 shared dependency 沒被先識別&lt;/li>
&lt;/ul>
&lt;h2 id="最低可執行-gate">最低可執行 Gate&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>變更分類&lt;/strong>：將規則/配置/控制面 API 變更標為 &lt;code>high-blast-radius change&lt;/code>。&lt;/li>
&lt;li>&lt;strong>語意檢查&lt;/strong>：對 query 參數、空值與預設行為做拒絕式驗證。&lt;/li>
&lt;li>&lt;strong>成本檢查&lt;/strong>：用代表性 payload 跑 rule-level CPU / latency 測試。&lt;/li>
&lt;li>&lt;strong>分批推送&lt;/strong>：至少分成小流量群組與全量兩階段，且每階段有回退條件。&lt;/li>
&lt;li>&lt;strong>撤告保護&lt;/strong>：對 withdrawal / delete 設速率與數量上限，超限自動中止。&lt;/li>
&lt;li>&lt;strong>決策紀錄&lt;/strong>：事故期間保留假設、證據、回退門檻、owner 與狀態差異。&lt;/li>
&lt;/ol>
&lt;h2 id="反模式">反模式&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>反模式&lt;/th>
 &lt;th>風險結果&lt;/th>
 &lt;th>修法&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>把規則推送當一般配置&lt;/td>
 &lt;td>低估擴散速度與影響面&lt;/td>
 &lt;td>強制走高風險變更 gate&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>只看 CI / lint&lt;/td>
 &lt;td>無法捕捉 runtime 計算成本風險&lt;/td>
 &lt;td>補 rule replay 與成本基線&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>全域一次推送&lt;/td>
 &lt;td>擴散太快，回退窗口太短&lt;/td>
 &lt;td>改 staged rollout + 即時回退閘門&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>事故後只寫事後摘要&lt;/td>
 &lt;td>無法復盤決策與恢復路徑&lt;/td>
 &lt;td>補 decision log + evidence package&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>未分離 desired/actual state&lt;/td>
 &lt;td>壞狀態難以回到已知穩定點&lt;/td>
 &lt;td>引入 snapshot 與 staged state restore&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="案例回扣">案例回扣&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/cases/cloudflare/2019-regex-cpu-outage/" data-link-title="Cloudflare 2019 Regex CPU Outage" data-link-desc="2019-07-02 Cloudflare WAF 規則更新導致全球 CPU 飆升的事故解析：觸發條件、擴散機制、止血決策與可回寫控制面。">Cloudflare 2019 Regex CPU Outage&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/cases/cloudflare/2023-control-plane-token-incident/" data-link-title="Cloudflare 2023 Control Plane Token Incident" data-link-desc="2023-01-24 Cloudflare service token 錯誤變更導致多產品連鎖影響的事故解析：信任邊界、擴散機制、止血策略與流程回寫。">Cloudflare 2023 Control Plane Token Incident&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/cases/cloudflare/2026-byoip-bgp-withdrawal/" data-link-title="Cloudflare 2026 BYOIP BGP Withdrawal" data-link-desc="2026-02-20 Cloudflare BYOIP prefixes 被非預期撤告的事故解析：Addressing API bug、BGP withdrawal、狀態恢復與控制面回寫。">Cloudflare 2026 BYOIP BGP Withdrawal&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>這三個案例對應同一個上位問題：控制面小變更如何在短時間擴散成全網事故。不同事故只是擴散路徑不同，gate 核心都是「先限制擴散、再修復功能」。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>規則推送安全閘門（rule rollout safety gate）的核心責任是防止控制面錯誤快速擴散到資料面。這個閘門是補上「規則與配置類變更」特有風險，跟既有 release gate 互補而非取代：變更體積小、覆蓋範圍大、擴散速度快。</p>
<p>當變更屬於 WAF rule、routing policy、token/policy、或 Addressing API 相關設定時，判讀重點從程式碼正確性轉為擴散控制。這類變更即使 diff 很短，也可能在數十秒內影響跨區域流量與多產品控制面。</p>
<h2 id="適用場景">適用場景</h2>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>典型風險</th>
          <th>為何需要獨立 gate</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>WAF / regex 規則更新</td>
          <td>高計算成本規則拖垮 edge runtime</td>
          <td>CI 綠燈無法代表 runtime 成本安全</td>
      </tr>
      <tr>
          <td>Routing / BYOIP 相關設定變更</td>
          <td>prefix withdrawal 造成服務不可達</td>
          <td>單一 API 查詢語意錯誤可全網擴散</td>
      </tr>
      <tr>
          <td>Token / policy 控制面變更</td>
          <td>多產品授權連鎖失效</td>
          <td>shared dependency 失效會誤導排障路徑</td>
      </tr>
      <tr>
          <td>共享控制面批次清理任務</td>
          <td>批量誤刪或批量撤告</td>
          <td>需要數量閘門與緊急停機機制</td>
      </tr>
  </tbody>
</table>
<h2 id="產業情境遊戲服務的規則推送安全">產業情境：遊戲服務的規則推送安全</h2>
<p>遊戲的規則推送（平衡性調整、反作弊規則、賽季設定、經濟系統參數）有特殊的擴散特性：影響面是全體玩家、生效時機即時、且玩家行為會立刻適應規則變更。</p>
<p>規則推送的 blast radius 預設是全體在線玩家。一次平衡性調整會立刻改變所有正在進行的比賽的角色強度、裝備數值或技能效果。跟一般 feature flag 的 percentage rollout 不同，遊戲平衡性需要所有玩家看到相同規則，否則同場比賽的公平性會被破壞。</p>
<p>推送時機需要跟 match lifecycle 對齊。在進行中的比賽套用新規則會造成不公平 — 某隊在舊規則下建立的優勢可能在新規則下消失。安全做法是在 match boundary（比賽開始或結束時）切換，讓新規則只套用到新開始的比賽。這要求規則推送系統能區分「已開始的 match」和「即將開始的 match」。</p>
<p>回退條件需要綁定遊戲特有的 KPI。active player count 下降超過門檻、match completion rate 異常降低（玩家中途離開）、player report rate 上升（玩家回報異常體驗）、in-game economy anomaly（虛擬貨幣或道具流通量異常）都是規則推送出問題的訊號。這些 KPI 的 feedback loop 比一般服務長 — 玩家行為的適應需要數小時到數天才會穩定，短窗觀察可能漏掉延遲暴露的問題。</p>
<p>反作弊規則的推送有額外約束：規則內容本身是機密的，推送失敗後不能在 log 或 alert 中暴露規則細節，回退也必須在不洩漏偵測邏輯的前提下進行。</p>
<h2 id="gate-檢查層">Gate 檢查層</h2>
<table>
  <thead>
      <tr>
          <th>層級</th>
          <th>Gate 問題</th>
          <th>不通過訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Query / API 語意</td>
          <td>查詢參數有沒有安全預設與錯誤拒絕策略</td>
          <td>空參數回傳全量、模糊布林語意</td>
      </tr>
      <tr>
          <td>Rule 計算成本</td>
          <td>規則是否通過代表性 payload 成本檢查</td>
          <td>單一規則可造成 CPU 熱點</td>
      </tr>
      <tr>
          <td>推送策略</td>
          <td>是否採分群 rollout 並設即時回退條件</td>
          <td>一次推全域、無分區觀測閘門</td>
      </tr>
      <tr>
          <td>Withdrawal 限速</td>
          <td>批次撤告 / 刪除是否有數量與速率限制</td>
          <td>單次操作可影響大量 prefixes 或 bindings</td>
      </tr>
      <tr>
          <td>Shared dependency</td>
          <td>是否識別跨產品共享控制點</td>
          <td>多產品同時異常卻無 shared root 判讀</td>
      </tr>
      <tr>
          <td>Evidence 與回寫</td>
          <td>事故後是否可回放決策、查證恢復路徑與狀態差異</td>
          <td>決策只留結論，缺假設與驗證證據</td>
      </tr>
  </tbody>
</table>
<h2 id="判讀訊號">判讀訊號</h2>
<ul>
<li>控制面變更後，多區域同時出現 5xx / timeout / auth 失敗</li>
<li>指標在秒級惡化，且與最新規則或 policy 變更高度同時</li>
<li>回退後短時間明顯回穩，顯示變更與故障高度關聯</li>
<li>部分服務可自助恢復、部分服務需人工修復，代表狀態損壞分層</li>
<li>事故中出現「每個產品都在修自己的症狀」，代表 shared dependency 沒被先識別</li>
</ul>
<h2 id="最低可執行-gate">最低可執行 Gate</h2>
<ol>
<li><strong>變更分類</strong>：將規則/配置/控制面 API 變更標為 <code>high-blast-radius change</code>。</li>
<li><strong>語意檢查</strong>：對 query 參數、空值與預設行為做拒絕式驗證。</li>
<li><strong>成本檢查</strong>：用代表性 payload 跑 rule-level CPU / latency 測試。</li>
<li><strong>分批推送</strong>：至少分成小流量群組與全量兩階段，且每階段有回退條件。</li>
<li><strong>撤告保護</strong>：對 withdrawal / delete 設速率與數量上限，超限自動中止。</li>
<li><strong>決策紀錄</strong>：事故期間保留假設、證據、回退門檻、owner 與狀態差異。</li>
</ol>
<h2 id="反模式">反模式</h2>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>風險結果</th>
          <th>修法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>把規則推送當一般配置</td>
          <td>低估擴散速度與影響面</td>
          <td>強制走高風險變更 gate</td>
      </tr>
      <tr>
          <td>只看 CI / lint</td>
          <td>無法捕捉 runtime 計算成本風險</td>
          <td>補 rule replay 與成本基線</td>
      </tr>
      <tr>
          <td>全域一次推送</td>
          <td>擴散太快，回退窗口太短</td>
          <td>改 staged rollout + 即時回退閘門</td>
      </tr>
      <tr>
          <td>事故後只寫事後摘要</td>
          <td>無法復盤決策與恢復路徑</td>
          <td>補 decision log + evidence package</td>
      </tr>
      <tr>
          <td>未分離 desired/actual state</td>
          <td>壞狀態難以回到已知穩定點</td>
          <td>引入 snapshot 與 staged state restore</td>
      </tr>
  </tbody>
</table>
<h2 id="案例回扣">案例回扣</h2>
<ul>
<li><a href="/blog/backend/08-incident-response/cases/cloudflare/2019-regex-cpu-outage/" data-link-title="Cloudflare 2019 Regex CPU Outage" data-link-desc="2019-07-02 Cloudflare WAF 規則更新導致全球 CPU 飆升的事故解析：觸發條件、擴散機制、止血決策與可回寫控制面。">Cloudflare 2019 Regex CPU Outage</a></li>
<li><a href="/blog/backend/08-incident-response/cases/cloudflare/2023-control-plane-token-incident/" data-link-title="Cloudflare 2023 Control Plane Token Incident" data-link-desc="2023-01-24 Cloudflare service token 錯誤變更導致多產品連鎖影響的事故解析：信任邊界、擴散機制、止血策略與流程回寫。">Cloudflare 2023 Control Plane Token Incident</a></li>
<li><a href="/blog/backend/08-incident-response/cases/cloudflare/2026-byoip-bgp-withdrawal/" data-link-title="Cloudflare 2026 BYOIP BGP Withdrawal" data-link-desc="2026-02-20 Cloudflare BYOIP prefixes 被非預期撤告的事故解析：Addressing API bug、BGP withdrawal、狀態恢復與控制面回寫。">Cloudflare 2026 BYOIP BGP Withdrawal</a></li>
</ul>
<p>這三個案例對應同一個上位問題：控制面小變更如何在短時間擴散成全網事故。不同事故只是擴散路徑不同，gate 核心都是「先限制擴散、再修復功能」。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li><code>04</code>： <a href="/blog/backend/04-observability/telemetry-data-quality/" data-link-title="4.17 Telemetry Data Quality" data-link-desc="把 missing signal、schema drift、sampling bias 與 timestamp skew 變成資料品質問題">4.17 Telemetry Data Quality</a></li>
<li><code>06</code>： <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">6.8 Release Gate</a></li>
<li><code>06</code>： <a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">6.20 Experiment Safety Boundary</a></li>
<li><code>06</code>： <a href="/blog/backend/06-reliability/verification-evidence-handoff/" data-link-title="6.23 Verification Evidence Handoff" data-link-desc="把 SLO、load、chaos、DR 與 readiness 結果包成 release / incident 可用證據">6.23 Verification Evidence Handoff</a></li>
<li><code>08</code>： <a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log</a></li>
<li><code>08</code>： <a href="/blog/backend/08-incident-response/incident-evidence-write-back/" data-link-title="8.22 Incident Evidence Write-back" data-link-desc="把事故證據、決策與復盤結論回寫到 observability、reliability 與 runbook">8.22 Incident Evidence Write-back</a></li>
</ul>
]]></content:encoded></item><item><title>6.25 Provider Dependency Release Gate 實作示範</title><link>https://tarrragon.github.io/blog/backend/06-reliability/provider-dependency-release-gate/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/06-reliability/provider-dependency-release-gate/</guid><description>&lt;p>Provider dependency release gate 的核心責任是把第三方依賴風險轉成可驗證放行條件，避免變更在高不確定性下直接擴散。&lt;/p>
&lt;h2 id="服務路徑與風險模型">服務路徑與風險模型&lt;/h2>
&lt;p>示範路徑是 checkout API 切換 payment provider timeout/retry 設定。這類變更看起來只改 config，但會直接影響交易成功率、延遲與重試風暴。&lt;/p>
&lt;p>gate 應固定五欄：&lt;code>Gate decision&lt;/code>、&lt;code>Checks&lt;/code>、&lt;code>Stop condition&lt;/code>、&lt;code>Rollback window&lt;/code>、&lt;code>Owner&lt;/code>。欄位先成立，再討論工具落地。&lt;/p>
&lt;p>以 payment provider timeout 調整為例，五欄的具體內容：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>欄位&lt;/th>
 &lt;th>範例值&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Gate decision&lt;/td>
 &lt;td>proceed / hold / rollback — 每批 canary 結束時做一次判定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Checks&lt;/td>
 &lt;td>checkout success rate &amp;gt; 99.5%、provider timeout ratio &amp;lt; 2%、duplicate charge = 0、error budget remaining &amp;gt; 30%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Stop condition&lt;/td>
 &lt;td>error rate 超門檻、latency p99 超過基線 2 倍、provider timeout ratio &amp;gt; 5%，任一觸發即停止擴批&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rollback window&lt;/td>
 &lt;td>15 min — config-only 變更無 schema 衝突，超過 15 min 後交易資料可能依賴新設定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Owner&lt;/td>
 &lt;td>checkout team lead，負責每批 go/no-go 與 rollback 決策&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Checks 欄位的數值來自歷史 baseline，每次變更前從 production 最近 7 天取值。baseline 偏移超過 10% 時，先校準再啟動 canary。&lt;/p>
&lt;h2 id="實作步驟">實作步驟&lt;/h2>
&lt;ol>
&lt;li>定義放行前檢查：checkout 成功率、provider timeout 比率、duplicate charge 監控、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">error budget&lt;/a> 餘量。&lt;/li>
&lt;li>設定 canary 節奏：1% -&amp;gt; 5% -&amp;gt; 25% -&amp;gt; 100%，每批觀察固定時間窗。&lt;/li>
&lt;li>為每批設定 stop condition：error rate、latency、provider timeout 任一超門檻即停止擴大。&lt;/li>
&lt;li>設定 rollback window：例如 15 分鐘內可無資料格式衝突地回退設定。&lt;/li>
&lt;li>把每批結果寫入 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/verification-evidence-handoff/" data-link-title="6.23 Verification Evidence Handoff" data-link-desc="把 SLO、load、chaos、DR 與 readiness 結果包成 release / incident 可用證據">6.23 Verification Evidence Handoff&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log&lt;/a>。&lt;/li>
&lt;/ol>
&lt;h3 id="canary-節奏與觀察窗">Canary 節奏與觀察窗&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>批次&lt;/th>
 &lt;th>流量比例&lt;/th>
 &lt;th>觀察窗&lt;/th>
 &lt;th>Go/no-go 判斷依據&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>B1&lt;/td>
 &lt;td>1%&lt;/td>
 &lt;td>30 min&lt;/td>
 &lt;td>checks 全過、stop condition 未觸發&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>B2&lt;/td>
 &lt;td>5%&lt;/td>
 &lt;td>1 h&lt;/td>
 &lt;td>B1 指標持平、無 duplicate charge、無客訴&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>B3&lt;/td>
 &lt;td>25%&lt;/td>
 &lt;td>2 h&lt;/td>
 &lt;td>B2 指標持平、error budget 消耗速度未加快&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>B4&lt;/td>
 &lt;td>100%&lt;/td>
 &lt;td>持續觀測&lt;/td>
 &lt;td>B3 指標持平、跨區結果一致，進入持續觀測而非一次性放行&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Payment 類變更的觀察窗比一般 config 變更長，原因有兩個。第一，交易確認有延遲 — provider 回傳 settlement 結果可能在數分鐘到數小時後，短觀察窗無法看到完整的交易結果分佈。第二，退款與爭議申請通常在交易後數小時甚至數天才出現，B3 階段需要持續追蹤退款率趨勢，確認新設定沒有引發 provider 層的異常判定。&lt;/p></description><content:encoded><![CDATA[<p>Provider dependency release gate 的核心責任是把第三方依賴風險轉成可驗證放行條件，避免變更在高不確定性下直接擴散。</p>
<h2 id="服務路徑與風險模型">服務路徑與風險模型</h2>
<p>示範路徑是 checkout API 切換 payment provider timeout/retry 設定。這類變更看起來只改 config，但會直接影響交易成功率、延遲與重試風暴。</p>
<p>gate 應固定五欄：<code>Gate decision</code>、<code>Checks</code>、<code>Stop condition</code>、<code>Rollback window</code>、<code>Owner</code>。欄位先成立，再討論工具落地。</p>
<p>以 payment provider timeout 調整為例，五欄的具體內容：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>範例值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gate decision</td>
          <td>proceed / hold / rollback — 每批 canary 結束時做一次判定</td>
      </tr>
      <tr>
          <td>Checks</td>
          <td>checkout success rate &gt; 99.5%、provider timeout ratio &lt; 2%、duplicate charge = 0、error budget remaining &gt; 30%</td>
      </tr>
      <tr>
          <td>Stop condition</td>
          <td>error rate 超門檻、latency p99 超過基線 2 倍、provider timeout ratio &gt; 5%，任一觸發即停止擴批</td>
      </tr>
      <tr>
          <td>Rollback window</td>
          <td>15 min — config-only 變更無 schema 衝突，超過 15 min 後交易資料可能依賴新設定</td>
      </tr>
      <tr>
          <td>Owner</td>
          <td>checkout team lead，負責每批 go/no-go 與 rollback 決策</td>
      </tr>
  </tbody>
</table>
<p>Checks 欄位的數值來自歷史 baseline，每次變更前從 production 最近 7 天取值。baseline 偏移超過 10% 時，先校準再啟動 canary。</p>
<h2 id="實作步驟">實作步驟</h2>
<ol>
<li>定義放行前檢查：checkout 成功率、provider timeout 比率、duplicate charge 監控、<a href="/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">error budget</a> 餘量。</li>
<li>設定 canary 節奏：1% -&gt; 5% -&gt; 25% -&gt; 100%，每批觀察固定時間窗。</li>
<li>為每批設定 stop condition：error rate、latency、provider timeout 任一超門檻即停止擴大。</li>
<li>設定 rollback window：例如 15 分鐘內可無資料格式衝突地回退設定。</li>
<li>把每批結果寫入 <a href="/blog/backend/06-reliability/verification-evidence-handoff/" data-link-title="6.23 Verification Evidence Handoff" data-link-desc="把 SLO、load、chaos、DR 與 readiness 結果包成 release / incident 可用證據">6.23 Verification Evidence Handoff</a> 與 <a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log</a>。</li>
</ol>
<h3 id="canary-節奏與觀察窗">Canary 節奏與觀察窗</h3>
<table>
  <thead>
      <tr>
          <th>批次</th>
          <th>流量比例</th>
          <th>觀察窗</th>
          <th>Go/no-go 判斷依據</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>B1</td>
          <td>1%</td>
          <td>30 min</td>
          <td>checks 全過、stop condition 未觸發</td>
      </tr>
      <tr>
          <td>B2</td>
          <td>5%</td>
          <td>1 h</td>
          <td>B1 指標持平、無 duplicate charge、無客訴</td>
      </tr>
      <tr>
          <td>B3</td>
          <td>25%</td>
          <td>2 h</td>
          <td>B2 指標持平、error budget 消耗速度未加快</td>
      </tr>
      <tr>
          <td>B4</td>
          <td>100%</td>
          <td>持續觀測</td>
          <td>B3 指標持平、跨區結果一致，進入持續觀測而非一次性放行</td>
      </tr>
  </tbody>
</table>
<p>Payment 類變更的觀察窗比一般 config 變更長，原因有兩個。第一，交易確認有延遲 — provider 回傳 settlement 結果可能在數分鐘到數小時後，短觀察窗無法看到完整的交易結果分佈。第二，退款與爭議申請通常在交易後數小時甚至數天才出現，B3 階段需要持續追蹤退款率趨勢，確認新設定沒有引發 provider 層的異常判定。</p>
<h3 id="證據留存格式">證據留存格式</h3>
<p>每批 canary 結束時留存一筆結構化證據，供 <a href="/blog/backend/06-reliability/verification-evidence-handoff/" data-link-title="6.23 Verification Evidence Handoff" data-link-desc="把 SLO、load、chaos、DR 與 readiness 結果包成 release / incident 可用證據">6.23</a> 與 <a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19</a> 調用。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>batch</td>
          <td>B1 / B2 / B3 / B4</td>
      </tr>
      <tr>
          <td>timestamp</td>
          <td>批次開始與結束時間</td>
      </tr>
      <tr>
          <td>traffic %</td>
          <td>該批實際流量比例</td>
      </tr>
      <tr>
          <td>metrics snapshot</td>
          <td>checkout success rate、latency p99、provider timeout ratio</td>
      </tr>
      <tr>
          <td>decision</td>
          <td>proceed / hold / rollback</td>
      </tr>
      <tr>
          <td>decider</td>
          <td>做出該決策的人與角色</td>
      </tr>
  </tbody>
</table>
<p>這個格式讓事故發生時，<a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log</a> 可以直接調用每批的 metrics 與決策紀錄，不需要回溯 dashboard 截圖。</p>
<h2 id="判讀訊號">判讀訊號</h2>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>判讀重點</th>
          <th>對應動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>canary 成功率正常但 timeout 升高</td>
          <td>交易完成但成本與延遲風險在累積</td>
          <td>暫停擴批，先調 provider timeout 策略</td>
      </tr>
      <tr>
          <td>error budget 快速消耗</td>
          <td>變更風險超過目前可承受範圍</td>
          <td>觸發 freeze，回到上一批設定</td>
      </tr>
      <tr>
          <td>rollback 成功但客訴仍上升</td>
          <td>影響可能來自非同步補償或下游延遲</td>
          <td>補 replay/對帳證據，再決定是否二次回退</td>
      </tr>
      <tr>
          <td>不同區域結果分歧</td>
          <td>provider 區域品質差異或路由策略不一致</td>
          <td>分區 gate，禁止全域同批放行</td>
      </tr>
      <tr>
          <td>告警只反映症狀無法定位變更關聯</td>
          <td>evidence 與 deploy event 沒對位</td>
          <td>補 deployment event link 與 owner 欄位</td>
      </tr>
  </tbody>
</table>
<h2 id="常見誤區">常見誤區</h2>
<p>把 gate 當成 CI 綠燈會漏掉依賴風險。依賴類變更需要觀測窗與停損條件，單靠測試通過不足以放行。</p>
<p>把 rollback window 寫成「可回退」但沒有時限也會失效。沒有時間邊界的回退通常意味著資料與行為已經漂移。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>這條路徑可用 <a href="/blog/backend/06-reliability/cases/stripe/idempotency-and-zero-downtime-migration/" data-link-title="Stripe：Idempotency 與零停機遷移的交易安全設計" data-link-desc="把 API 重試與資料遷移放在同一套安全模型，維持支付交易的一致結果。">Stripe Idempotency and Zero-downtime Migration</a> 回寫。先看交易正確性與變更節奏如何綁定，再回到本章對齊 gate 欄位與停損邏輯。</p>
<p>這個案例主要支撐的是「交易依賴變更放行節奏」判讀，不直接支撐 incident 通訊節奏；對外更新要回到 8.4。</p>
<h2 id="跨模組路由">跨模組路由</h2>
<ol>
<li>與 4.22 的交接：證據來源使用 <a href="/blog/backend/04-observability/checkout-api-evidence-package/" data-link-title="4.22 Checkout API Evidence Package 實作示範" data-link-desc="用 checkout 路徑示範 evidence package 如何交接給 release gate 與 incident decision。">Checkout API Evidence Package</a>。</li>
<li>與 6.8 的交接：策略與制度回到 <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">Release Gate 與變更節奏</a>。</li>
<li>與 6.23 的交接：每批驗證證據進 <a href="/blog/backend/06-reliability/verification-evidence-handoff/" data-link-title="6.23 Verification Evidence Handoff" data-link-desc="把 SLO、load、chaos、DR 與 readiness 結果包成 release / incident 可用證據">Verification Evidence Handoff</a>。</li>
<li>與 8.19 的交接：停損與回退決策同步到 incident decision log。</li>
</ol>
<h2 id="下一步路由">下一步路由</h2>
<p>要看控制面事故如何用 decision log 與 write-back 關閉迴圈，接著讀 <a href="/blog/backend/08-incident-response/control-plane-decision-log-write-back/" data-link-title="8.23 Control Plane Decision Log and Write-back 實作示範" data-link-desc="以 rule/config rollout 事故示範 decision log 與 write-back 如何形成可回放閉環。">8.23 Control Plane Decision Log and Write-back 實作示範</a>。</p>
]]></content:encoded></item><item><title>Gate Decision</title><link>https://tarrragon.github.io/blog/backend/knowledge-cards/gate-decision/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/knowledge-cards/gate-decision/</guid><description>&lt;p>Gate decision 的核心概念是「release gate 根據證據做出的明確下一步」。它連接 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/evidence-package/" data-link-title="Evidence Package" data-link-desc="說明觀測、驗證與事故流程如何把證據包成可交接、可回放的 artifact">evidence package&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/stop-condition/" data-link-title="Stop Condition" data-link-desc="說明變更、實驗或事故處理何時必須暫停、回退或改路線">stop condition&lt;/a>，讓 gate 不只寫檢查結果，也寫出能不能前進。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Gate decision 位在 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/confidence/" data-link-title="Confidence" data-link-desc="說明證據包如何標示 confirmed、suspected 或 needs follow-up 的判讀信心">confidence&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rollback-window/" data-link-title="Rollback Window" data-link-desc="說明變更進入 production 後還能用哪種方式回退或改路線的時間與條件">rollback window&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/incident-decision-log/" data-link-title="Incident Decision Log" data-link-desc="說明事故期間如何保留決策、證據、owner 與回退條件">incident decision log&lt;/a> 之間。Checks 描述檢查結果，gate decision 把結果轉成放行、暫停、回退、fail-forward 或補證據。&lt;/p>
&lt;h2 id="可觀察訊號">可觀察訊號&lt;/h2>
&lt;p>系統需要 gate decision 的訊號是：&lt;/p>
&lt;ul>
&lt;li>CI、SLO、validation query 都有結果，但沒人知道下一步&lt;/li>
&lt;li>evidence 足以支持部分放行，但不足以支持完整 cutover&lt;/li>
&lt;li>變更需要逐批 rollout、backfill、warmup 或 replay&lt;/li>
&lt;li>gate 要保留 owner 與 rollback window&lt;/li>
&lt;/ul>
&lt;h2 id="接近真實網路服務的例子">接近真實網路服務的例子&lt;/h2>
&lt;p>資料庫 migration 的 gate decision 可以寫成 &lt;code>allow next 10% backfill; block customer-visible read cutover&lt;/code>。這句話比 &lt;code>migration pass&lt;/code> 更可操作，因為它同時說明允許前進的範圍與被擋住的風險面。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Gate decision 要包含決策內容、支撐 checks、stop condition、rollback window 與 owner。它要能被 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/incident-decision-log/" data-link-title="Incident Decision Log" data-link-desc="說明事故期間如何保留決策、證據、owner 與回退條件">incident decision log&lt;/a> 承接，讓放行後出現異常時能回放當時依據。&lt;/p></description><content:encoded><![CDATA[<p>Gate decision 的核心概念是「release gate 根據證據做出的明確下一步」。它連接 <a href="/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate</a>、<a href="/blog/backend/knowledge-cards/evidence-package/" data-link-title="Evidence Package" data-link-desc="說明觀測、驗證與事故流程如何把證據包成可交接、可回放的 artifact">evidence package</a> 與 <a href="/blog/backend/knowledge-cards/stop-condition/" data-link-title="Stop Condition" data-link-desc="說明變更、實驗或事故處理何時必須暫停、回退或改路線">stop condition</a>，讓 gate 不只寫檢查結果，也寫出能不能前進。</p>
<h2 id="概念位置">概念位置</h2>
<p>Gate decision 位在 <a href="/blog/backend/knowledge-cards/confidence/" data-link-title="Confidence" data-link-desc="說明證據包如何標示 confirmed、suspected 或 needs follow-up 的判讀信心">confidence</a>、<a href="/blog/backend/knowledge-cards/rollback-window/" data-link-title="Rollback Window" data-link-desc="說明變更進入 production 後還能用哪種方式回退或改路線的時間與條件">rollback window</a> 與 <a href="/blog/backend/knowledge-cards/incident-decision-log/" data-link-title="Incident Decision Log" data-link-desc="說明事故期間如何保留決策、證據、owner 與回退條件">incident decision log</a> 之間。Checks 描述檢查結果，gate decision 把結果轉成放行、暫停、回退、fail-forward 或補證據。</p>
<h2 id="可觀察訊號">可觀察訊號</h2>
<p>系統需要 gate decision 的訊號是：</p>
<ul>
<li>CI、SLO、validation query 都有結果，但沒人知道下一步</li>
<li>evidence 足以支持部分放行，但不足以支持完整 cutover</li>
<li>變更需要逐批 rollout、backfill、warmup 或 replay</li>
<li>gate 要保留 owner 與 rollback window</li>
</ul>
<h2 id="接近真實網路服務的例子">接近真實網路服務的例子</h2>
<p>資料庫 migration 的 gate decision 可以寫成 <code>allow next 10% backfill; block customer-visible read cutover</code>。這句話比 <code>migration pass</code> 更可操作，因為它同時說明允許前進的範圍與被擋住的風險面。</p>
<h2 id="設計責任">設計責任</h2>
<p>Gate decision 要包含決策內容、支撐 checks、stop condition、rollback window 與 owner。它要能被 <a href="/blog/backend/knowledge-cards/incident-decision-log/" data-link-title="Incident Decision Log" data-link-desc="說明事故期間如何保留決策、證據、owner 與回退條件">incident decision log</a> 承接，讓放行後出現異常時能回放當時依據。</p>
]]></content:encoded></item><item><title>Release Gate</title><link>https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/</guid><description>&lt;p>Release Gate 的核心概念是「在變更進入正式環境前，用明確條件決定能不能放行」。 可先對照 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rollback-rehearsal/" data-link-title="Rollback Rehearsal" data-link-desc="說明如何在正式事故前演練回滾流程">Rollback Rehearsal&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Release Gate 位在 migration、schema change、deployment、error budget 與 incident policy 之間。它把驗證結果轉成可執行的放行決策，並常搭配 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rollback-rehearsal/" data-link-title="Rollback Rehearsal" data-link-desc="說明如何在正式事故前演練回滾流程">Rollback Rehearsal&lt;/a> 確認放行前後都能回復。&lt;/p>
&lt;h2 id="可觀察訊號">可觀察訊號&lt;/h2>
&lt;p>系統需要 release gate 的訊號是：&lt;/p>
&lt;ul>
&lt;li>變更會影響使用者可用性或資料正確性&lt;/li>
&lt;li>新舊版本會並存一段時間&lt;/li>
&lt;li>團隊需要在 release 前確認檢查項都過關&lt;/li>
&lt;li>發版失敗時要有明確阻擋條件&lt;/li>
&lt;/ul>
&lt;h2 id="接近真實網路服務的例子">接近真實網路服務的例子&lt;/h2>
&lt;p>Schema migration 要先確認相容性與 backfill 結果再放行；高風險設定變更要通過 security review 與 drift check；error budget 快耗盡時，團隊可以暫停高風險變更，直到風險恢復到可接受範圍。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Release Gate 要定義檢查項、擁有者、通過條件、阻擋條件與例外流程。它是把風險控制流程標準化的機制，單純的批准按鈕無法達到同等效果。&lt;/p></description><content:encoded><![CDATA[<p>Release Gate 的核心概念是「在變更進入正式環境前，用明確條件決定能不能放行」。 可先對照 <a href="/blog/backend/knowledge-cards/rollback-rehearsal/" data-link-title="Rollback Rehearsal" data-link-desc="說明如何在正式事故前演練回滾流程">Rollback Rehearsal</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>Release Gate 位在 migration、schema change、deployment、error budget 與 incident policy 之間。它把驗證結果轉成可執行的放行決策，並常搭配 <a href="/blog/backend/knowledge-cards/rollback-rehearsal/" data-link-title="Rollback Rehearsal" data-link-desc="說明如何在正式事故前演練回滾流程">Rollback Rehearsal</a> 確認放行前後都能回復。</p>
<h2 id="可觀察訊號">可觀察訊號</h2>
<p>系統需要 release gate 的訊號是：</p>
<ul>
<li>變更會影響使用者可用性或資料正確性</li>
<li>新舊版本會並存一段時間</li>
<li>團隊需要在 release 前確認檢查項都過關</li>
<li>發版失敗時要有明確阻擋條件</li>
</ul>
<h2 id="接近真實網路服務的例子">接近真實網路服務的例子</h2>
<p>Schema migration 要先確認相容性與 backfill 結果再放行；高風險設定變更要通過 security review 與 drift check；error budget 快耗盡時，團隊可以暫停高風險變更，直到風險恢復到可接受範圍。</p>
<h2 id="設計責任">設計責任</h2>
<p>Release Gate 要定義檢查項、擁有者、通過條件、阻擋條件與例外流程。它是把風險控制流程標準化的機制，單純的批准按鈕無法達到同等效果。</p>
]]></content:encoded></item><item><title>7.R11.P16 產物缺少來源證據</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/problem-cards/fp-artifact-without-provenance/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/problem-cards/fp-artifact-without-provenance/</guid><description>&lt;p>這個失效樣式的核心問題是部署產物與來源提交無法完整對應。當 artifact 缺少 provenance 證據，污染產物會更容易穿越 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate&lt;/a>。&lt;/p>
&lt;h2 id="常見形成條件">常見形成條件&lt;/h2>
&lt;ul>
&lt;li>build metadata 與來源提交缺少可回查關聯。&lt;/li>
&lt;li>產物簽署驗證未納入 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate&lt;/a>。&lt;/li>
&lt;li>供應鏈事件後缺少受影響 artifact 快速盤點機制。&lt;/li>
&lt;/ul>
&lt;h2 id="判讀訊號">判讀訊號&lt;/h2>
&lt;ul>
&lt;li>同版本 artifact 的來源紀錄不一致或不可追溯。&lt;/li>
&lt;li>發佈關卡通過但缺少簽署驗證證據。&lt;/li>
&lt;li>事件發生後無法快速定位受影響部署批次，導致 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/impact-scope/" data-link-title="Impact Scope" data-link-desc="說明事故中如何盤點受影響範圍，支持通報、回復與責任判讀">impact scope&lt;/a> 判讀延後。&lt;/li>
&lt;/ul>
&lt;h2 id="案例觸發參考">案例觸發參考&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/cases/supply-chain/solarwinds-2020-sunburst/" data-link-title="7.R7.2.1 SolarWinds 2020：更新鏈被濫用" data-link-desc="合法更新流程遭植入後，攻擊者如何長期潛伏與橫向擴散">SolarWinds 2020&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/cases/supply-chain/3cx-2023-desktopapp-supply-chain/" data-link-title="7.R7.2.8 3CX 2023：桌面軟體更新鏈攻擊" data-link-desc="合法更新流程被植入後，桌面端供應鏈事件如何傳到企業端點">3CX 2023&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/cases/supply-chain/xz-backdoor-2024-open-source-supply-chain/" data-link-title="7.R7.2.4 XZ Backdoor 2024：開源供應鏈長期滲透" data-link-desc="開源維護鏈遭滲透後，為何會直接影響廣泛 Linux 發行流程">XZ 2024&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="來源主題章節">來源主題章節&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/supply-chain-integrity-and-artifact-trust/" data-link-title="7.12 供應鏈完整性與 Artifact 信任" data-link-desc="定義 build provenance、artifact 信任與交付鏈風險問題">7.12 供應鏈完整性與 Artifact 信任&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/red-team/control-failure-patterns/" data-link-title="7.R8 控制面失效樣式" data-link-desc="把常見攻擊結果回推成控制面失效樣式">7.R8 控制面失效樣式&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>本失效樣式對應的實作 chain：&lt;/p>
&lt;p>&lt;strong>控制面（mitigation 在這裡定義）&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>演練 / 控制落地（轉成欄位）&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/blue-team/materials/control-patterns/vulnerability-response-pattern/" data-link-title="Vulnerability Response Pattern" data-link-desc="定義漏洞回應如何從 observed 推進到 assessed、mitigated、patched、validated 與 closed">Vulnerability response pattern&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/blue-team/materials/control-patterns/evidence-chain-pattern/" data-link-title="Evidence Chain Pattern" data-link-desc="定義事故與演練需要保存的訊號、決策、artifact、timeline 與 retention 證據">Evidence chain pattern&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個失效樣式的核心問題是部署產物與來源提交無法完整對應。當 artifact 缺少 provenance 證據，污染產物會更容易穿越 <a href="/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate</a>。</p>
<h2 id="常見形成條件">常見形成條件</h2>
<ul>
<li>build metadata 與來源提交缺少可回查關聯。</li>
<li>產物簽署驗證未納入 <a href="/blog/backend/knowledge-cards/release-gate/" data-link-title="Release Gate" data-link-desc="說明變更在正式釋出前如何通過或阻擋">release gate</a>。</li>
<li>供應鏈事件後缺少受影響 artifact 快速盤點機制。</li>
</ul>
<h2 id="判讀訊號">判讀訊號</h2>
<ul>
<li>同版本 artifact 的來源紀錄不一致或不可追溯。</li>
<li>發佈關卡通過但缺少簽署驗證證據。</li>
<li>事件發生後無法快速定位受影響部署批次，導致 <a href="/blog/backend/knowledge-cards/impact-scope/" data-link-title="Impact Scope" data-link-desc="說明事故中如何盤點受影響範圍，支持通報、回復與責任判讀">impact scope</a> 判讀延後。</li>
</ul>
<h2 id="案例觸發參考">案例觸發參考</h2>
<ul>
<li><a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/solarwinds-2020-sunburst/" data-link-title="7.R7.2.1 SolarWinds 2020：更新鏈被濫用" data-link-desc="合法更新流程遭植入後，攻擊者如何長期潛伏與橫向擴散">SolarWinds 2020</a></li>
<li><a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/3cx-2023-desktopapp-supply-chain/" data-link-title="7.R7.2.8 3CX 2023：桌面軟體更新鏈攻擊" data-link-desc="合法更新流程被植入後，桌面端供應鏈事件如何傳到企業端點">3CX 2023</a></li>
<li><a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/xz-backdoor-2024-open-source-supply-chain/" data-link-title="7.R7.2.4 XZ Backdoor 2024：開源供應鏈長期滲透" data-link-desc="開源維護鏈遭滲透後，為何會直接影響廣泛 Linux 發行流程">XZ 2024</a></li>
</ul>
<h2 id="來源主題章節">來源主題章節</h2>
<ul>
<li><a href="/blog/backend/07-security-data-protection/supply-chain-integrity-and-artifact-trust/" data-link-title="7.12 供應鏈完整性與 Artifact 信任" data-link-desc="定義 build provenance、artifact 信任與交付鏈風險問題">7.12 供應鏈完整性與 Artifact 信任</a></li>
<li><a href="/blog/backend/07-security-data-protection/red-team/control-failure-patterns/" data-link-title="7.R8 控制面失效樣式" data-link-desc="把常見攻擊結果回推成控制面失效樣式">7.R8 控制面失效樣式</a></li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<p>本失效樣式對應的實作 chain：</p>
<p><strong>控制面（mitigation 在這裡定義）</strong>：</p>
<ul>
<li><a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a></li>
</ul>
<p><strong>演練 / 控制落地（轉成欄位）</strong>：</p>
<ul>
<li><a href="/blog/backend/07-security-data-protection/blue-team/materials/control-patterns/vulnerability-response-pattern/" data-link-title="Vulnerability Response Pattern" data-link-desc="定義漏洞回應如何從 observed 推進到 assessed、mitigated、patched、validated 與 closed">Vulnerability response pattern</a></li>
<li><a href="/blog/backend/07-security-data-protection/blue-team/materials/control-patterns/evidence-chain-pattern/" data-link-title="Evidence Chain Pattern" data-link-desc="定義事故與演練需要保存的訊號、決策、artifact、timeline 與 retention 證據">Evidence chain pattern</a></li>
</ul>
]]></content:encoded></item><item><title>7.22 資安風險如何進入 Release Gate</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/security-risk-in-release-gate/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/security-risk-in-release-gate/</guid><description>&lt;p>本篇的責任是把資安風險接到 release gate。讀者讀完後，能把控制驗證、例外條件與風險判讀轉成放行判準。&lt;/p>
&lt;h2 id="核心論點">核心論點&lt;/h2>
&lt;p>資安進入 release gate 的核心概念是讓放行決策可回查。放行條件一旦包含風險與證據，變更速度與風險控制可以共同優化。&lt;/p>
&lt;h2 id="gate-欄位">Gate 欄位&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>欄位&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>產出&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Risk classification&lt;/td>
 &lt;td>定義變更風險等級&lt;/td>
 &lt;td>risk label&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Required controls&lt;/td>
 &lt;td>定義必備控制驗證&lt;/td>
 &lt;td>control checklist&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Evidence bundle&lt;/td>
 &lt;td>定義放行證據集合&lt;/td>
 &lt;td>evidence package&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Exception window&lt;/td>
 &lt;td>定義例外期間與補償措施&lt;/td>
 &lt;td>exception record&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Decision owner&lt;/td>
 &lt;td>定義放行決策責任&lt;/td>
 &lt;td>approval route&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Re-evaluation trigger&lt;/td>
 &lt;td>定義重評估條件&lt;/td>
 &lt;td>tripwire link&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="高風險變更流程">高風險變更流程&lt;/h2>
&lt;p>高風險變更流程的責任是讓放行有階段節奏。流程可分成預檢、驗證、審查、放行、回寫五步，並固定記錄風險假設與驗證結果。&lt;/p>
&lt;h2 id="例外治理">例外治理&lt;/h2>
&lt;p>例外治理的責任是讓例外成為受控狀態。例外紀錄至少包含期限、補償控制、回收條件與 owner，並接到 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/tripwire/" data-link-title="Tripwire" data-link-desc="說明風險決策在條件變化時如何自動回到評估流程">tripwire&lt;/a>。&lt;/p>
&lt;h2 id="與部署與可靠性交接">與部署與可靠性交接&lt;/h2>
&lt;p>與部署與可靠性交接的責任是把 gate 決策接到執行層。放行結果可直接交接到部署流程、回退策略與 incident readiness。&lt;/p>
&lt;h2 id="判讀訊號與路由">判讀訊號與路由&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>判讀訊號&lt;/th>
 &lt;th>代表需求&lt;/th>
 &lt;th>下一步路由&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>發版條件只看功能測試&lt;/td>
 &lt;td>需要補資安證據欄位&lt;/td>
 &lt;td>7.22 → 7.B3&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>例外到期後仍持續放行&lt;/td>
 &lt;td>需要補 re-evaluation trigger&lt;/td>
 &lt;td>7.22 → 7.14&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>高風險變更缺少 owner 決策&lt;/td>
 &lt;td>需要補 decision owner&lt;/td>
 &lt;td>7.22 → 05&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>放行後事故率上升&lt;/td>
 &lt;td>需要補 gate 迭代回寫&lt;/td>
 &lt;td>7.22 → 7.24&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="從-gate-通過到-control-實際驗證">從 Gate 通過到 control 實際驗證&lt;/h2>
&lt;p>Gate 通過代表流程跑完（risk classification + controls + evidence + exception 全填）；control 是否真在生產驗過、要靠兩條 chain：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Evidence chain&lt;/strong>：evidence package 列的證據要對應到 control 實際 mechanism、不只填欄位。例：「TLS 已啟用」要附 cipher suite + cert valid + HSTS preload 證據、不只 prod 連得上 https。Mechanism 細節見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">7.5 傳輸信任&lt;/a> 跟對應 knowledge-card。&lt;/li>
&lt;li>&lt;strong>Re-evaluation chain&lt;/strong>：tripwire 觸發 / 例外到期 / 事件 trigger 接到 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/security-governance-exception-and-tripwire/" data-link-title="7.14 資安治理例外與 Tripwire" data-link-desc="定義例外管理、風險接受與重新評估觸發器">7.14 例外治理&lt;/a> 跟 7.x 主章節再評估。&lt;/li>
&lt;/ul>
&lt;p>Gate 通過 + 兩條 chain 跑通、放行才是 risk reduce 決策。Gate 跟 control 是流程層 vs 實作層、由 evidence 內容對應。&lt;/p>
&lt;h2 id="必連章節">必連章節&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/security-governance-exception-and-tripwire/" data-link-title="7.14 資安治理例外與 Tripwire" data-link-desc="定義例外管理、風險接受與重新評估觸發器">7.14 資安治理例外與 Tripwire&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/blue-team/security-control-validation/" data-link-title="7.B3 資安控制驗證" data-link-desc="建立資安控制面如何用證據、演練與 release gate 驗證的大綱">7.B3 資安控制驗證&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/security-control-handoff-to-delivery-and-incident/" data-link-title="7.18 資安控制面如何交接到部署與事故流程" data-link-desc="建立資安控制面交接到部署、可靠性與事故流程的大綱">7.18 資安控制面如何交接到部署與事故流程&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/security-and-reliability-shared-controls/" data-link-title="7.23 資安與可靠性的共同控制面" data-link-desc="建立資安與可靠性共同控制面的交集，整合 rollback、containment、degradation 與 evidence">7.23 資安與可靠性的共同控制面&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="完稿判準">完稿判準&lt;/h2>
&lt;p>完稿時要讓讀者能為高風險變更建立資安 gate。輸出至少包含風險等級、控制驗證、證據包、例外條件與重評估觸發器。&lt;/p></description><content:encoded><![CDATA[<p>本篇的責任是把資安風險接到 release gate。讀者讀完後，能把控制驗證、例外條件與風險判讀轉成放行判準。</p>
<h2 id="核心論點">核心論點</h2>
<p>資安進入 release gate 的核心概念是讓放行決策可回查。放行條件一旦包含風險與證據，變更速度與風險控制可以共同優化。</p>
<h2 id="gate-欄位">Gate 欄位</h2>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>責任</th>
          <th>產出</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Risk classification</td>
          <td>定義變更風險等級</td>
          <td>risk label</td>
      </tr>
      <tr>
          <td>Required controls</td>
          <td>定義必備控制驗證</td>
          <td>control checklist</td>
      </tr>
      <tr>
          <td>Evidence bundle</td>
          <td>定義放行證據集合</td>
          <td>evidence package</td>
      </tr>
      <tr>
          <td>Exception window</td>
          <td>定義例外期間與補償措施</td>
          <td>exception record</td>
      </tr>
      <tr>
          <td>Decision owner</td>
          <td>定義放行決策責任</td>
          <td>approval route</td>
      </tr>
      <tr>
          <td>Re-evaluation trigger</td>
          <td>定義重評估條件</td>
          <td>tripwire link</td>
      </tr>
  </tbody>
</table>
<h2 id="高風險變更流程">高風險變更流程</h2>
<p>高風險變更流程的責任是讓放行有階段節奏。流程可分成預檢、驗證、審查、放行、回寫五步，並固定記錄風險假設與驗證結果。</p>
<h2 id="例外治理">例外治理</h2>
<p>例外治理的責任是讓例外成為受控狀態。例外紀錄至少包含期限、補償控制、回收條件與 owner，並接到 <a href="/blog/backend/knowledge-cards/tripwire/" data-link-title="Tripwire" data-link-desc="說明風險決策在條件變化時如何自動回到評估流程">tripwire</a>。</p>
<h2 id="與部署與可靠性交接">與部署與可靠性交接</h2>
<p>與部署與可靠性交接的責任是把 gate 決策接到執行層。放行結果可直接交接到部署流程、回退策略與 incident readiness。</p>
<h2 id="判讀訊號與路由">判讀訊號與路由</h2>
<table>
  <thead>
      <tr>
          <th>判讀訊號</th>
          <th>代表需求</th>
          <th>下一步路由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>發版條件只看功能測試</td>
          <td>需要補資安證據欄位</td>
          <td>7.22 → 7.B3</td>
      </tr>
      <tr>
          <td>例外到期後仍持續放行</td>
          <td>需要補 re-evaluation trigger</td>
          <td>7.22 → 7.14</td>
      </tr>
      <tr>
          <td>高風險變更缺少 owner 決策</td>
          <td>需要補 decision owner</td>
          <td>7.22 → 05</td>
      </tr>
      <tr>
          <td>放行後事故率上升</td>
          <td>需要補 gate 迭代回寫</td>
          <td>7.22 → 7.24</td>
      </tr>
  </tbody>
</table>
<h2 id="從-gate-通過到-control-實際驗證">從 Gate 通過到 control 實際驗證</h2>
<p>Gate 通過代表流程跑完（risk classification + controls + evidence + exception 全填）；control 是否真在生產驗過、要靠兩條 chain：</p>
<ul>
<li><strong>Evidence chain</strong>：evidence package 列的證據要對應到 control 實際 mechanism、不只填欄位。例：「TLS 已啟用」要附 cipher suite + cert valid + HSTS preload 證據、不只 prod 連得上 https。Mechanism 細節見 <a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">7.5 傳輸信任</a> 跟對應 knowledge-card。</li>
<li><strong>Re-evaluation chain</strong>：tripwire 觸發 / 例外到期 / 事件 trigger 接到 <a href="/blog/backend/07-security-data-protection/security-governance-exception-and-tripwire/" data-link-title="7.14 資安治理例外與 Tripwire" data-link-desc="定義例外管理、風險接受與重新評估觸發器">7.14 例外治理</a> 跟 7.x 主章節再評估。</li>
</ul>
<p>Gate 通過 + 兩條 chain 跑通、放行才是 risk reduce 決策。Gate 跟 control 是流程層 vs 實作層、由 evidence 內容對應。</p>
<h2 id="必連章節">必連章節</h2>
<ul>
<li><a href="/blog/backend/07-security-data-protection/security-governance-exception-and-tripwire/" data-link-title="7.14 資安治理例外與 Tripwire" data-link-desc="定義例外管理、風險接受與重新評估觸發器">7.14 資安治理例外與 Tripwire</a></li>
<li><a href="/blog/backend/07-security-data-protection/blue-team/security-control-validation/" data-link-title="7.B3 資安控制驗證" data-link-desc="建立資安控制面如何用證據、演練與 release gate 驗證的大綱">7.B3 資安控制驗證</a></li>
<li><a href="/blog/backend/07-security-data-protection/security-control-handoff-to-delivery-and-incident/" data-link-title="7.18 資安控制面如何交接到部署與事故流程" data-link-desc="建立資安控制面交接到部署、可靠性與事故流程的大綱">7.18 資安控制面如何交接到部署與事故流程</a></li>
<li><a href="/blog/backend/07-security-data-protection/security-and-reliability-shared-controls/" data-link-title="7.23 資安與可靠性的共同控制面" data-link-desc="建立資安與可靠性共同控制面的交集，整合 rollback、containment、degradation 與 evidence">7.23 資安與可靠性的共同控制面</a></li>
</ul>
<h2 id="完稿判準">完稿判準</h2>
<p>完稿時要讓讀者能為高風險變更建立資安 gate。輸出至少包含風險等級、控制驗證、證據包、例外條件與重評估觸發器。</p>
]]></content:encoded></item></channel></rss>