<?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>Privacy on Tarragon</title><link>https://tarrragon.github.io/blog/tags/privacy/</link><description>Recent content in Privacy on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/privacy/index.xml" rel="self" type="application/rss+xml"/><item><title>SDK Redaction API 設計</title><link>https://tarrragon.github.io/blog/monitoring/07-security-privacy/sdk-redaction-api/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/07-security-privacy/sdk-redaction-api/</guid><description>&lt;p>Redaction 是在事件資料離開 client 之前，把敏感欄位的值替換成遮罩或移除。本章聚焦 redaction 的策略面 — 哪些資訊需要保護、保護的判斷依據和適用範圍。SDK 的 API 實作細節（初始化方式、helper 函式設計、和 flush 管線的整合）見 &lt;a href="https://tarrragon.github.io/blog/monitoring/03-sdk-design/redaction-helper/" data-link-title="SDK redaction helper" data-link-desc="在事件離開 SDK 前移除敏感資訊 — 預設 redaction rule 處理常見 pattern，自訂 rule 處理業務特定的 secret">SDK redaction helper&lt;/a>。Redaction 在 SDK 端執行的設計原則是「敏感資料不離開 client」— 一旦資料送到 collector，即使 collector 有 access control，資料已經在網路上傳輸過，多了一層洩漏面。&lt;/p>
&lt;h2 id="預設-redaction-rule">預設 Redaction Rule&lt;/h2>
&lt;p>SDK 內建的 redaction rule 覆蓋最常見的敏感欄位模式。開發者不需要設定就能獲得基本保護。&lt;/p>
&lt;h3 id="欄位名稱比對">欄位名稱比對&lt;/h3>
&lt;p>以下欄位名稱（不分大小寫）的值自動替換為 &lt;code>[REDACTED]&lt;/code>：&lt;/p>
&lt;ul>
&lt;li>&lt;code>password&lt;/code>、&lt;code>passwd&lt;/code>、&lt;code>secret&lt;/code>、&lt;code>token&lt;/code>、&lt;code>api_key&lt;/code>、&lt;code>apiKey&lt;/code>&lt;/li>
&lt;li>&lt;code>authorization&lt;/code>、&lt;code>auth&lt;/code>、&lt;code>credential&lt;/code>&lt;/li>
&lt;li>&lt;code>ssn&lt;/code>、&lt;code>social_security&lt;/code>&lt;/li>
&lt;li>&lt;code>credit_card&lt;/code>、&lt;code>card_number&lt;/code>、&lt;code>cvv&lt;/code>、&lt;code>cvc&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>欄位名稱比對用 substring match — &lt;code>user_password&lt;/code> 包含 &lt;code>password&lt;/code> 會被 redact，&lt;code>password_reset_token&lt;/code> 包含 &lt;code>password&lt;/code> 和 &lt;code>token&lt;/code> 也會。&lt;/p>
&lt;h3 id="值格式比對">值格式比對&lt;/h3>
&lt;p>以下格式的值無論欄位名稱為何都自動替換：&lt;/p>
&lt;ul>
&lt;li>Email 地址格式（&lt;code>user@domain.com&lt;/code> → &lt;code>u***@domain.com&lt;/code>）&lt;/li>
&lt;li>信用卡號碼格式（連續 13-19 位數字 → 保留末四碼）&lt;/li>
&lt;li>Bearer token 格式（&lt;code>Bearer xxx&lt;/code> → &lt;code>Bearer [REDACTED]&lt;/code>）&lt;/li>
&lt;/ul>
&lt;p>值格式比對用正則表達式。正則的效能影響在大量事件時需要注意 — 預設 rule 的正則保持簡單，避免 catastrophic backtracking。&lt;/p>
&lt;h2 id="自訂-pattern">自訂 Pattern&lt;/h2>
&lt;p>應用可能有自己的 secret 格式，預設 rule 覆蓋不到。SDK 提供 API 讓開發者註冊自訂 redaction pattern。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">monitor.addRedactionRule(
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> name: &amp;#39;internal-api-key&amp;#39;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> pattern: RegExp(r&amp;#39;sk_live_[a-zA-Z0-9]{24}&amp;#39;),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> replacement: &amp;#39;[REDACTED:api-key]&amp;#39;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">monitor.addRedactionRule(
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> name: &amp;#39;database-url&amp;#39;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> fieldNames: [&amp;#39;database_url&amp;#39;, &amp;#39;db_url&amp;#39;, &amp;#39;connection_string&amp;#39;],
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> replacement: &amp;#39;[REDACTED:db-url]&amp;#39;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>自訂 pattern 的設計考量：&lt;/p>
&lt;p>&lt;strong>Pattern 在 init 時註冊&lt;/strong>。Redaction rule 在 SDK 初始化時設定，之後所有事件都通過這些 rule。不支援動態修改 — 避免「中途加 rule 導致之前的事件沒被 redact」的困惑。&lt;/p>
&lt;p>&lt;strong>Pattern 順序無關&lt;/strong>。所有 rule 獨立執行，不依賴順序。一個欄位可以匹配多個 rule，以第一個匹配的 replacement 為準。&lt;/p>
&lt;p>&lt;strong>Replacement 可以保留部分資訊&lt;/strong>。&lt;code>[REDACTED]&lt;/code> 完全遮蔽，&lt;code>[REDACTED:api-key]&lt;/code> 保留類型資訊，&lt;code>u***@domain.com&lt;/code> 保留結構。保留類型資訊對 debug 有幫助 — 看到 &lt;code>[REDACTED:api-key]&lt;/code> 至少知道這裡原本有一個 API key。&lt;/p>
&lt;h2 id="redaction-的適用範圍">Redaction 的適用範圍&lt;/h2>
&lt;p>Redaction 應用在 SDK 送出事件前的最後一步 — 在序列化（JSON encode）之前。適用範圍包括：&lt;/p>
&lt;ul>
&lt;li>Event 的 data 欄位（自由欄位，開發者可能放入任何內容）&lt;/li>
&lt;li>Error 的 stack trace（檔案路徑可能包含使用者名稱或部署路徑）&lt;/li>
&lt;li>Error 的 message（例外訊息可能包含 query string 或參數值）&lt;/li>
&lt;li>Lifecycle 的 metadata（連線 URL 可能包含認證資訊）&lt;/li>
&lt;/ul>
&lt;p>Redaction 不應用在 SDK 的內部欄位（timestamp、event type、session ID）— 這些是 SDK 自己產生的，不包含使用者資料。&lt;/p></description><content:encoded><![CDATA[<p>Redaction 是在事件資料離開 client 之前，把敏感欄位的值替換成遮罩或移除。本章聚焦 redaction 的策略面 — 哪些資訊需要保護、保護的判斷依據和適用範圍。SDK 的 API 實作細節（初始化方式、helper 函式設計、和 flush 管線的整合）見 <a href="/blog/monitoring/03-sdk-design/redaction-helper/" data-link-title="SDK redaction helper" data-link-desc="在事件離開 SDK 前移除敏感資訊 — 預設 redaction rule 處理常見 pattern，自訂 rule 處理業務特定的 secret">SDK redaction helper</a>。Redaction 在 SDK 端執行的設計原則是「敏感資料不離開 client」— 一旦資料送到 collector，即使 collector 有 access control，資料已經在網路上傳輸過，多了一層洩漏面。</p>
<h2 id="預設-redaction-rule">預設 Redaction Rule</h2>
<p>SDK 內建的 redaction rule 覆蓋最常見的敏感欄位模式。開發者不需要設定就能獲得基本保護。</p>
<h3 id="欄位名稱比對">欄位名稱比對</h3>
<p>以下欄位名稱（不分大小寫）的值自動替換為 <code>[REDACTED]</code>：</p>
<ul>
<li><code>password</code>、<code>passwd</code>、<code>secret</code>、<code>token</code>、<code>api_key</code>、<code>apiKey</code></li>
<li><code>authorization</code>、<code>auth</code>、<code>credential</code></li>
<li><code>ssn</code>、<code>social_security</code></li>
<li><code>credit_card</code>、<code>card_number</code>、<code>cvv</code>、<code>cvc</code></li>
</ul>
<p>欄位名稱比對用 substring match — <code>user_password</code> 包含 <code>password</code> 會被 redact，<code>password_reset_token</code> 包含 <code>password</code> 和 <code>token</code> 也會。</p>
<h3 id="值格式比對">值格式比對</h3>
<p>以下格式的值無論欄位名稱為何都自動替換：</p>
<ul>
<li>Email 地址格式（<code>user@domain.com</code> → <code>u***@domain.com</code>）</li>
<li>信用卡號碼格式（連續 13-19 位數字 → 保留末四碼）</li>
<li>Bearer token 格式（<code>Bearer xxx</code> → <code>Bearer [REDACTED]</code>）</li>
</ul>
<p>值格式比對用正則表達式。正則的效能影響在大量事件時需要注意 — 預設 rule 的正則保持簡單，避免 catastrophic backtracking。</p>
<h2 id="自訂-pattern">自訂 Pattern</h2>
<p>應用可能有自己的 secret 格式，預設 rule 覆蓋不到。SDK 提供 API 讓開發者註冊自訂 redaction pattern。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">monitor.addRedactionRule(
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  name: &#39;internal-api-key&#39;,
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  pattern: RegExp(r&#39;sk_live_[a-zA-Z0-9]{24}&#39;),
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  replacement: &#39;[REDACTED:api-key]&#39;,
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">)
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">monitor.addRedactionRule(
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  name: &#39;database-url&#39;,
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  fieldNames: [&#39;database_url&#39;, &#39;db_url&#39;, &#39;connection_string&#39;],
</span></span><span class="line"><span class="ln">10</span><span class="cl">  replacement: &#39;[REDACTED:db-url]&#39;,
</span></span><span class="line"><span class="ln">11</span><span class="cl">)</span></span></code></pre></div><p>自訂 pattern 的設計考量：</p>
<p><strong>Pattern 在 init 時註冊</strong>。Redaction rule 在 SDK 初始化時設定，之後所有事件都通過這些 rule。不支援動態修改 — 避免「中途加 rule 導致之前的事件沒被 redact」的困惑。</p>
<p><strong>Pattern 順序無關</strong>。所有 rule 獨立執行，不依賴順序。一個欄位可以匹配多個 rule，以第一個匹配的 replacement 為準。</p>
<p><strong>Replacement 可以保留部分資訊</strong>。<code>[REDACTED]</code> 完全遮蔽，<code>[REDACTED:api-key]</code> 保留類型資訊，<code>u***@domain.com</code> 保留結構。保留類型資訊對 debug 有幫助 — 看到 <code>[REDACTED:api-key]</code> 至少知道這裡原本有一個 API key。</p>
<h2 id="redaction-的適用範圍">Redaction 的適用範圍</h2>
<p>Redaction 應用在 SDK 送出事件前的最後一步 — 在序列化（JSON encode）之前。適用範圍包括：</p>
<ul>
<li>Event 的 data 欄位（自由欄位，開發者可能放入任何內容）</li>
<li>Error 的 stack trace（檔案路徑可能包含使用者名稱或部署路徑）</li>
<li>Error 的 message（例外訊息可能包含 query string 或參數值）</li>
<li>Lifecycle 的 metadata（連線 URL 可能包含認證資訊）</li>
</ul>
<p>Redaction 不應用在 SDK 的內部欄位（timestamp、event type、session ID）— 這些是 SDK 自己產生的，不包含使用者資料。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>資料離開 client 後的保護 → <a href="/blog/monitoring/07-security-privacy/transport-security/" data-link-title="Transport 安全" data-link-desc="HTTPS / basic auth / 同區網也要加密的理由 — 監控資料在傳輸途中的保護機制">Transport 安全</a></li>
<li>去識別化策略 → <a href="/blog/monitoring/07-security-privacy/anonymization-strategy/" data-link-title="去識別化策略" data-link-desc="IP 截斷 / user agent 簡化 / stack trace 路徑清理 / session UUID — 四種去識別化技術的適用場景和實作方式">去識別化策略</a></li>
<li>IME 個人化學習的 secret 洩漏風險 → <a href="/blog/ux-design/03-input-mechanism/ime-security-checklist/" data-link-title="安全敏感輸入框的 IME 控制 checklist" data-link-desc="處理密碼、API key、伺服器路徑等 secret 的輸入框需要關閉 IME 的個人化學習和自動校正 — 安全要求而非 UX 偏好">ux-design 模組三 IME 安全 checklist</a></li>
</ul>
]]></content:encoded></item><item><title>去識別化策略</title><link>https://tarrragon.github.io/blog/monitoring/07-security-privacy/anonymization-strategy/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/07-security-privacy/anonymization-strategy/</guid><description>&lt;p>去識別化是把監控資料中可以關聯到特定個人的欄位，轉換成無法回溯到個人但仍保留分析價值的形式。去識別化和 &lt;a href="https://tarrragon.github.io/blog/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a> 的差別在於：redaction 完全移除資訊（&lt;code>[REDACTED]&lt;/code>），去識別化保留結構化的資訊但移除可識別性。&lt;/p>
&lt;h2 id="ip-截斷">IP 截斷&lt;/h2>
&lt;p>IP 位址是最常見的個人識別欄位。完整的 IPv4 位址（&lt;code>192.168.1.50&lt;/code>）可以定位到特定的網路和裝置；截斷後的 IP（&lt;code>192.168.1.0&lt;/code>）保留網段資訊但無法定位到特定裝置。&lt;/p>
&lt;h3 id="截斷策略">截斷策略&lt;/h3>
&lt;p>&lt;strong>IPv4 末八位清零&lt;/strong>：&lt;code>192.168.1.50&lt;/code> → &lt;code>192.168.1.0&lt;/code>。保留 /24 網段資訊，足以判斷「使用者在哪個網段」但無法定位到特定裝置。Google Analytics 採用這個策略。&lt;/p>
&lt;p>&lt;strong>IPv4 末十六位清零&lt;/strong>：&lt;code>192.168.1.50&lt;/code> → &lt;code>192.168.0.0&lt;/code>。更強的去識別化，但地理定位精度降低到城市級。&lt;/p>
&lt;p>&lt;strong>IPv6&lt;/strong>：截斷更多位元。IPv6 的後 80 位通常包含 MAC 位址衍生的 interface ID — 截斷到 /48 前綴保留 ISP 資訊，移除裝置識別。&lt;/p>
&lt;h3 id="實作位置">實作位置&lt;/h3>
&lt;p>IP 截斷應在 collector 收到事件後、寫入儲存前執行。SDK 端不做 IP 截斷 — SDK 通常不知道自己的外部 IP（知道的是 NAT 後的內部 IP），外部 IP 是 collector 從 HTTP request 的 source IP 取得的。&lt;/p>
&lt;h2 id="user-agent-簡化">User Agent 簡化&lt;/h2>
&lt;p>User agent 字串包含瀏覽器版本、OS 版本、裝置型號 — 組合起來可能形成唯一的 fingerprint。簡化 user agent 保留有用的分類資訊（「iOS 17 上的 Safari」），移除可用於 fingerprinting 的細節（「iPhone 15 Pro Max, Build/22A3354」）。&lt;/p>
&lt;h3 id="簡化規則">簡化規則&lt;/h3>
&lt;p>保留：平台（iOS / Android / Windows / macOS）、主要版本號（iOS 17、Android 14）、瀏覽器類型（Safari / Chrome / Firefox）。&lt;/p>
&lt;p>移除：minor version、build number、裝置型號、CPU 架構、語言設定。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">原始：Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">簡化：iOS/17 Safari&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="stack-trace-路徑清理">Stack Trace 路徑清理&lt;/h2>
&lt;p>Error 事件的 stack trace 包含檔案路徑。檔案路徑可能洩漏部署結構（&lt;code>/home/deploy_user/app/v2.3.1/src/...&lt;/code>）或開發者的個人資訊（&lt;code>/Users/alice/projects/...&lt;/code>）。&lt;/p>
&lt;h3 id="清理規則">清理規則&lt;/h3>
&lt;p>&lt;strong>移除使用者目錄前綴&lt;/strong>：&lt;code>/Users/alice/projects/app/src/main.dart:42&lt;/code> → &lt;code>src/main.dart:42&lt;/code>。保留 source file 相對路徑和行號，移除使用者名稱。&lt;/p>
&lt;p>&lt;strong>移除部署路徑前綴&lt;/strong>：&lt;code>/opt/deploy/releases/20260619/app/lib/...&lt;/code> → &lt;code>lib/...&lt;/code>。保留程式碼結構，移除部署細節。&lt;/p>
&lt;p>&lt;strong>統一 path separator&lt;/strong>：Windows 路徑（&lt;code>C:\Users\...&lt;/code>）和 Unix 路徑（&lt;code>/home/...&lt;/code>）統一處理。&lt;/p>
&lt;p>清理規則用正則表達式匹配常見的路徑前綴模式，替換為空字串。自訂的部署路徑格式需要在 collector 設定中額外註冊。&lt;/p>
&lt;h2 id="session-uuid">Session UUID&lt;/h2>
&lt;p>Session ID 用於關聯同一次使用中的多個事件。UUID v4（隨機產生）作為 session ID，沒有可預測性、沒有順序性、無法回推使用者身份。&lt;/p>
&lt;h3 id="session-id-的生命週期">Session ID 的生命週期&lt;/h3>
&lt;p>SDK 在初始化時產生一個 UUID v4 作為 session ID，所有事件附帶這個 ID。App 重新啟動時產生新的 session ID — 前後兩次使用的事件無法關聯。&lt;/p>
&lt;p>這個設計讓分析粒度限制在「一次使用」而非「一個使用者」。如果需要跨 session 關聯（例如計算 DAU），需要另一個 persistent ID — 但 persistent ID 本身就是可識別資訊，需要使用者同意。&lt;/p>
&lt;h3 id="避免使用可識別的-id">避免使用可識別的 ID&lt;/h3>
&lt;p>裝置 ID（IDFA / GAID）、安裝 ID、使用者帳號 — 這些可以關聯到特定個人，不適合作為監控系統的 session ID。使用 UUID v4 確保 session ID 的唯一性來自隨機性而非身份。&lt;/p>
&lt;p>去識別化是資料保護的一環，另一環是在資料離開 client 之前就處理 — &lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/sdk-redaction-api/" data-link-title="SDK Redaction API 設計" data-link-desc="預設 redaction rule 過濾已知敏感欄位、自訂 pattern 擴展應用特有的 secret 格式 — redaction 在 SDK 端執行，敏感資料不離開 client">SDK Redaction API 設計&lt;/a>從 SDK 端攔截敏感欄位。法規層面的具體要求見 &lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/gdpr-minimization/" data-link-title="GDPR 最小化原則的工程落地" data-link-desc="資料最小化、目的限制、儲存限制 — GDPR 三個核心原則在監控系統的工程實作方式">GDPR 最小化原則的工程落地&lt;/a>。去識別化完成後的資料才能用於&lt;a href="https://tarrragon.github.io/blog/monitoring/08-business-analytics/" data-link-title="模組八：行為資料的商業利用" data-link-desc="Funnel / Cohort / Attribution / A/B test / 推薦系統 / RFM — 從 debug 工具到商業資產的翻轉">行為分析&lt;/a> — 這是商業利用的入場條件。&lt;/p></description><content:encoded><![CDATA[<p>去識別化是把監控資料中可以關聯到特定個人的欄位，轉換成無法回溯到個人但仍保留分析價值的形式。去識別化和 <a href="/blog/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a> 的差別在於：redaction 完全移除資訊（<code>[REDACTED]</code>），去識別化保留結構化的資訊但移除可識別性。</p>
<h2 id="ip-截斷">IP 截斷</h2>
<p>IP 位址是最常見的個人識別欄位。完整的 IPv4 位址（<code>192.168.1.50</code>）可以定位到特定的網路和裝置；截斷後的 IP（<code>192.168.1.0</code>）保留網段資訊但無法定位到特定裝置。</p>
<h3 id="截斷策略">截斷策略</h3>
<p><strong>IPv4 末八位清零</strong>：<code>192.168.1.50</code> → <code>192.168.1.0</code>。保留 /24 網段資訊，足以判斷「使用者在哪個網段」但無法定位到特定裝置。Google Analytics 採用這個策略。</p>
<p><strong>IPv4 末十六位清零</strong>：<code>192.168.1.50</code> → <code>192.168.0.0</code>。更強的去識別化，但地理定位精度降低到城市級。</p>
<p><strong>IPv6</strong>：截斷更多位元。IPv6 的後 80 位通常包含 MAC 位址衍生的 interface ID — 截斷到 /48 前綴保留 ISP 資訊，移除裝置識別。</p>
<h3 id="實作位置">實作位置</h3>
<p>IP 截斷應在 collector 收到事件後、寫入儲存前執行。SDK 端不做 IP 截斷 — SDK 通常不知道自己的外部 IP（知道的是 NAT 後的內部 IP），外部 IP 是 collector 從 HTTP request 的 source IP 取得的。</p>
<h2 id="user-agent-簡化">User Agent 簡化</h2>
<p>User agent 字串包含瀏覽器版本、OS 版本、裝置型號 — 組合起來可能形成唯一的 fingerprint。簡化 user agent 保留有用的分類資訊（「iOS 17 上的 Safari」），移除可用於 fingerprinting 的細節（「iPhone 15 Pro Max, Build/22A3354」）。</p>
<h3 id="簡化規則">簡化規則</h3>
<p>保留：平台（iOS / Android / Windows / macOS）、主要版本號（iOS 17、Android 14）、瀏覽器類型（Safari / Chrome / Firefox）。</p>
<p>移除：minor version、build number、裝置型號、CPU 架構、語言設定。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">原始：Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X)
</span></span><span class="line"><span class="ln">2</span><span class="cl">簡化：iOS/17 Safari</span></span></code></pre></div><h2 id="stack-trace-路徑清理">Stack Trace 路徑清理</h2>
<p>Error 事件的 stack trace 包含檔案路徑。檔案路徑可能洩漏部署結構（<code>/home/deploy_user/app/v2.3.1/src/...</code>）或開發者的個人資訊（<code>/Users/alice/projects/...</code>）。</p>
<h3 id="清理規則">清理規則</h3>
<p><strong>移除使用者目錄前綴</strong>：<code>/Users/alice/projects/app/src/main.dart:42</code> → <code>src/main.dart:42</code>。保留 source file 相對路徑和行號，移除使用者名稱。</p>
<p><strong>移除部署路徑前綴</strong>：<code>/opt/deploy/releases/20260619/app/lib/...</code> → <code>lib/...</code>。保留程式碼結構，移除部署細節。</p>
<p><strong>統一 path separator</strong>：Windows 路徑（<code>C:\Users\...</code>）和 Unix 路徑（<code>/home/...</code>）統一處理。</p>
<p>清理規則用正則表達式匹配常見的路徑前綴模式，替換為空字串。自訂的部署路徑格式需要在 collector 設定中額外註冊。</p>
<h2 id="session-uuid">Session UUID</h2>
<p>Session ID 用於關聯同一次使用中的多個事件。UUID v4（隨機產生）作為 session ID，沒有可預測性、沒有順序性、無法回推使用者身份。</p>
<h3 id="session-id-的生命週期">Session ID 的生命週期</h3>
<p>SDK 在初始化時產生一個 UUID v4 作為 session ID，所有事件附帶這個 ID。App 重新啟動時產生新的 session ID — 前後兩次使用的事件無法關聯。</p>
<p>這個設計讓分析粒度限制在「一次使用」而非「一個使用者」。如果需要跨 session 關聯（例如計算 DAU），需要另一個 persistent ID — 但 persistent ID 本身就是可識別資訊，需要使用者同意。</p>
<h3 id="避免使用可識別的-id">避免使用可識別的 ID</h3>
<p>裝置 ID（IDFA / GAID）、安裝 ID、使用者帳號 — 這些可以關聯到特定個人，不適合作為監控系統的 session ID。使用 UUID v4 確保 session ID 的唯一性來自隨機性而非身份。</p>
<p>去識別化是資料保護的一環，另一環是在資料離開 client 之前就處理 — <a href="/blog/monitoring/07-security-privacy/sdk-redaction-api/" data-link-title="SDK Redaction API 設計" data-link-desc="預設 redaction rule 過濾已知敏感欄位、自訂 pattern 擴展應用特有的 secret 格式 — redaction 在 SDK 端執行，敏感資料不離開 client">SDK Redaction API 設計</a>從 SDK 端攔截敏感欄位。法規層面的具體要求見 <a href="/blog/monitoring/07-security-privacy/gdpr-minimization/" data-link-title="GDPR 最小化原則的工程落地" data-link-desc="資料最小化、目的限制、儲存限制 — GDPR 三個核心原則在監控系統的工程實作方式">GDPR 最小化原則的工程落地</a>。去識別化完成後的資料才能用於<a href="/blog/monitoring/08-business-analytics/" data-link-title="模組八：行為資料的商業利用" data-link-desc="Funnel / Cohort / Attribution / A/B test / 推薦系統 / RFM — 從 debug 工具到商業資產的翻轉">行為分析</a> — 這是商業利用的入場條件。</p>
]]></content:encoded></item><item><title>GDPR 最小化原則的工程落地</title><link>https://tarrragon.github.io/blog/monitoring/07-security-privacy/gdpr-minimization/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/07-security-privacy/gdpr-minimization/</guid><description>&lt;p>GDPR 的資料最小化原則要求「只收集達成特定目的所需的最少資料」。這個法律原則轉譯到監控系統的工程實作，影響三個設計決策：收集什麼欄位、保留多久、誰可以存取。&lt;/p>
&lt;h2 id="資料最小化只收集需要的欄位">資料最小化：只收集需要的欄位&lt;/h2>
&lt;p>資料最小化的工程落地是「每個收集的欄位都要能回答：這個欄位用來做什麼決策？」。如果一個欄位只是「可能有用」但沒有明確的消費場景，就不應該收集。&lt;/p>
&lt;h3 id="正面表列-vs-負面排除">正面表列 vs 負面排除&lt;/h3>
&lt;p>正面表列（allowlist）是列出「收集哪些欄位」— 只收集清單上的欄位，其他全部不收。&lt;/p>
&lt;p>負面排除（denylist）是列出「不收集哪些欄位」— 預設收集所有欄位，排除清單上的。&lt;/p>
&lt;p>GDPR 的精神更接近正面表列 — 每個收集行為需要有正當理由（lawful basis）。工程上的實作方式是：事件 schema 定義哪些欄位是允許的，不在 schema 中的欄位在 collector 端丟棄。&lt;/p>
&lt;h3 id="sdk-端的最小化">SDK 端的最小化&lt;/h3>
&lt;p>SDK 端的最小化更主動 — 在事件產生時就只包含必要的欄位，而非送到 collector 再過濾。&lt;/p>
&lt;p>設計 SDK 的 event API 時，不提供「送任意 key-value」的 free-form API，而是提供結構化的 API：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">// free-form（難以控制收集了什麼）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">monitor.event(&amp;#39;login&amp;#39;, data: {&amp;#39;email&amp;#39;: email, &amp;#39;ip&amp;#39;: ip, &amp;#39;device&amp;#39;: device, ...})
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">// 結構化（schema 控制收集範圍）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">monitor.event(&amp;#39;login&amp;#39;, loginMethod: &amp;#39;biometric&amp;#39;, success: true)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>結構化 API 的參數在 SDK 設計時就決定了收集範圍，code review 時可以檢查「為什麼這個 event 需要這個參數」。&lt;/p>
&lt;h2 id="目的限制收集的資料只用於聲明的目的">目的限制：收集的資料只用於聲明的目的&lt;/h2>
&lt;p>目的限制要求資料只用於收集時聲明的目的。監控系統收集事件的目的通常是 debug 和效能監控 — 如果之後要用同一份資料做行為分析或廣告投放，需要額外的法律基礎（通常是使用者同意）。&lt;/p>
&lt;h3 id="工程落地">工程落地&lt;/h3>
&lt;p>目的限制在工程上的實作是「不同目的的資料分開儲存、分開授權」。&lt;/p>
&lt;p>Debug 用的 error 事件和行為分析用的 event 事件存在不同的儲存位置（不同的 JSONL 檔案或不同的資料庫 table）。Debug 用途的 access 不需要使用者同意（legitimate interest）；行為分析用途的 access 需要使用者同意。&lt;/p>
&lt;p>分開儲存讓「使用者撤回行為分析同意」的工程操作變簡單 — 刪除行為分析的儲存，不影響 debug 儲存。&lt;/p>
&lt;h2 id="儲存限制不保留超過必要期間的資料">儲存限制：不保留超過必要期間的資料&lt;/h2>
&lt;p>儲存限制要求資料只保留達成目的所需的最短期間。監控資料的合理保留期間依用途不同：&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>Debug&lt;/td>
 &lt;td>30-90 天&lt;/td>
 &lt;td>大部分 bug 在 30 天內被發現和修復&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>效能趨勢&lt;/td>
 &lt;td>6-12 個月&lt;/td>
 &lt;td>季節性趨勢需要至少一年的資料&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>行為分析&lt;/td>
 &lt;td>依同意期間&lt;/td>
 &lt;td>使用者同意到期就刪除&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>合規審計&lt;/td>
 &lt;td>依法規要求（通常 1-7 年）&lt;/td>
 &lt;td>法規指定的最短保留期間&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="自動清理">自動清理&lt;/h3>
&lt;p>Collector 的儲存清理應該自動化 — 手動清理依賴人記得執行，最終會被遺忘。&lt;/p>
&lt;p>JSONL 儲存用「一天一檔」的命名（&lt;code>events-2026-06-19.jsonl&lt;/code>），清理腳本每天刪除超過保留期限的檔案。Cron job 或 systemd timer 定期執行。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>去識別化技術 → &lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/anonymization-strategy/" data-link-title="去識別化策略" data-link-desc="IP 截斷 / user agent 簡化 / stack trace 路徑清理 / session UUID — 四種去識別化技術的適用場景和實作方式">去識別化策略&lt;/a>&lt;/li>
&lt;li>監控資料洩漏的威脅分析 → &lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/monitoring-data-threat-model/" data-link-title="監控資料洩漏的 Threat Model" data-link-desc="監控系統本身是攻擊面 — 四個威脅場景（傳輸竊聽 / 儲存入侵 / endpoint 濫用 / 內部越權存取）的風險評估和防護措施">監控資料洩漏的 threat model&lt;/a>&lt;/li>
&lt;li>Collector 的儲存設計 → &lt;a href="https://tarrragon.github.io/blog/monitoring/04-collector/" data-link-title="模組四：Collector 設計" data-link-desc="收 → 驗 → 存 → 查 → 觸發的完整鏈路 — Go 單一 binary、可插拔 Storage Backend、rule engine">模組四 Collector 設計&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>GDPR 的資料最小化原則要求「只收集達成特定目的所需的最少資料」。這個法律原則轉譯到監控系統的工程實作，影響三個設計決策：收集什麼欄位、保留多久、誰可以存取。</p>
<h2 id="資料最小化只收集需要的欄位">資料最小化：只收集需要的欄位</h2>
<p>資料最小化的工程落地是「每個收集的欄位都要能回答：這個欄位用來做什麼決策？」。如果一個欄位只是「可能有用」但沒有明確的消費場景，就不應該收集。</p>
<h3 id="正面表列-vs-負面排除">正面表列 vs 負面排除</h3>
<p>正面表列（allowlist）是列出「收集哪些欄位」— 只收集清單上的欄位，其他全部不收。</p>
<p>負面排除（denylist）是列出「不收集哪些欄位」— 預設收集所有欄位，排除清單上的。</p>
<p>GDPR 的精神更接近正面表列 — 每個收集行為需要有正當理由（lawful basis）。工程上的實作方式是：事件 schema 定義哪些欄位是允許的，不在 schema 中的欄位在 collector 端丟棄。</p>
<h3 id="sdk-端的最小化">SDK 端的最小化</h3>
<p>SDK 端的最小化更主動 — 在事件產生時就只包含必要的欄位，而非送到 collector 再過濾。</p>
<p>設計 SDK 的 event API 時，不提供「送任意 key-value」的 free-form API，而是提供結構化的 API：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">// free-form（難以控制收集了什麼）
</span></span><span class="line"><span class="ln">2</span><span class="cl">monitor.event(&#39;login&#39;, data: {&#39;email&#39;: email, &#39;ip&#39;: ip, &#39;device&#39;: device, ...})
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">// 結構化（schema 控制收集範圍）
</span></span><span class="line"><span class="ln">5</span><span class="cl">monitor.event(&#39;login&#39;, loginMethod: &#39;biometric&#39;, success: true)</span></span></code></pre></div><p>結構化 API 的參數在 SDK 設計時就決定了收集範圍，code review 時可以檢查「為什麼這個 event 需要這個參數」。</p>
<h2 id="目的限制收集的資料只用於聲明的目的">目的限制：收集的資料只用於聲明的目的</h2>
<p>目的限制要求資料只用於收集時聲明的目的。監控系統收集事件的目的通常是 debug 和效能監控 — 如果之後要用同一份資料做行為分析或廣告投放，需要額外的法律基礎（通常是使用者同意）。</p>
<h3 id="工程落地">工程落地</h3>
<p>目的限制在工程上的實作是「不同目的的資料分開儲存、分開授權」。</p>
<p>Debug 用的 error 事件和行為分析用的 event 事件存在不同的儲存位置（不同的 JSONL 檔案或不同的資料庫 table）。Debug 用途的 access 不需要使用者同意（legitimate interest）；行為分析用途的 access 需要使用者同意。</p>
<p>分開儲存讓「使用者撤回行為分析同意」的工程操作變簡單 — 刪除行為分析的儲存，不影響 debug 儲存。</p>
<h2 id="儲存限制不保留超過必要期間的資料">儲存限制：不保留超過必要期間的資料</h2>
<p>儲存限制要求資料只保留達成目的所需的最短期間。監控資料的合理保留期間依用途不同：</p>
<table>
  <thead>
      <tr>
          <th>用途</th>
          <th>合理保留期間</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Debug</td>
          <td>30-90 天</td>
          <td>大部分 bug 在 30 天內被發現和修復</td>
      </tr>
      <tr>
          <td>效能趨勢</td>
          <td>6-12 個月</td>
          <td>季節性趨勢需要至少一年的資料</td>
      </tr>
      <tr>
          <td>行為分析</td>
          <td>依同意期間</td>
          <td>使用者同意到期就刪除</td>
      </tr>
      <tr>
          <td>合規審計</td>
          <td>依法規要求（通常 1-7 年）</td>
          <td>法規指定的最短保留期間</td>
      </tr>
  </tbody>
</table>
<h3 id="自動清理">自動清理</h3>
<p>Collector 的儲存清理應該自動化 — 手動清理依賴人記得執行，最終會被遺忘。</p>
<p>JSONL 儲存用「一天一檔」的命名（<code>events-2026-06-19.jsonl</code>），清理腳本每天刪除超過保留期限的檔案。Cron job 或 systemd timer 定期執行。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>去識別化技術 → <a href="/blog/monitoring/07-security-privacy/anonymization-strategy/" data-link-title="去識別化策略" data-link-desc="IP 截斷 / user agent 簡化 / stack trace 路徑清理 / session UUID — 四種去識別化技術的適用場景和實作方式">去識別化策略</a></li>
<li>監控資料洩漏的威脅分析 → <a href="/blog/monitoring/07-security-privacy/monitoring-data-threat-model/" data-link-title="監控資料洩漏的 Threat Model" data-link-desc="監控系統本身是攻擊面 — 四個威脅場景（傳輸竊聽 / 儲存入侵 / endpoint 濫用 / 內部越權存取）的風險評估和防護措施">監控資料洩漏的 threat model</a></li>
<li>Collector 的儲存設計 → <a href="/blog/monitoring/04-collector/" data-link-title="模組四：Collector 設計" data-link-desc="收 → 驗 → 存 → 查 → 觸發的完整鏈路 — Go 單一 binary、可插拔 Storage Backend、rule engine">模組四 Collector 設計</a></li>
</ul>
]]></content:encoded></item><item><title>SDK redaction helper</title><link>https://tarrragon.github.io/blog/monitoring/03-sdk-design/redaction-helper/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/03-sdk-design/redaction-helper/</guid><description>&lt;p>SDK &lt;a href="https://tarrragon.github.io/blog/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a> helper 在事件離開 SDK（進入 HTTP POST payload）前掃描事件內容，把匹配敏感資訊 pattern 的欄位值替換為 &lt;code>[REDACTED]&lt;/code>。Redaction 在 SDK 端執行，確保敏感資訊不會經過網路傳輸到 collector — 即使 transport 層被攔截，攻擊者看到的也是脫敏後的資料。&lt;/p>
&lt;h2 id="預設-redaction-rule">預設 redaction rule&lt;/h2>
&lt;p>SDK 內建一組預設 rule，處理常見的敏感資訊 pattern：&lt;/p>
&lt;h3 id="密碼欄位">密碼欄位&lt;/h3>
&lt;p>匹配 data 物件中 key 包含 &lt;code>password&lt;/code>、&lt;code>passwd&lt;/code>、&lt;code>secret&lt;/code>、&lt;code>token&lt;/code>、&lt;code>api_key&lt;/code>、&lt;code>apiKey&lt;/code>、&lt;code>authorization&lt;/code> 的欄位。匹配方式是 key 名稱的子字串比對（case-insensitive）。&lt;/p>
&lt;h3 id="url-中的認證資訊">URL 中的認證資訊&lt;/h3>
&lt;p>匹配 &lt;code>https://user:password@host&lt;/code> 格式的 URL，把 &lt;code>user:password&lt;/code> 部分替換為 &lt;code>[REDACTED]&lt;/code>。&lt;/p>
&lt;h3 id="stack-trace-中的檔案路徑">Stack trace 中的檔案路徑&lt;/h3>
&lt;p>匹配 stack trace 字串中的使用者目錄路徑（&lt;code>/Users/username/&lt;/code>、&lt;code>/home/username/&lt;/code>、&lt;code>C:\Users\username\&lt;/code>），替換為 &lt;code>[USER_HOME]/&lt;/code>。避免使用者名稱從 stack trace 洩漏。&lt;/p>
&lt;h2 id="自訂-redaction-rule">自訂 redaction rule&lt;/h2>
&lt;p>業務特定的敏感資訊（信用卡號、身分證字號、醫療資料）不在預設 rule 的範圍內。SDK 提供 API 讓開發者在 init 時註冊自訂 rule。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">Monitor.init({
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> redactionRules: [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> { pattern: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/, replace: &amp;#39;[CARD]&amp;#39; },
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> { keyPattern: /^ssn$/i, replace: &amp;#39;[REDACTED]&amp;#39; },
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ],
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">})&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>自訂 rule 和預設 rule 一起執行。如果同一個值被多個 rule 匹配，第一個匹配的 rule 生效（rule 的執行順序：預設 rule 先，自訂 rule 後）。&lt;/p>
&lt;h2 id="redaction-的執行時機">Redaction 的執行時機&lt;/h2>
&lt;p>Redaction 在事件進入 flush payload 的那一刻執行 — buffer 中的事件保持原始內容，flush 時複製一份並在複製上執行 redaction。&lt;/p>
&lt;p>在 buffer 中保持原始內容的理由是 debug：開發者在本地 console 看到的 log 應該包含完整資訊（開發環境不需要脫敏），只有離開 SDK 時才脫敏。SDK 可以提供 &lt;code>debugMode&lt;/code> flag — debugMode 開啟時 console log 印出原始內容，HTTP POST 仍送出脫敏後的內容。&lt;/p>
&lt;h2 id="redaction-和模組七的關係">Redaction 和模組七的關係&lt;/h2>
&lt;p>SDK redaction helper 是&lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/" data-link-title="模組七：資安與隱私" data-link-desc="SDK redaction / transport 加密 / collector access control / 去識別化 — 蒐集的資料本身就是風險資產">模組七 資安與隱私&lt;/a>中 redaction 策略的實作層。模組七定義「什麼資訊需要被保護」（策略），本章定義「SDK 如何在程式碼中實現這個保護」（實作）。&lt;/p>
&lt;p>兩者的分工：&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>策略層&lt;/td>
 &lt;td>哪些欄位需要 redaction、哪些 pattern 敏感&lt;/td>
 &lt;td>模組七&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>實作層&lt;/td>
 &lt;td>預設 rule、自訂 rule API、執行時機&lt;/td>
 &lt;td>本章&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗證層&lt;/td>
 &lt;td>確認脫敏後的事件不包含敏感資訊&lt;/td>
 &lt;td>collector 端&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Collector 端可以做第二道檢查（re-scan 收到的事件是否仍包含敏感 pattern），作為 SDK 端 redaction 的備援。但主要的脫敏責任在 SDK 端 — 資料離開 SDK 後經過網路，已經暴露在傳輸風險中。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>SDK 公開 API → &lt;a href="https://tarrragon.github.io/blog/monitoring/03-sdk-design/public-api/" data-link-title="SDK 公開 API 設計" data-link-desc="init / event / error / metric / flush / close 六個方法構成 SDK 的完整生命週期 — 跨平台共用相同 API 介面">SDK 公開 API 設計&lt;/a>&lt;/li>
&lt;li>資安與隱私的完整策略 → &lt;a href="https://tarrragon.github.io/blog/monitoring/07-security-privacy/" data-link-title="模組七：資安與隱私" data-link-desc="SDK redaction / transport 加密 / collector access control / 去識別化 — 蒐集的資料本身就是風險資產">模組七 資安與隱私&lt;/a>&lt;/li>
&lt;li>自動攔截的 error 也需要 redaction → &lt;a href="https://tarrragon.github.io/blog/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">自動攔截機制&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>SDK <a href="/blog/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a> helper 在事件離開 SDK（進入 HTTP POST payload）前掃描事件內容，把匹配敏感資訊 pattern 的欄位值替換為 <code>[REDACTED]</code>。Redaction 在 SDK 端執行，確保敏感資訊不會經過網路傳輸到 collector — 即使 transport 層被攔截，攻擊者看到的也是脫敏後的資料。</p>
<h2 id="預設-redaction-rule">預設 redaction rule</h2>
<p>SDK 內建一組預設 rule，處理常見的敏感資訊 pattern：</p>
<h3 id="密碼欄位">密碼欄位</h3>
<p>匹配 data 物件中 key 包含 <code>password</code>、<code>passwd</code>、<code>secret</code>、<code>token</code>、<code>api_key</code>、<code>apiKey</code>、<code>authorization</code> 的欄位。匹配方式是 key 名稱的子字串比對（case-insensitive）。</p>
<h3 id="url-中的認證資訊">URL 中的認證資訊</h3>
<p>匹配 <code>https://user:password@host</code> 格式的 URL，把 <code>user:password</code> 部分替換為 <code>[REDACTED]</code>。</p>
<h3 id="stack-trace-中的檔案路徑">Stack trace 中的檔案路徑</h3>
<p>匹配 stack trace 字串中的使用者目錄路徑（<code>/Users/username/</code>、<code>/home/username/</code>、<code>C:\Users\username\</code>），替換為 <code>[USER_HOME]/</code>。避免使用者名稱從 stack trace 洩漏。</p>
<h2 id="自訂-redaction-rule">自訂 redaction rule</h2>
<p>業務特定的敏感資訊（信用卡號、身分證字號、醫療資料）不在預設 rule 的範圍內。SDK 提供 API 讓開發者在 init 時註冊自訂 rule。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Monitor.init({
</span></span><span class="line"><span class="ln">2</span><span class="cl">  redactionRules: [
</span></span><span class="line"><span class="ln">3</span><span class="cl">    { pattern: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/, replace: &#39;[CARD]&#39; },
</span></span><span class="line"><span class="ln">4</span><span class="cl">    { keyPattern: /^ssn$/i, replace: &#39;[REDACTED]&#39; },
</span></span><span class="line"><span class="ln">5</span><span class="cl">  ],
</span></span><span class="line"><span class="ln">6</span><span class="cl">})</span></span></code></pre></div><p>自訂 rule 和預設 rule 一起執行。如果同一個值被多個 rule 匹配，第一個匹配的 rule 生效（rule 的執行順序：預設 rule 先，自訂 rule 後）。</p>
<h2 id="redaction-的執行時機">Redaction 的執行時機</h2>
<p>Redaction 在事件進入 flush payload 的那一刻執行 — buffer 中的事件保持原始內容，flush 時複製一份並在複製上執行 redaction。</p>
<p>在 buffer 中保持原始內容的理由是 debug：開發者在本地 console 看到的 log 應該包含完整資訊（開發環境不需要脫敏），只有離開 SDK 時才脫敏。SDK 可以提供 <code>debugMode</code> flag — debugMode 開啟時 console log 印出原始內容，HTTP POST 仍送出脫敏後的內容。</p>
<h2 id="redaction-和模組七的關係">Redaction 和模組七的關係</h2>
<p>SDK redaction helper 是<a href="/blog/monitoring/07-security-privacy/" data-link-title="模組七：資安與隱私" data-link-desc="SDK redaction / transport 加密 / collector access control / 去識別化 — 蒐集的資料本身就是風險資產">模組七 資安與隱私</a>中 redaction 策略的實作層。模組七定義「什麼資訊需要被保護」（策略），本章定義「SDK 如何在程式碼中實現這個保護」（實作）。</p>
<p>兩者的分工：</p>
<table>
  <thead>
      <tr>
          <th>層級</th>
          <th>職責</th>
          <th>定義在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>策略層</td>
          <td>哪些欄位需要 redaction、哪些 pattern 敏感</td>
          <td>模組七</td>
      </tr>
      <tr>
          <td>實作層</td>
          <td>預設 rule、自訂 rule API、執行時機</td>
          <td>本章</td>
      </tr>
      <tr>
          <td>驗證層</td>
          <td>確認脫敏後的事件不包含敏感資訊</td>
          <td>collector 端</td>
      </tr>
  </tbody>
</table>
<p>Collector 端可以做第二道檢查（re-scan 收到的事件是否仍包含敏感 pattern），作為 SDK 端 redaction 的備援。但主要的脫敏責任在 SDK 端 — 資料離開 SDK 後經過網路，已經暴露在傳輸風險中。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>SDK 公開 API → <a href="/blog/monitoring/03-sdk-design/public-api/" data-link-title="SDK 公開 API 設計" data-link-desc="init / event / error / metric / flush / close 六個方法構成 SDK 的完整生命週期 — 跨平台共用相同 API 介面">SDK 公開 API 設計</a></li>
<li>資安與隱私的完整策略 → <a href="/blog/monitoring/07-security-privacy/" data-link-title="模組七：資安與隱私" data-link-desc="SDK redaction / transport 加密 / collector access control / 去識別化 — 蒐集的資料本身就是風險資產">模組七 資安與隱私</a></li>
<li>自動攔截的 error 也需要 redaction → <a href="/blog/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">自動攔截機制</a></li>
</ul>
]]></content:encoded></item><item><title>6.4 跨雲端 / 本地的資料邊界</title><link>https://tarrragon.github.io/blog/llm/06-security/cross-cloud-local-data-boundary/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/06-security/cross-cloud-local-data-boundary/</guid><description>&lt;p>寫 code 工作流常混用本地 LLM 跟雲端 LLM、混用的好處是組合兩邊優勢、代價是 prompt 在不同信任邊界之間流動。本章把「哪些 prompt 該留本機、哪些可以送雲端、怎麼配置才不會誤送」整理成可操作的分流判讀。本章是 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/privacy-data-flow/" data-link-title="0.7 隱私 / 資安的資料流原理" data-link-desc="從「位置」到「資料流」的思考升級：信任邊界、合約模型、零信任原則套用到 LLM 工作流">0.7 隱私資料流原理&lt;/a>「資料流 thinking + 信任邊界」的具體落地、跟 &lt;a href="https://tarrragon.github.io/blog/llm/01-local-llm-services/vscode-continue-integration/" data-link-title="1.3 VS Code &amp;#43; Continue.dev 整合" data-link-desc="安裝 Continue 擴充套件、config.json 設定、Cmd&amp;#43;L 對話 / Cmd&amp;#43;I 行內編輯快捷鍵">1.3 VS Code + Continue.dev 整合&lt;/a> 的 multi-provider 配置直接對應。信任邊界詞彙見 backend &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/trust-boundary/" data-link-title="Trust Boundary" data-link-desc="說明系統哪些位置開始不能沿用原本的信任假設">trust-boundary&lt;/a> 卡、PII 跟資料分類見 backend &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/pii/" data-link-title="PII" data-link-desc="說明可識別個人的資料如何影響權限、遮罩、保留與稽核">pii&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/data-classification/" data-link-title="Data Classification" data-link-desc="說明資料分級如何決定保護、存取、保留與匯出規則">data-classification&lt;/a> 卡、API key 管理見 backend &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">secret-management&lt;/a> 卡。本章 framing 是個人 dev 視角；production 場景的 log / PII 治理見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-log-and-pii-governance/" data-link-title="LLM Log 與 PII 治理" data-link-desc="production LLM 服務的 prompt log 累積、PII 偵測與過濾、保留期限與合規對齊">backend/07 LLM log 與 PII 治理&lt;/a>。&lt;/p>
&lt;p>讀完本章後、你應該能對自己的 IDE 工作流回答：每個 LLM provider 收到什麼 prompt、雲端服務的資料政策大致長怎樣、哪些任務該分到本地、哪些可以送雲端、配置誤送的常見路徑跟對應防護。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;ol>
&lt;li>認識「prompt 邊界」在多 provider 工作流的位置。&lt;/li>
&lt;li>區分本地 LLM 跟雲端 LLM 在資料流上的差異。&lt;/li>
&lt;li>認識主流雲端 LLM 服務的資料政策大致分類。&lt;/li>
&lt;li>用「敏感度 × 任務類型」軸把工作流分流到本地或雲端。&lt;/li>
&lt;li>認識多 provider 設定下、prompt 誤送的常見路徑跟對應防護。&lt;/li>
&lt;/ol>
&lt;h2 id="prompt-邊界在哪">prompt 邊界在哪&lt;/h2>
&lt;p>在多 provider 工作流下、prompt 邊界長這樣：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl"> ┌───────────────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> │ 使用者 + 本機 codebase │ ← trust zone A：完全本地
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> └───────────────────────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓ prompt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ┌─────────────────────────────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> │ IDE LLM client（Continue.dev） │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> │ ↓ route by config │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> │ ├── 本地 model（Ollama / llama-server）│ ← trust zone B：仍在本機
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> │ ├── 商業雲端（Anthropic / OpenAI） │ ← trust zone C：雲端 vendor
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> │ └── 第三方 LLM 聚合（OpenRouter etc.） │ ← trust zone D：聚合層 + 上游 vendor
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> └─────────────────────────────────────────┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>每跨一條邊界、prompt 都會被另一個主體看到。trust zone B 是本機 process（包括其他可能 dump 流量的工具）、C 是商業 LLM vendor、D 是聚合層加上游 vendor、複雜度跟洩漏面隨層數增加。&lt;/p></description><content:encoded><![CDATA[<p>寫 code 工作流常混用本地 LLM 跟雲端 LLM、混用的好處是組合兩邊優勢、代價是 prompt 在不同信任邊界之間流動。本章把「哪些 prompt 該留本機、哪些可以送雲端、怎麼配置才不會誤送」整理成可操作的分流判讀。本章是 <a href="/blog/llm/00-foundations/privacy-data-flow/" data-link-title="0.7 隱私 / 資安的資料流原理" data-link-desc="從「位置」到「資料流」的思考升級：信任邊界、合約模型、零信任原則套用到 LLM 工作流">0.7 隱私資料流原理</a>「資料流 thinking + 信任邊界」的具體落地、跟 <a href="/blog/llm/01-local-llm-services/vscode-continue-integration/" data-link-title="1.3 VS Code &#43; Continue.dev 整合" data-link-desc="安裝 Continue 擴充套件、config.json 設定、Cmd&#43;L 對話 / Cmd&#43;I 行內編輯快捷鍵">1.3 VS Code + Continue.dev 整合</a> 的 multi-provider 配置直接對應。信任邊界詞彙見 backend <a href="/blog/backend/knowledge-cards/trust-boundary/" data-link-title="Trust Boundary" data-link-desc="說明系統哪些位置開始不能沿用原本的信任假設">trust-boundary</a> 卡、PII 跟資料分類見 backend <a href="/blog/backend/knowledge-cards/pii/" data-link-title="PII" data-link-desc="說明可識別個人的資料如何影響權限、遮罩、保留與稽核">pii</a> / <a href="/blog/backend/knowledge-cards/data-classification/" data-link-title="Data Classification" data-link-desc="說明資料分級如何決定保護、存取、保留與匯出規則">data-classification</a> 卡、API key 管理見 backend <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">secret-management</a> 卡。本章 framing 是個人 dev 視角；production 場景的 log / PII 治理見 <a href="/blog/backend/07-security-data-protection/llm-log-and-pii-governance/" data-link-title="LLM Log 與 PII 治理" data-link-desc="production LLM 服務的 prompt log 累積、PII 偵測與過濾、保留期限與合規對齊">backend/07 LLM log 與 PII 治理</a>。</p>
<p>讀完本章後、你應該能對自己的 IDE 工作流回答：每個 LLM provider 收到什麼 prompt、雲端服務的資料政策大致長怎樣、哪些任務該分到本地、哪些可以送雲端、配置誤送的常見路徑跟對應防護。</p>
<h2 id="本章目標">本章目標</h2>
<ol>
<li>認識「prompt 邊界」在多 provider 工作流的位置。</li>
<li>區分本地 LLM 跟雲端 LLM 在資料流上的差異。</li>
<li>認識主流雲端 LLM 服務的資料政策大致分類。</li>
<li>用「敏感度 × 任務類型」軸把工作流分流到本地或雲端。</li>
<li>認識多 provider 設定下、prompt 誤送的常見路徑跟對應防護。</li>
</ol>
<h2 id="prompt-邊界在哪">prompt 邊界在哪</h2>
<p>在多 provider 工作流下、prompt 邊界長這樣：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">                ┌───────────────────────────┐
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">                │  使用者 + 本機 codebase   │ ← trust zone A：完全本地
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">                └───────────────────────────┘
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">                            ↓ prompt
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">        ┌─────────────────────────────────────────┐
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        │  IDE LLM client（Continue.dev）         │
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        │   ↓ route by config                     │
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">        │   ├── 本地 model（Ollama / llama-server）│ ← trust zone B：仍在本機
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        │   ├── 商業雲端（Anthropic / OpenAI）     │ ← trust zone C：雲端 vendor
</span></span><span class="line"><span class="ln">10</span><span class="cl">        │   └── 第三方 LLM 聚合（OpenRouter etc.） │ ← trust zone D：聚合層 + 上游 vendor
</span></span><span class="line"><span class="ln">11</span><span class="cl">        └─────────────────────────────────────────┘</span></span></code></pre></div><p>每跨一條邊界、prompt 都會被另一個主體看到。trust zone B 是本機 process（包括其他可能 dump 流量的工具）、C 是商業 LLM vendor、D 是聚合層加上游 vendor、複雜度跟洩漏面隨層數增加。</p>
<h2 id="本地-llm-vs-雲端-llm-在資料流上的差異">本地 LLM vs 雲端 LLM 在資料流上的差異</h2>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>本地 LLM</th>
          <th>雲端 LLM</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>prompt 走向</td>
          <td>留本機</td>
          <td>送到 vendor、依政策可能 log / 訓練用</td>
      </tr>
      <tr>
          <td>模型權重</td>
          <td>在本機</td>
          <td>在 vendor</td>
      </tr>
      <tr>
          <td>帳號需求</td>
          <td>無</td>
          <td>需註冊、有 API key</td>
      </tr>
      <tr>
          <td>監管 / 合規</td>
          <td>跟本機資料保護一致</td>
          <td>跟 vendor 政策（GDPR、HIPAA 等）對齊</td>
      </tr>
      <tr>
          <td>商業機密內容</td>
          <td>較適合</td>
          <td>看 vendor 政策、enterprise plan 通常承諾不訓練</td>
      </tr>
      <tr>
          <td>大模型能力</td>
          <td>視本機硬體</td>
          <td>較高（GPT-5、Claude 等旗艦）</td>
      </tr>
      <tr>
          <td>反應速度</td>
          <td>視本機硬體</td>
          <td>視網路 + vendor</td>
      </tr>
      <tr>
          <td>持續成本</td>
          <td>一次硬體投入</td>
          <td>按 token / call 收費</td>
      </tr>
  </tbody>
</table>
<p>混用的好處：</p>
<ol>
<li><strong>敏感任務留本地</strong>：機密 codebase、PII、合約等不送雲端。</li>
<li><strong>能力受限任務送雲端</strong>：跨檔案重構、複雜推理用旗艦雲端模型。</li>
<li><strong>離線可用</strong>：本地當 fallback、雲端不可用時仍能基本運作。</li>
</ol>
<p>混用的風險：<strong>配置稍微錯一步、原本想留本地的 prompt 被誤送到雲端</strong>。</p>
<h2 id="主流雲端-llm-服務的資料政策大致分類">主流雲端 LLM 服務的資料政策（大致分類）</h2>
<p>各家雲端 LLM 服務的資料政策依方案跟版本變化、大致可以分成幾類：</p>
<table>
  <thead>
      <tr>
          <th>政策類別</th>
          <th>典型描述</th>
          <th>個人 dev 視角</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Enterprise / API 預設不訓練</td>
          <td>透過 API 送的內容不用於訓練、僅依條款保留</td>
          <td>商業 API 的常見預設、個人 dev 用 API key 通常套用</td>
      </tr>
      <tr>
          <td>Consumer 預設可能用於訓練</td>
          <td>ChatGPT.com、Claude.ai 等網頁版、預設可能用於訓練</td>
          <td>看清楚當前條款跟 opt-out 開關</td>
      </tr>
      <tr>
          <td>30 天 abuse log 保留</td>
          <td>為了 abuse detection 保留 30 天、之後刪除</td>
          <td>多數商業 API 的常見做法</td>
      </tr>
      <tr>
          <td>Zero retention（特殊方案）</td>
          <td>enterprise 或特殊申請、不保留任何內容</td>
          <td>個人 dev 通常用不到</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：上面是 2026 年 5 月主流商業 LLM 服務的常見政策分類、具體條款依 vendor、地區、方案、版本快速變化、且各家詞彙不一致（如「training」「improve our services」「abuse review」可能指不同範圍）。引用前以對應 vendor 的當前官方<a href="https://www.anthropic.com/legal/privacy">資料政策頁面</a>、<a href="https://openai.com/policies/">OpenAI Data Policy</a> 等為準。</p></blockquote>
<p>判讀重點不是「哪家最嚴」、是「我送進去的內容、貼合我的預期嗎」。</p>
<h2 id="按敏感度--任務類型分流">按敏感度 × 任務類型分流</h2>
<p>把工作流分流到本地或雲端的兩軸：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">敏感度軸：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  公開 / 一般 / 機密 / 高機密（PII、合約、未公開 codebase）
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">任務類型軸：
</span></span><span class="line"><span class="ln">5</span><span class="cl">  補完 / 解釋 / 重構 / 設計討論 / 端到端 agent</span></span></code></pre></div><p>對應的分流建議：</p>
<table>
  <thead>
      <tr>
          <th>任務 \ 敏感度</th>
          <th>公開 / 一般</th>
          <th>機密</th>
          <th>高機密（PII、合約、未公開核心）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>補完</td>
          <td>雲端或本地皆可、看速度</td>
          <td>本地優先</td>
          <td>本地、且 disable codebase RAG</td>
      </tr>
      <tr>
          <td>解釋程式碼</td>
          <td>雲端較流暢</td>
          <td>本地、視內容</td>
          <td>本地、避免送整檔</td>
      </tr>
      <tr>
          <td>跨檔案重構</td>
          <td>雲端旗艦能力較強</td>
          <td>看 enterprise plan 的政策</td>
          <td>本地、或人工切片送雲端</td>
      </tr>
      <tr>
          <td>設計討論</td>
          <td>雲端較流暢</td>
          <td>enterprise plan 或本地</td>
          <td>本地、且過濾掉具體 entity 名稱</td>
      </tr>
      <tr>
          <td>端到端 agent</td>
          <td>雲端旗艦</td>
          <td>本地、且降低 tool 副作用範圍</td>
          <td>不適合 agent、改用 chat-only 本地</td>
      </tr>
  </tbody>
</table>
<p>實務上的常見模式：</p>
<ol>
<li><strong>預設本地、特定任務開雲端</strong>：日常工作走本地、需要旗艦能力時手動切。</li>
<li><strong>預設雲端、敏感任務切本地</strong>：日常走雲端旗艦、開機密 repo 時切本地。</li>
<li><strong>依 repo 切</strong>：用 Continue.dev / IDE 工具的「per-workspace config」、每個 repo 自己決定。</li>
</ol>
<p>選哪種模式取決於工作流的敏感度分布。多數寫 code 個人 dev 屬於「一般 / 機密混合」、值得用模式 1 或模式 3。「哪個任務適合本地、哪個適合雲端」的任務面判讀見 <a href="/blog/llm/01-local-llm-services/expectation-management/" data-link-title="1.5 期望管理：本地 LLM 的擅長領域與分工" data-link-desc="本地 LLM 是免費的初階 pair programmer：辨識它的擅長領域、跟雲端旗艦做結構性分工">1.5 期望管理</a>、本章補上「分流之後的資料邊界」面。</p>
<h2 id="continuedev-多-provider-配置範例">Continue.dev 多 provider 配置範例</h2>
<p>Continue.dev 基礎安裝跟單一 provider config 見 <a href="/blog/llm/01-local-llm-services/vscode-continue-integration/" data-link-title="1.3 VS Code &#43; Continue.dev 整合" data-link-desc="安裝 Continue 擴充套件、config.json 設定、Cmd&#43;L 對話 / Cmd&#43;I 行內編輯快捷鍵">1.3 VS Code + Continue.dev 整合</a>、本節聚焦多 provider 共存下的安全性設計。下面是一個合理的 Continue.dev 配置範例、把本地 + 雲端混用、清楚標出每個 model 的走向：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="nt">&#34;models&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">      <span class="nt">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Local 30B MoE (default)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">      <span class="nt">&#34;provider&#34;</span><span class="p">:</span> <span class="s2">&#34;ollama&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">      <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;qwen3-30b-a3b&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">      <span class="nt">&#34;apiBase&#34;</span><span class="p">:</span> <span class="s2">&#34;http://localhost:11434&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">      <span class="nt">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Local 14B (fast)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">      <span class="nt">&#34;provider&#34;</span><span class="p">:</span> <span class="s2">&#34;ollama&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">      <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;qwen3-14b&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">      <span class="nt">&#34;apiBase&#34;</span><span class="p">:</span> <span class="s2">&#34;http://localhost:11434&#34;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">      <span class="nt">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Cloud Claude (premium only)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">      <span class="nt">&#34;provider&#34;</span><span class="p">:</span> <span class="s2">&#34;anthropic&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">      <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;claude-sonnet-4-6&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">      <span class="nt">&#34;apiKey&#34;</span><span class="p">:</span> <span class="s2">&#34;${env:ANTHROPIC_API_KEY}&#34;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">  <span class="nt">&#34;tabAutocompleteModel&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="nt">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Local autocomplete&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="nt">&#34;provider&#34;</span><span class="p">:</span> <span class="s2">&#34;ollama&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;qwen3-14b&#34;</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>關鍵設計：</p>
<ol>
<li><strong>預設模型是本地</strong>：list 第一個是 local、tabAutocomplete 也是 local。</li>
<li><strong>雲端模型 title 明確標記</strong>：「Cloud Claude」開頭、避免選錯。</li>
<li><strong>autocomplete 永遠本地</strong>：補完的 prompt 流量大、autocomplete 屬於高頻、留本地。</li>
<li><strong>API key 從環境變數</strong>：不寫死在 config 裡、避免 commit 進 git。</li>
</ol>
<blockquote>
<p><strong>事實查核註</strong>：Continue.dev 的 config 格式跟 provider 支援度依版本變化、本範例為示意、實際引用以當前 Continue.dev 官方文件為準。</p></blockquote>
<h2 id="prompt-誤送的常見路徑">prompt 誤送的常見路徑</h2>
<p>個人 dev 場景下常見的 prompt 誤送路徑：</p>
<ol>
<li><strong>預設 model 設成雲端、按了 hotkey 沒看到當前 model</strong>：把寫到一半的機密 prompt 送到雲端。對應防護：預設改本地、雲端 model 用名稱前綴明確。</li>
<li><strong>autocomplete 設成雲端</strong>：補完每幾秒就觸發、prompt 包含當前游標附近 code、流量大且持續。對應防護：autocomplete 必定本地。</li>
<li><strong>codebase RAG 索引到 <code>.env</code> / secrets</strong>：RAG 把 secret 加進 prompt、再送雲端。對應防護：IDE search exclude 加上 <code>.env</code>、<code>*.key</code>、<code>secrets/</code>、<code>.aws/</code>。RAG 把外部內容引入 prompt 的整體機制與失敗模式見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a>。</li>
<li><strong>多 client 同時跑、key 共用</strong>：Cursor / Continue.dev / Claude Code 等多 client 共用 API key、難追是哪個 client 的流量。對應防護：給每個 client 各自的 API key、有問題能追溯。</li>
<li><strong>聚合服務不知道實際送到哪</strong>：用 OpenRouter / together.ai 等聚合層、prompt 經過聚合層後送到上游 vendor、上游可能是不同 region 不同政策。對應防護：個人 dev 場景傾向不用聚合、直接接 vendor。</li>
<li><strong>forgot prompt history 含 sensitive content</strong>：某次貼了機密內容後、後續同 conversation 都帶著、不知不覺重複送。對應防護：機密 prompt 用獨立 conversation、用完清空。</li>
</ol>
<h2 id="個人-dev-場景的最低防護建議">個人 dev 場景的最低防護建議</h2>
<ol>
<li><strong>預設模型設成本地</strong>：避免誤觸發雲端。</li>
<li><strong>autocomplete 必定本地</strong>：流量大、持續、適合本機處理。</li>
<li><strong>API key 從環境變數讀、不寫死 config</strong>：dotfile commit 不會洩漏。</li>
<li><strong>codebase search exclude <code>.env</code> / secrets 路徑</strong>：避免 RAG 索引到 secret。</li>
<li><strong>看完 prompt 內容再送雲端</strong>：對重要任務、value 不大但風險高時 prefer 本地。</li>
<li><strong>不同 client 用不同 API key</strong>：流量追溯。</li>
<li><strong>機密 prompt 用獨立 conversation</strong>：用完清空、不污染後續。</li>
</ol>
<h2 id="雲端-vendor-的-enterprise-plan-選擇">雲端 vendor 的 enterprise plan 選擇</h2>
<p>當個人 dev 工作流穩定後、若要把雲端 LLM 用得更深、可以評估 enterprise plan：</p>
<table>
  <thead>
      <tr>
          <th>Plan 類型</th>
          <th>典型差異</th>
          <th>個人 dev 適用性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Consumer / Free</td>
          <td>預設可能用於訓練、有 opt-out</td>
          <td>不適合機密內容</td>
      </tr>
      <tr>
          <td>API key（pay-as-you-go）</td>
          <td>通常預設不訓練、保留 30 天 abuse log</td>
          <td>多數個人 dev 用這個</td>
      </tr>
      <tr>
          <td>Team / Pro 訂閱</td>
          <td>多人共用、可能有額外 data control</td>
          <td>個人或小團隊適用</td>
      </tr>
      <tr>
          <td>Enterprise</td>
          <td>zero retention、SLA、客製合約</td>
          <td>個人 dev 通常用不到</td>
      </tr>
  </tbody>
</table>
<p>選擇判讀：個人 dev 主要看「API key 預設政策」、若不夠用、再評估升級。</p>
<h2 id="給讀者的跨邊界判讀流程">給讀者的跨邊界判讀流程</h2>
<p>每次設新工作流 / 換 LLM client / 加新 model 時的判讀流程：</p>
<ol>
<li><strong>盤點 model 列表</strong>：每個 model 是本地還是雲端、走哪家 vendor。</li>
<li><strong>看 vendor 的當前政策</strong>：別憑印象、看當前官方文件。</li>
<li><strong>設定 default model + autocomplete model</strong>：default 跟 autocomplete 是高頻路徑、優先本地。</li>
<li><strong>加 codebase RAG exclude</strong>：把 secret / sensitive path 排除。</li>
<li><strong>跑簡單測試</strong>：開個假機密 prompt（如「我的 SSH key 是 fake-key-test」）、觀察 client log 跟 vendor dashboard、確認流量去向符合預期。</li>
</ol>
<h2 id="下一章">下一章</h2>
<p><strong>靜態網站 / 沒 backend 場景的 prompt 邊界</strong>（API key 暴露、CORS、SaaS 信任、client-side abuse）見 <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 / serverless RAG deployment</a> 的資安段。</p>
<p>下一章：<a href="/blog/llm/06-security/routing-to-production-security/" data-link-title="6.5 跨進 production 的 routing 中樞" data-link-desc="個人 dev → 團隊 → production LLM 服務的三層演化、跟 backend/07 對應卡片的 routing 清單">6.5 跨進 production 的 routing 中樞</a>、整合本模組到 backend/07 production 場景的路由。</p>
]]></content:encoded></item><item><title>模組七：資安與隱私</title><link>https://tarrragon.github.io/blog/monitoring/07-security-privacy/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/07-security-privacy/</guid><description>&lt;p>回答「蒐集的資料本身就是風險資產，怎麼保護」。三層防護：SDK 端 redaction → transport 加密 → collector access control。&lt;/p>
&lt;h2 id="待寫章節">待寫章節&lt;/h2>
&lt;ul>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> SDK redaction API 設計（預設 redaction rule + 自訂 pattern）&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> Transport 安全（HTTPS / basic auth / 同區網也要加密的理由）&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> Collector access control 實作（認證 / 授權 / access log）&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> 去識別化策略（IP 截斷 / user agent 簡化 / stack trace 路徑清理 / session UUID）&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> GDPR 最小化原則的工程落地&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> 「監控資料洩漏」的 threat model&lt;/li>
&lt;li>&lt;input checked="" disabled="" type="checkbox"> Client-side SDK 認證的根本限制（credential 必然暴露、多層緩解策略）&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/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">backend 07 資安&lt;/a>：server-side 的 secret management 跟本模組的 redaction 互補&lt;/li>
&lt;li>← &lt;a href="https://tarrragon.github.io/blog/ux-design/03-input-mechanism/" data-link-title="模組三：輸入機制設計" data-link-desc="Keyboard type / submit model / IME policy / special keys — 輸入機制是設計產物，影響 UI layout 和 protocol">ux-design 模組三 輸入機制&lt;/a>：IME 個人化學習 = secret 洩漏&lt;/li>
&lt;li>← &lt;a href="https://tarrragon.github.io/blog/testing/02-client-observability/" data-link-title="模組二：客戶端可觀測性" data-link-desc="連線生命週期 log、protocol 訊息 log、使用者行為 log — log 設計是功能規格的一部分">testing 模組二 客戶端可觀測性&lt;/a>：log 內容可能含 secret，需要 redaction&lt;/li>
&lt;li>→ &lt;a href="https://tarrragon.github.io/blog/monitoring/08-business-analytics/" data-link-title="模組八：行為資料的商業利用" data-link-desc="Funnel / Cohort / Attribution / A/B test / 推薦系統 / RFM — 從 debug 工具到商業資產的翻轉">monitoring 模組八&lt;/a>：去識別化是商業利用的入場條件&lt;/li>
&lt;li>待建連結 → &lt;code>compliance/&lt;/code>（隱私法規教學分類）&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>回答「蒐集的資料本身就是風險資產，怎麼保護」。三層防護：SDK 端 redaction → transport 加密 → collector access control。</p>
<h2 id="待寫章節">待寫章節</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> SDK redaction API 設計（預設 redaction rule + 自訂 pattern）</li>
<li><input checked="" disabled="" type="checkbox"> Transport 安全（HTTPS / basic auth / 同區網也要加密的理由）</li>
<li><input checked="" disabled="" type="checkbox"> Collector access control 實作（認證 / 授權 / access log）</li>
<li><input checked="" disabled="" type="checkbox"> 去識別化策略（IP 截斷 / user agent 簡化 / stack trace 路徑清理 / session UUID）</li>
<li><input checked="" disabled="" type="checkbox"> GDPR 最小化原則的工程落地</li>
<li><input checked="" disabled="" type="checkbox"> 「監控資料洩漏」的 threat model</li>
<li><input checked="" disabled="" type="checkbox"> Client-side SDK 認證的根本限制（credential 必然暴露、多層緩解策略）</li>
</ul>
<h2 id="跨分類引用">跨分類引用</h2>
<ul>
<li>→ <a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">backend 07 資安</a>：server-side 的 secret management 跟本模組的 redaction 互補</li>
<li>← <a href="/blog/ux-design/03-input-mechanism/" data-link-title="模組三：輸入機制設計" data-link-desc="Keyboard type / submit model / IME policy / special keys — 輸入機制是設計產物，影響 UI layout 和 protocol">ux-design 模組三 輸入機制</a>：IME 個人化學習 = secret 洩漏</li>
<li>← <a href="/blog/testing/02-client-observability/" data-link-title="模組二：客戶端可觀測性" data-link-desc="連線生命週期 log、protocol 訊息 log、使用者行為 log — log 設計是功能規格的一部分">testing 模組二 客戶端可觀測性</a>：log 內容可能含 secret，需要 redaction</li>
<li>→ <a href="/blog/monitoring/08-business-analytics/" data-link-title="模組八：行為資料的商業利用" data-link-desc="Funnel / Cohort / Attribution / A/B test / 推薦系統 / RFM — 從 debug 工具到商業資產的翻轉">monitoring 模組八</a>：去識別化是商業利用的入場條件</li>
<li>待建連結 → <code>compliance/</code>（隱私法規教學分類）</li>
</ul>
]]></content:encoded></item><item><title>0.7 隱私 / 資安的資料流原理</title><link>https://tarrragon.github.io/blog/llm/00-foundations/privacy-data-flow/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/00-foundations/privacy-data-flow/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/info-judgment-frames/" data-link-title="0.6 判讀本地 LLM 資訊的五個框架" data-link-desc="本地 LLM 資訊更新快，學會用版本、層級、變數、能力、資料流五個框架評估文章與宣稱">0.6 判讀框架五&lt;/a> 建立的反射是「隱私是資料流、不是位置」。本章把這個 framing 展開成可操作的設計原則：信任邊界該怎麼劃、本地推論 vs 雲端的合約模型差異、零信任原則套用到 LLM 工作流的具體做法、NDA / 企業合規場景的判讀框架。&lt;/p>
&lt;p>本章寫的是「無論工具怎麼演變、隱私設計都該這樣思考」的原理層。具體合規法規條文（GDPR、HIPAA、各地新法）、特定工具的 telemetry 設定（每家半年一變）不在本章——這些隨時間變、用本章建立的 framework 重新評估就好。本章是 framing；落地操作見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/" data-link-title="模組六：本地 LLM 的安全與權限" data-link-desc="個人 dev 在自己機器上跑本地 LLM 的安全議題：模型供應鏈、推論伺服器綁定、tool use 副作用、prompt injection 在 IDE、跨雲端 / 本地資料邊界">模組六 本地 LLM 的安全與權限&lt;/a>、把這些框架拆到推論伺服器綁定、tool use 權限、prompt injection、跨雲端邊界等具體決策。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>用資料流圖描述自己的 LLM 工作流、辨識每個 hop 的信任邊界。&lt;/li>
&lt;li>區分「物理保證」與「合約保證」兩種隱私模型的取捨。&lt;/li>
&lt;li>把零信任原則套用到 LLM 系統設計。&lt;/li>
&lt;li>對 NDA / 企業合規場景做出有條理的判讀、不只看「是否本地」。&lt;/li>
&lt;/ol>
&lt;h2 id="從位置-thinking到資料流-thinking">從「位置 Thinking」到「資料流 Thinking」&lt;/h2>
&lt;p>「跑在本地、所以隱私」這個直覺假設「位置」是隱私的唯一變數。實際上隱私風險來自整條資料流的每個節點、位置只是其中一個維度。&lt;/p>
&lt;p>把問題從「我的 prompt 是否離開機器」改成「我的 prompt 從打字到最終結果、經過哪些 process、儲存在哪、誰能看到」。後者覆蓋面廣得多：&lt;/p>
&lt;ul>
&lt;li>prompt 在 IDE 內被 cache？&lt;/li>
&lt;li>IDE 有沒有開雲端同步？&lt;/li>
&lt;li>推論伺服器 log 留多久？&lt;/li>
&lt;li>對話歷史存到哪？&lt;/li>
&lt;li>第三方 plugin 有沒有偷 access prompt？&lt;/li>
&lt;li>結果寫到磁碟後、有沒有被自動備份到 iCloud / Dropbox？&lt;/li>
&lt;/ul>
&lt;p>「位置 thinking」對所有這些都看不到——只要推論在本地就覺得安全。「資料流 thinking」把整條 hop 攤開、每個節點單獨評估。&lt;/p>
&lt;p>這個 shift 是隱私設計的根本前提。沒做這個 shift、其他設計都建立在錯誤假設上。&lt;/p>
&lt;h2 id="信任邊界的定義">信任邊界的定義&lt;/h2>
&lt;p>LLM 工作流通常跨多層信任邊界（IDE / 推論伺服器 / 雲端同步 / 第三方 plugin / LAN）、隱私設計的第一步是把這些邊界明確畫出來。信任邊界（trust boundary）的概念來自系統安全設計：「誰能看到什麼資料」的明確分隔。穿越邊界的資料需要明確的授權跟稽核；同邊界內的資料假設安全。&lt;/p>
&lt;p>本地推論的天然信任邊界是「我的 Mac」——資料在這個邊界內預設安全（除非機器本身被入侵）。但實際 LLM 工作流會穿透這個邊界：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>雲端同步穿透&lt;/strong>：VS Code 同步 settings、Notion 備份對話、iCloud 同步文件——資料從 Mac 走到雲、信任邊界被擴展到供應商。&lt;/li>
&lt;li>&lt;strong>Telemetry 穿透&lt;/strong>：IDE plugin、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a>、作業系統都可能送遙測資料、含 prompt 片段 / metadata。&lt;/li>
&lt;li>&lt;strong>第三方 plugin 穿透&lt;/strong>：裝的 VS Code extension、瀏覽器 plugin 都可能 access 同個 prompt context。&lt;/li>
&lt;li>&lt;strong>網路 expose 穿透&lt;/strong>：&lt;code>OLLAMA_HOST=0.0.0.0&lt;/code> 把本地伺服器暴露到 LAN、信任邊界從「我的 Mac」擴展到「整個區網」。&lt;/li>
&lt;/ul>
&lt;p>LLM 工作流通常有多層信任邊界、跟「我在本地跑」的單純直覺不一定一致。設計隱私時、先把所有信任邊界畫出來、再評估每個邊界的「誰能看到、能看到什麼」。&lt;/p>
&lt;p>信任邊界的判讀問題：&lt;/p>
&lt;ul>
&lt;li>這個 process 屬於哪個邊界內？&lt;/li>
&lt;li>跨邊界傳資料需要什麼授權？&lt;/li>
&lt;li>邊界外的 component 如果被入侵、能 access 到什麼？&lt;/li>
&lt;/ul>
&lt;p>這幾個問題答得清楚、隱私設計就有 ground truth；答得模糊、設計就建立在假設上。&lt;/p>
&lt;h2 id="本地-vs-雲端的合約模型">本地 vs 雲端的合約模型&lt;/h2>
&lt;p>本地推論跟雲端推論的隱私保證來自不同模型：&lt;/p>
&lt;h3 id="物理保證本地">物理保證（本地）&lt;/h3>
&lt;p>本地推論的隱私保證是「物理上資料留在這台機器」、可技術觀察：&lt;/p>
&lt;ul>
&lt;li>用 &lt;code>lsof&lt;/code>（list open files、看 process 持有的網路 socket）看推論伺服器的網路連線、確認沒對外送資料。&lt;/li>
&lt;li>用 &lt;code>tcpdump&lt;/code>（系統封包擷取工具）監聽流量、確認 prompt 沒外洩。&lt;/li>
&lt;li>看磁碟 IO、確認對話歷史沒被寫到雲端同步資料夾。&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>這些工具的能力邊界&lt;/strong>：&lt;code>lsof&lt;/code> / &lt;code>tcpdump&lt;/code> 給的是「常態流量觀察」、不是完整安全證明。編譯期注入、kernel-level exfiltration、DNS tunneling 等繞過手法仍可能規避這些觀察視角。國家級威脅模型或高 stakes 合規場景下、要再加程式碼簽章驗證、SELinux / EndpointSecurity policy、出口防火牆等更深的控制；個人 / 中小企業場景下、這三個工具的觀察通常足以建立日常的信心。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/00-foundations/info-judgment-frames/" data-link-title="0.6 判讀本地 LLM 資訊的五個框架" data-link-desc="本地 LLM 資訊更新快，學會用版本、層級、變數、能力、資料流五個框架評估文章與宣稱">0.6 判讀框架五</a> 建立的反射是「隱私是資料流、不是位置」。本章把這個 framing 展開成可操作的設計原則：信任邊界該怎麼劃、本地推論 vs 雲端的合約模型差異、零信任原則套用到 LLM 工作流的具體做法、NDA / 企業合規場景的判讀框架。</p>
<p>本章寫的是「無論工具怎麼演變、隱私設計都該這樣思考」的原理層。具體合規法規條文（GDPR、HIPAA、各地新法）、特定工具的 telemetry 設定（每家半年一變）不在本章——這些隨時間變、用本章建立的 framework 重新評估就好。本章是 framing；落地操作見 <a href="/blog/llm/06-security/" data-link-title="模組六：本地 LLM 的安全與權限" data-link-desc="個人 dev 在自己機器上跑本地 LLM 的安全議題：模型供應鏈、推論伺服器綁定、tool use 副作用、prompt injection 在 IDE、跨雲端 / 本地資料邊界">模組六 本地 LLM 的安全與權限</a>、把這些框架拆到推論伺服器綁定、tool use 權限、prompt injection、跨雲端邊界等具體決策。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>用資料流圖描述自己的 LLM 工作流、辨識每個 hop 的信任邊界。</li>
<li>區分「物理保證」與「合約保證」兩種隱私模型的取捨。</li>
<li>把零信任原則套用到 LLM 系統設計。</li>
<li>對 NDA / 企業合規場景做出有條理的判讀、不只看「是否本地」。</li>
</ol>
<h2 id="從位置-thinking到資料流-thinking">從「位置 Thinking」到「資料流 Thinking」</h2>
<p>「跑在本地、所以隱私」這個直覺假設「位置」是隱私的唯一變數。實際上隱私風險來自整條資料流的每個節點、位置只是其中一個維度。</p>
<p>把問題從「我的 prompt 是否離開機器」改成「我的 prompt 從打字到最終結果、經過哪些 process、儲存在哪、誰能看到」。後者覆蓋面廣得多：</p>
<ul>
<li>prompt 在 IDE 內被 cache？</li>
<li>IDE 有沒有開雲端同步？</li>
<li>推論伺服器 log 留多久？</li>
<li>對話歷史存到哪？</li>
<li>第三方 plugin 有沒有偷 access prompt？</li>
<li>結果寫到磁碟後、有沒有被自動備份到 iCloud / Dropbox？</li>
</ul>
<p>「位置 thinking」對所有這些都看不到——只要推論在本地就覺得安全。「資料流 thinking」把整條 hop 攤開、每個節點單獨評估。</p>
<p>這個 shift 是隱私設計的根本前提。沒做這個 shift、其他設計都建立在錯誤假設上。</p>
<h2 id="信任邊界的定義">信任邊界的定義</h2>
<p>LLM 工作流通常跨多層信任邊界（IDE / 推論伺服器 / 雲端同步 / 第三方 plugin / LAN）、隱私設計的第一步是把這些邊界明確畫出來。信任邊界（trust boundary）的概念來自系統安全設計：「誰能看到什麼資料」的明確分隔。穿越邊界的資料需要明確的授權跟稽核；同邊界內的資料假設安全。</p>
<p>本地推論的天然信任邊界是「我的 Mac」——資料在這個邊界內預設安全（除非機器本身被入侵）。但實際 LLM 工作流會穿透這個邊界：</p>
<ul>
<li><strong>雲端同步穿透</strong>：VS Code 同步 settings、Notion 備份對話、iCloud 同步文件——資料從 Mac 走到雲、信任邊界被擴展到供應商。</li>
<li><strong>Telemetry 穿透</strong>：IDE plugin、<a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a>、作業系統都可能送遙測資料、含 prompt 片段 / metadata。</li>
<li><strong>第三方 plugin 穿透</strong>：裝的 VS Code extension、瀏覽器 plugin 都可能 access 同個 prompt context。</li>
<li><strong>網路 expose 穿透</strong>：<code>OLLAMA_HOST=0.0.0.0</code> 把本地伺服器暴露到 LAN、信任邊界從「我的 Mac」擴展到「整個區網」。</li>
</ul>
<p>LLM 工作流通常有多層信任邊界、跟「我在本地跑」的單純直覺不一定一致。設計隱私時、先把所有信任邊界畫出來、再評估每個邊界的「誰能看到、能看到什麼」。</p>
<p>信任邊界的判讀問題：</p>
<ul>
<li>這個 process 屬於哪個邊界內？</li>
<li>跨邊界傳資料需要什麼授權？</li>
<li>邊界外的 component 如果被入侵、能 access 到什麼？</li>
</ul>
<p>這幾個問題答得清楚、隱私設計就有 ground truth；答得模糊、設計就建立在假設上。</p>
<h2 id="本地-vs-雲端的合約模型">本地 vs 雲端的合約模型</h2>
<p>本地推論跟雲端推論的隱私保證來自不同模型：</p>
<h3 id="物理保證本地">物理保證（本地）</h3>
<p>本地推論的隱私保證是「物理上資料留在這台機器」、可技術觀察：</p>
<ul>
<li>用 <code>lsof</code>（list open files、看 process 持有的網路 socket）看推論伺服器的網路連線、確認沒對外送資料。</li>
<li>用 <code>tcpdump</code>（系統封包擷取工具）監聽流量、確認 prompt 沒外洩。</li>
<li>看磁碟 IO、確認對話歷史沒被寫到雲端同步資料夾。</li>
</ul>
<p><strong>這些工具的能力邊界</strong>：<code>lsof</code> / <code>tcpdump</code> 給的是「常態流量觀察」、不是完整安全證明。編譯期注入、kernel-level exfiltration、DNS tunneling 等繞過手法仍可能規避這些觀察視角。國家級威脅模型或高 stakes 合規場景下、要再加程式碼簽章驗證、SELinux / EndpointSecurity policy、出口防火牆等更深的控制；個人 / 中小企業場景下、這三個工具的觀察通常足以建立日常的信心。</p>
<p>物理保證的特性：</p>
<ul>
<li><strong>可單機驗證</strong>：不需要信任供應商、能用本地工具觀察流量。</li>
<li><strong>能力上限受硬體限制</strong>：本地模型受 Mac 算力跟記憶體限制、能力比雲端旗艦低一個量級。</li>
<li><strong>不依賴合約承諾</strong>：供應商有沒有承諾「不訓練」「zero-retention」都跟本地推論無關——資料本來就沒去那裡。</li>
</ul>
<h3 id="合約保證雲端">合約保證（雲端）</h3>
<p>雲端推論的隱私保證是「供應商承諾不留資料、不訓練、合規 X 規範」、技術上單機不可驗證、靠合約與 audit 支撐：</p>
<ul>
<li>Anthropic、OpenAI 的企業方案明示 zero-retention、不訓練選項（2026 年 5 月當時的 ToS、雲端 ToS 半年一變、實際採用前以最新版為準）。</li>
<li>SOC 2、ISO 27001、HIPAA BAA 等合規認證提供第三方 audit。</li>
<li>供應商的 ToS / privacy policy 是法律承諾、違反可訴訟。</li>
</ul>
<p>合約保證的特性：</p>
<ul>
<li><strong>不可單機驗證</strong>：要信任供應商沒違反承諾、加上第三方 audit 補強。</li>
<li><strong>能力沒上限</strong>：能用上雲端最強模型（GPT-5、Claude Sonnet 4.6、Opus）、沒有硬體限制。</li>
<li><strong>受法律管轄影響</strong>：供應商所在管轄區的法律、未來變動會影響保證強度（如政府要求供應商交資料）。</li>
</ul>
<h3 id="兩種模型的取捨">兩種模型的取捨</h3>
<p>兩種模型不是「誰比較好」、是「在什麼情境下哪個適合」：</p>
<ul>
<li><strong>隱私要求極高 + 模型能力夠用</strong>：本地。物理保證可驗證、不需信任供應商。</li>
<li><strong>能力要求極高 + 隱私要求中等</strong>：雲端 + 合約保證。Claude / GPT 旗艦的能力本地短期內追不上。</li>
<li><strong>合規場景</strong>：看具體規範要求。HIPAA、PCI-DSS 等場景雲端 + BAA / DPA 合約 + technical control 是主流方案、不一定要本地。</li>
<li><strong>NDA + 客戶明示不得送雲</strong>：本地是預設、合約保證對「不得送雲」這條沒幫助。</li>
</ul>
<p>判讀「該選哪邊」不是 binary、是 spectrum：許多場景混用、敏感任務本地、需要能力的任務雲端 + 合約保證。混用模式有一個隱形 leak 風險：同一個 IDE 同時接本地與雲端 backend、prompt routing 設錯就會把該走本地的內容送到雲端。實作時要明確隔離（不同 workspace / 不同帳號 / 不同 plugin set）、用配置強制路由、而非依賴每次手動切換。Continue.dev 多 provider 設定的具體路由判讀見 <a href="/blog/llm/06-security/cross-cloud-local-data-boundary/" data-link-title="6.4 跨雲端 / 本地的資料邊界" data-link-desc="個人 dev 場景下混用雲端 LLM 跟本地 LLM 時的 prompt 洩漏點：Continue.dev 多 provider 設定、隱私資料流、按敏感度分流的判讀">6.4 跨雲端 / 本地的資料邊界</a>。</p>
<h2 id="零信任原則套用到-llm-工作流">零信任原則套用到 LLM 工作流</h2>
<p>零信任（zero trust）的核心是「不假設任何 component 是 trusted、每個 hop 都重新驗證」。傳統信任模型假設「邊界內安全」、零信任假設「邊界本身可能被穿透」、每次 access 都驗證。</p>
<p>套用到 LLM 工作流的具體實踐：</p>
<h3 id="不信任預設配置">不信任預設配置</h3>
<p>每個 component 的預設配置往往不是「最隱私」、是「最方便」。<code>OLLAMA_HOST</code> 預設 <code>127.0.0.1</code> 還算安全、但很多工具預設打開 telemetry、預設同步到雲端。在 NDA / 合規場景下、所有 component 的隱私相關設定通常需要逐項 review、預設值會根據場景調整。</p>
<h3 id="每個-hop-都評估">每個 hop 都評估</h3>
<p>不只是「我用 Ollama 所以隱私」、要評估從打字到結果的每個 hop：IDE telemetry、plugin 行為、推論伺服器 log、對話歷史儲存、檔案系統位置、雲端同步範圍。任何一個 hop 預設設定「外洩」、整條鏈的隱私就破。</p>
<h3 id="最小權限">最小權限</h3>
<p>每個 component 只給它必要的 access：</p>
<ul>
<li>推論伺服器：不需要存 prompt 歷史就關 log。</li>
<li>IDE plugin：不裝沒驗證的 third-party plugin。</li>
<li>雲端同步：個人場景白名單同步是低成本 default、NDA / 合規場景直接排除整個 LLM 相關目錄。</li>
</ul>
<p>「最小權限」需要主動設計、不會自動發生——預設都是「方便優先」。</p>
<h3 id="認假設不認直覺">認假設、不認直覺</h3>
<p>「跑在本地所以安全」是直覺、不是已驗證的事實。零信任要求每個假設都跑一次 audit 確認、用觀察取代感覺。</p>
<h2 id="資料流分析的具體做法">資料流分析的具體做法</h2>
<p>把抽象原則落地、要做資料流分析：把整個工作流畫成 graph、每個 node 是 process、每個 edge 是資料流動、標示資料類型跟流向。</p>
<p>具體步驟：</p>
<ol>
<li><strong>列出所有節點</strong>：使用者、IDE、IDE plugin、推論伺服器、模型、磁碟、雲端服務、第三方 service。</li>
<li><strong>畫出所有 edge</strong>：誰送資料給誰、什麼類型的資料、什麼觸發。</li>
<li><strong>標示信任邊界</strong>：哪些節點屬同一個邊界、邊界之間的 edge 標出來。</li>
<li><strong>每個跨邊界 edge 評估三個問題</strong>：
<ul>
<li>誰能看到流過這條 edge 的資料？</li>
<li>儲存多久？</li>
<li>會不會再轉送出去？</li>
</ul>
</li>
<li><strong>找出風險集中點</strong>：常見集中點是 IDE telemetry、雲端同步、第三方 plugin。</li>
</ol>
<p>這個分析做完、隱私風險不再是抽象的「會不會洩漏」、是具體的「哪個 edge 在洩漏什麼」。修補策略也跟著具體：關 telemetry、移除特定 plugin、改設定。</p>
<p>實務做這個分析、第一次通常會發現預期外的 edge——例如「我以為對話歷史只在本地、結果發現 IDE 的 sync settings 把它送到雲」、「我以為這個 plugin 只 access code、結果它也送 prompt 給自家 analytics」。</p>
<h2 id="nda--企業合規場景的判讀框架">NDA / 企業合規場景的判讀框架</h2>
<p>NDA 跟企業合規場景的隱私要求比個人使用嚴格、判讀方式：</p>
<h3 id="nda-場景">NDA 場景</h3>
<ul>
<li><strong>核心要求</strong>：客戶明示「不得送第三方 AI 服務」、本地是預設選擇。</li>
<li><strong>不夠的地方</strong>：本地推論只保證模型呼叫不出去、要 audit 整條資料流（IDE telemetry、雲端同步、plugin 行為）。</li>
<li><strong>常見的事故</strong>：以為 Ollama 跑就安全、但 Cursor / Copilot 同時開著還送 prompt 給自家 service、NDA 已穿透。</li>
<li><strong>強化做法</strong>：NDA 客戶程式碼專案開獨立 IDE workspace、停雲端同步、移除第三方 plugin、明確隔離。</li>
</ul>
<h3 id="企業合規場景">企業合規場景</h3>
<p>不同規範保護的核心點不同、每條規範需對應到該規範要求的 control、避免用單一 mitigation 一網打盡的做法：</p>
<table>
  <thead>
      <tr>
          <th>規範</th>
          <th>核心保護點</th>
          <th>常見對位 control</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HIPAA</td>
          <td>健康資料（PHI）的接觸與儲存</td>
          <td>雲端供應商簽 BAA（Business Associate Agreement）+ 加密 + audit log</td>
      </tr>
      <tr>
          <td>PCI-DSS</td>
          <td>信用卡 cardholder data 的網路 segmentation</td>
          <td>把處理卡號的環境隔離、避免任意 process 接觸</td>
      </tr>
      <tr>
          <td>SOC 2</td>
          <td>服務組織的安全 / 可用 / 機密性整體控制</td>
          <td>跨組織技術 + 流程控制、用第三方 audit 驗證</td>
      </tr>
      <tr>
          <td>GDPR</td>
          <td>資料主體的存取 / 刪除 / 移植權</td>
          <td>DPA（Data Processing Agreement）+ 資料分類 + 主體請求流程</td>
      </tr>
  </tbody>
</table>
<p>判讀流程：列合規要求 → 對應資料流節點 → 找出缺哪個保護 → 補上技術或合約控制。本地推論滿足「資料留在內部」這條、但通常仍需要 audit log、access control、retention policy 等補強；雲端 + BAA / DPA + zero-retention 是另一條合規路徑、看規範允許哪條再做選擇。</p>
<h3 id="個人--一般工作場景">個人 + 一般工作場景</h3>
<ul>
<li>多數場景隱私風險中等、合理控制就夠。</li>
<li>預設關掉明顯外洩管道（telemetry、雲端同步敏感內容）、敏感任務本地、其他雲端、就 cover 90% 場景。</li>
<li>過度設計反而生產力大幅下降、得不償失。</li>
</ul>
<p>判讀框架的核心不是「該不該做隱私」、是「該做到什麼程度」。NDA / 合規場景要做到嚴、個人場景做到合理、過度都是浪費。</p>
<h2 id="常見的隱私邊界穿透">常見的隱私邊界穿透</h2>
<p>下列五個穿透模式都符合「位置看似安全、資料流卻外洩」的 pattern、即使用本地推論仍會破隱私：</p>
<h3 id="ide-雲端同步">IDE 雲端同步</h3>
<p>VS Code、JetBrains 系列預設可能開 settings sync、把對話歷史、recent files、command history 同步到雲。對話歷史尤其敏感——可能含 prompt 跟 LLM 回應全文。</p>
<p>判讀訊號：登入帳號後、跨機器 settings 自動同步——這條 pipe 通常也帶其他資料。</p>
<p>緩解：明確查看 sync 範圍、敏感場景關閉 sync 或開選擇性 sync（只同步配置、不同步歷史）。</p>
<h3 id="第三方-plugin-偷送-prompt">第三方 plugin 偷送 prompt</h3>
<p>裝 VS Code extension 時、權限模型較寬：理論上 plugin 能 access 整個 workspace、含 prompt 跟 LLM 回應。多數 plugin 安全、但供應鏈攻擊或惡意 plugin 存在。</p>
<p>判讀訊號：plugin 不是 verified publisher、下載量少、permission 列表廣。</p>
<p>緩解：敏感場景只用 verified plugin、定期 audit 已裝 plugin、移除不必要的。完整 tool use / MCP server 信任邊界見 <a href="/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 與 MCP server 的權限模型</a>、IDE 場景的 prompt injection 攻擊面（codebase / 外部文件 / 剪貼簿）見 <a href="/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3</a>。</p>
<h3 id="open-webui-對話歷史備份">Open WebUI 對話歷史備份</h3>
<p>Open WebUI（常見的本地 Web 對話介面、通常以 Docker 部署）把對話歷史存本機 SQLite、預設安全。但很多人把 <code>~/.openwebui</code> 放在 Dropbox / iCloud 同步目錄、歷史間接同步到雲。</p>
<p>判讀訊號：home directory 整個被雲端服務同步。</p>
<p>緩解：明確排除 LLM 相關目錄、或把 LLM 資料移到不被同步的位置。</p>
<h3 id="ollama_host0000-暴露區網"><code>OLLAMA_HOST=0.0.0.0</code> 暴露區網</h3>
<p>把 Ollama 從 <a href="/blog/llm/knowledge-cards/port-and-localhost/" data-link-title="Port 與 Localhost" data-link-desc="TCP port 與 listen address 如何決定 API server 的對外暴露範圍"><code>127.0.0.1</code></a> 改成 <code>0.0.0.0</code> 是常見配置（讓區網其他機器接）、但等於把本地 LLM 暴露在 LAN 上。風險視 LAN trust level 而定：純自家信任裝置的家用網路風險低、有 IoT / 訪客機 / 公共 Wi-Fi 的 LAN 環境風險顯著上升（IoT 裝置常被植入、預設要放在 untrusted segment、用 VLAN 或 firewall 隔離後再評估能否互通）。</p>
<p>判讀訊號：能從另一台機器 curl <code>&lt;你的 Mac IP&gt;:11434</code> 成功。</p>
<p>緩解：純自家信任裝置的 LAN 接受、混合 trust LAN 用防火牆規則限定 source IP、公共 Wi-Fi 改回 <code>127.0.0.1</code> 或用 SSH tunnel 隧道到遠端機器。完整綁定模式（loopback / LAN / reverse proxy + auth）跟誤開放後的後果見 <a href="/blog/llm/06-security/inference-server-binding/" data-link-title="6.1 推論伺服器的綁定與暴露範圍" data-link-desc="個人 dev 場景下 llama-server / Ollama / LM Studio 的 bind address 判讀：127.0.0.1 vs LAN vs 反代、預設安全、誤開放給內網的後果">6.1 推論伺服器的綁定與暴露範圍</a>。</p>
<h3 id="ide-plugin-同時送雲">IDE Plugin 同時送雲</h3>
<p>Cursor 預設 telemetry 強、Copilot 本來就送 prompt 給 GitHub。即使在這些 IDE 內用 Continue.dev 接本地 Ollama、IDE 本身可能仍送 prompt 給自家 service。</p>
<p>判讀訊號：IDE 是「雲端 AI 為主」的工具、本地 LLM 接入只是附加功能。</p>
<p>緩解：敏感場景用「本地 AI 為主」的 IDE（如 VS Code + Continue.dev）、不用混合的雲端 IDE。跨 provider 切換的具體 routing 設計見 <a href="/blog/llm/06-security/cross-cloud-local-data-boundary/" data-link-title="6.4 跨雲端 / 本地的資料邊界" data-link-desc="個人 dev 場景下混用雲端 LLM 跟本地 LLM 時的 prompt 洩漏點：Continue.dev 多 provider 設定、隱私資料流、按敏感度分流的判讀">6.4 跨雲端 / 本地的資料邊界</a>。</p>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>「資料流 thinking」對「位置 thinking」的優越性。</li>
<li>信任邊界的定義跟畫法。</li>
<li>物理保證 vs 合約保證的雙模型 framing。</li>
<li>零信任原則的四個套用實踐。</li>
<li>資料流分析的 5 步驟方法。</li>
<li>NDA / 合規 / 個人三類場景的判讀框架。</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>具體合規法規（GDPR、HIPAA、CCPA、各國新法會持續更新）。</li>
<li>特定工具的隱私行為（IDE / 雲端服務的 ToS、telemetry policy 會調整）。</li>
<li>雲端供應商的合約細節（BAA / DPA / SCC 條款會 evolve）。</li>
<li>「常見穿透模式」的具體例子（會隨工具生態變）。</li>
</ul>
<p>新工具、新法規、新雲端服務出來時、回到本章的方法重新跑一遍資料流分析、信任邊界評估——framework 不變、實例更新。</p>
<h2 id="下一步">下一步</h2>
<p>下一步：<a href="/blog/llm/01-local-llm-services/" data-link-title="模組一：本地 LLM 服務的安裝與應用" data-link-desc="Ollama、LM Studio、llama.cpp 的安裝與差異、VS Code &#43; Continue.dev 整合、模型選型與期望管理">模組一：本地 LLM 服務的安裝與應用</a>（Apple Silicon Mac）或 <a href="/blog/llm/05-discrete-gpu/" data-link-title="模組五：Windows / Linux &#43; 獨立 GPU" data-link-desc="消費級 PC（Windows / Linux &#43; NVIDIA / AMD 獨立 GPU）跑本地 LLM 的硬體判讀、MoE CPU 卸載、KV cache 量化與 llama.cpp 調參">模組五：Windows / Linux + 獨立 GPU</a> 把心智模型落到實際操作。模組一 / 五跑穩之後、回到 <a href="/blog/llm/06-security/" data-link-title="模組六：本地 LLM 的安全與權限" data-link-desc="個人 dev 在自己機器上跑本地 LLM 的安全議題：模型供應鏈、推論伺服器綁定、tool use 副作用、prompt injection 在 IDE、跨雲端 / 本地資料邊界">模組六：本地 LLM 的安全與權限</a> 把本章建立的「資料流 thinking」「信任邊界」「物理 vs 合約保證」三組框架落到具體決策（伺服器綁定、tool use 權限、prompt injection、跨雲端 routing）。</p>
]]></content:encoded></item><item><title>LLM Log 與 PII 治理</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-log-and-pii-governance/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-log-and-pii-governance/</guid><description>&lt;p>本章的責任是把 LLM 服務的 prompt log / response log / context cache 在累積、儲存、保留、刪除四個階段的 PII 治理拆成可操作的判讀。通用詞彙見 backend &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/pii/" data-link-title="PII" data-link-desc="說明可識別個人的資料如何影響權限、遮罩、保留與稽核">pii&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/data-masking/" data-link-title="Data Masking" data-link-desc="說明敏感資料如何在顯示、匯出、log 與測試資料中降低暴露">data-masking&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/data-classification/" data-link-title="Data Classification" data-link-desc="說明資料分級如何決定保護、存取、保留與匯出規則">data-classification&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit-log&lt;/a> 卡；模型輸出虛構 PII 的特殊議題見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination&lt;/a> 卡。一般資料保護跟 masking 流程沿用 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 資料保護與遮罩治理&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/data-residency-deletion-and-evidence-chain/" data-link-title="7.11 資料駐留、刪除與證據鏈" data-link-desc="定義跨區資料駐留、刪除請求與可驗證證據鏈問題">7.8 資料居住地、刪除與證據鏈&lt;/a>、本章聚焦 LLM 場景下的特殊性：prompt 含豐富使用者意圖、response 可能 hallucinate 出 PII、KV cache 跟 context cache 是非典型 log 載體。&lt;/p>
&lt;h2 id="本章寫作邊界">本章寫作邊界&lt;/h2>
&lt;p>本章聚焦 production LLM 服務的 log / cache / context 中的 PII 治理特殊性。個人 dev 場景的隱私資料流見 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/privacy-data-flow/" data-link-title="0.7 隱私 / 資安的資料流原理" data-link-desc="從「位置」到「資料流」的思考升級：信任邊界、合約模型、零信任原則套用到 LLM 工作流">0.7 隱私資料流&lt;/a>；通用資料保護見 7.4；資料居住地與刪除證據鏈見 7.8。&lt;/p>
&lt;h2 id="本章-threat-scope">本章 threat scope&lt;/h2>
&lt;p>&lt;strong>In-scope&lt;/strong>：prompt log 累積的 PII、response log 中模型 hallucinate 出的 PII、context cache 跟 KV cache 中的殘留、跨地區資料居住地對應、log 保留期限與刪除證據。&lt;/p>
&lt;p>&lt;strong>Out-of-scope&lt;/strong>（路由到他章）:&lt;/p>
&lt;ul>
&lt;li>通用資料保護與 masking → &lt;a href="../data-protection-and-masking-governance/">7.4 data-protection-and-masking-governance&lt;/a>&lt;/li>
&lt;li>資料居住地與刪除證據鏈 → &lt;a href="../data-residency-deletion-and-evidence-chain/">7.8 data-residency-deletion-and-evidence-chain&lt;/a>&lt;/li>
&lt;li>通用 audit log → 通用 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit-log knowledge-card&lt;/a>&lt;/li>
&lt;li>multi-tenant log 隔離 → &lt;a href="../llm-multi-tenant-isolation/">llm-multi-tenant-isolation&lt;/a>&lt;/li>
&lt;li>偵測訊號 → &lt;a href="../llm-as-service-detection-coverage/">llm-as-service-detection-coverage&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="從本章到實作">從本章到實作&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Mechanism&lt;/strong>：問題節點表 → knowledge-card。&lt;/li>
&lt;li>&lt;strong>Delivery&lt;/strong>：交接路由 → &lt;code>05-deployment-platform / 08-incident-response&lt;/code>。&lt;/li>
&lt;/ul>
&lt;h2 id="llm-服務的-log-載體">LLM 服務的 log 載體&lt;/h2>
&lt;p>LLM 服務累積的 log / cache 比一般 service 多幾類載體：&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>Request log（API 層）&lt;/td>
 &lt;td>endpoint、status、tenant、latency&lt;/td>
 &lt;td>一般、跟普通 API service 一致&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prompt log&lt;/td>
 &lt;td>完整 prompt 內容（含 system / context / user message）&lt;/td>
 &lt;td>高、含使用者意圖、可能含 PII&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Response log&lt;/td>
 &lt;td>LLM 完整輸出&lt;/td>
 &lt;td>高、可能 hallucinate 出 PII&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Tool call log&lt;/td>
 &lt;td>tool name、arguments、result&lt;/td>
 &lt;td>高、tool 參數可能含 sensitive 內容&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>KV cache&lt;/td>
 &lt;td>推論時的 attention 暫存&lt;/td>
 &lt;td>中、跨 request 殘留可能洩漏&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Context cache / RAG&lt;/td>
 &lt;td>持久化的 context、embedding cache&lt;/td>
 &lt;td>高、含原始文件內容&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Telemetry / metric&lt;/td>
 &lt;td>tokens / cost / model / latency 等聚合&lt;/td>
 &lt;td>一般、用 tenant tag 隔離&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>跟一般 service 的差異點：&lt;strong>Prompt log / Response log 是新類別&lt;/strong>、它們含的不是 API meta-data、是使用者實際的「想法 / 內容」、隱私敏感度遠高於一般 API log。&lt;/p></description><content:encoded><![CDATA[<p>本章的責任是把 LLM 服務的 prompt log / response log / context cache 在累積、儲存、保留、刪除四個階段的 PII 治理拆成可操作的判讀。通用詞彙見 backend <a href="/blog/backend/knowledge-cards/pii/" data-link-title="PII" data-link-desc="說明可識別個人的資料如何影響權限、遮罩、保留與稽核">pii</a>、<a href="/blog/backend/knowledge-cards/data-masking/" data-link-title="Data Masking" data-link-desc="說明敏感資料如何在顯示、匯出、log 與測試資料中降低暴露">data-masking</a>、<a href="/blog/backend/knowledge-cards/data-classification/" data-link-title="Data Classification" data-link-desc="說明資料分級如何決定保護、存取、保留與匯出規則">data-classification</a>、<a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit-log</a> 卡；模型輸出虛構 PII 的特殊議題見 <a href="/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination</a> 卡。一般資料保護跟 masking 流程沿用 <a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 資料保護與遮罩治理</a> 跟 <a href="/blog/backend/07-security-data-protection/data-residency-deletion-and-evidence-chain/" data-link-title="7.11 資料駐留、刪除與證據鏈" data-link-desc="定義跨區資料駐留、刪除請求與可驗證證據鏈問題">7.8 資料居住地、刪除與證據鏈</a>、本章聚焦 LLM 場景下的特殊性：prompt 含豐富使用者意圖、response 可能 hallucinate 出 PII、KV cache 跟 context cache 是非典型 log 載體。</p>
<h2 id="本章寫作邊界">本章寫作邊界</h2>
<p>本章聚焦 production LLM 服務的 log / cache / context 中的 PII 治理特殊性。個人 dev 場景的隱私資料流見 <a href="/blog/llm/00-foundations/privacy-data-flow/" data-link-title="0.7 隱私 / 資安的資料流原理" data-link-desc="從「位置」到「資料流」的思考升級：信任邊界、合約模型、零信任原則套用到 LLM 工作流">0.7 隱私資料流</a>；通用資料保護見 7.4；資料居住地與刪除證據鏈見 7.8。</p>
<h2 id="本章-threat-scope">本章 threat scope</h2>
<p><strong>In-scope</strong>：prompt log 累積的 PII、response log 中模型 hallucinate 出的 PII、context cache 跟 KV cache 中的殘留、跨地區資料居住地對應、log 保留期限與刪除證據。</p>
<p><strong>Out-of-scope</strong>（路由到他章）:</p>
<ul>
<li>通用資料保護與 masking → <a href="../data-protection-and-masking-governance/">7.4 data-protection-and-masking-governance</a></li>
<li>資料居住地與刪除證據鏈 → <a href="../data-residency-deletion-and-evidence-chain/">7.8 data-residency-deletion-and-evidence-chain</a></li>
<li>通用 audit log → 通用 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit-log knowledge-card</a></li>
<li>multi-tenant log 隔離 → <a href="../llm-multi-tenant-isolation/">llm-multi-tenant-isolation</a></li>
<li>偵測訊號 → <a href="../llm-as-service-detection-coverage/">llm-as-service-detection-coverage</a></li>
</ul>
<h2 id="從本章到實作">從本章到實作</h2>
<ul>
<li><strong>Mechanism</strong>：問題節點表 → knowledge-card。</li>
<li><strong>Delivery</strong>：交接路由 → <code>05-deployment-platform / 08-incident-response</code>。</li>
</ul>
<h2 id="llm-服務的-log-載體">LLM 服務的 log 載體</h2>
<p>LLM 服務累積的 log / cache 比一般 service 多幾類載體：</p>
<table>
  <thead>
      <tr>
          <th>載體</th>
          <th>內容</th>
          <th>隱私敏感度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Request log（API 層）</td>
          <td>endpoint、status、tenant、latency</td>
          <td>一般、跟普通 API service 一致</td>
      </tr>
      <tr>
          <td>Prompt log</td>
          <td>完整 prompt 內容（含 system / context / user message）</td>
          <td>高、含使用者意圖、可能含 PII</td>
      </tr>
      <tr>
          <td>Response log</td>
          <td>LLM 完整輸出</td>
          <td>高、可能 hallucinate 出 PII</td>
      </tr>
      <tr>
          <td>Tool call log</td>
          <td>tool name、arguments、result</td>
          <td>高、tool 參數可能含 sensitive 內容</td>
      </tr>
      <tr>
          <td>KV cache</td>
          <td>推論時的 attention 暫存</td>
          <td>中、跨 request 殘留可能洩漏</td>
      </tr>
      <tr>
          <td>Context cache / RAG</td>
          <td>持久化的 context、embedding cache</td>
          <td>高、含原始文件內容</td>
      </tr>
      <tr>
          <td>Telemetry / metric</td>
          <td>tokens / cost / model / latency 等聚合</td>
          <td>一般、用 tenant tag 隔離</td>
      </tr>
  </tbody>
</table>
<p>跟一般 service 的差異點：<strong>Prompt log / Response log 是新類別</strong>、它們含的不是 API meta-data、是使用者實際的「想法 / 內容」、隱私敏感度遠高於一般 API log。</p>
<h2 id="分析模型">分析模型</h2>
<p>LLM log 治理依四個階段分析：</p>
<ol>
<li><strong>累積階段</strong>：哪些載體會累積什麼內容、累積速率多大。</li>
<li><strong>儲存階段</strong>：儲存位置（DB / S3 / SIEM）、加密、訪問權。</li>
<li><strong>保留階段</strong>：保留期限、保留期內的訪問規則。</li>
<li><strong>刪除階段</strong>：刪除觸發條件、刪除證據鏈、合規對應。</li>
</ol>
<h2 id="判讀流程">判讀流程</h2>
<p>判讀流程的責任是把「LLM 服務的 log」轉成「合規可審計的 log」。</p>
<ol>
<li>先盤點所有 log / cache 載體跟對應內容。</li>
<li>再確認 PII 偵測 / masking 在累積階段是否生效。</li>
<li>接著確認儲存跟訪問權跟一般資料保護一致。</li>
<li>最後確認保留期限跟刪除證據鏈跟資料居住地對齊。</li>
</ol>
<h2 id="問題節點案例觸發式">問題節點（案例觸發式）</h2>
<table>
  <thead>
      <tr>
          <th>問題節點</th>
          <th>判讀訊號</th>
          <th>風險後果</th>
          <th>前置控制面</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prompt log 含 PII 未 mask</td>
          <td>使用者貼信用卡 / 身分證號、log 完整保留</td>
          <td>隱私洩漏、合規違規（GDPR / HIPAA）</td>
          <td><a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">data-protection</a></td>
      </tr>
      <tr>
          <td>Response 含 hallucinated PII</td>
          <td>LLM 生成虛構電話 / 地址、log 保留</td>
          <td>模型「虛構」也算 PII 處理、合規範圍</td>
          <td><a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">data-protection</a></td>
      </tr>
      <tr>
          <td>KV cache 跨 request 殘留 PII</td>
          <td>inference engine 沒清 cache、下個 request 的 dump 看得到</td>
          <td>tenant 間隱私洩漏</td>
          <td><a href="/blog/backend/07-security-data-protection/llm-multi-tenant-isolation/" data-link-title="LLM 多租戶推論隔離" data-link-desc="production LLM 服務的多租戶隔離：KV cache 不共享、log / model artifact 隔離、跨用戶 prompt 洩漏面">llm-multi-tenant-isolation</a></td>
      </tr>
      <tr>
          <td>Context cache 跨 session 重用</td>
          <td>同 user 的 long context cache 被其他 session 共用</td>
          <td>個人 prompt 洩漏到其他 session</td>
          <td><a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">data-protection</a></td>
      </tr>
      <tr>
          <td>保留期限跟資料居住地不一致</td>
          <td>log 跨地區複製、不同地區保留期限不一</td>
          <td>合規對應失效、刪除無法執行</td>
          <td><a href="/blog/backend/07-security-data-protection/data-residency-deletion-and-evidence-chain/" data-link-title="7.11 資料駐留、刪除與證據鏈" data-link-desc="定義跨區資料駐留、刪除請求與可驗證證據鏈問題">data-residency</a></td>
      </tr>
      <tr>
          <td>刪除證據鏈缺失</td>
          <td>客戶要求刪除、無法證明已刪除所有副本</td>
          <td>合規違規、客戶投訴升級</td>
          <td><a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit-log</a></td>
      </tr>
      <tr>
          <td>Vendor 政策跟自家政策衝突</td>
          <td>用雲端 LLM、vendor log 30 天、自家承諾 7 天</td>
          <td>對外承諾無法兌現</td>
          <td><a href="/blog/backend/knowledge-cards/contract/" data-link-title="Boundary Contract" data-link-desc="說明跨邊界約定如何維持相容與可驗證">vendor-contract</a></td>
      </tr>
  </tbody>
</table>
<h2 id="常見風險邊界">常見風險邊界</h2>
<p>風險邊界的責任是界定何時 LLM log 治理已進入高壓狀態。</p>
<ul>
<li>Prompt log 含未 mask 的 PII 時、代表 PII 治理在累積階段失效。</li>
<li>KV cache / context cache 跨 tenant 共用時、代表 isolation 失效（亦見 <a href="/blog/backend/07-security-data-protection/llm-multi-tenant-isolation/" data-link-title="LLM 多租戶推論隔離" data-link-desc="production LLM 服務的多租戶隔離：KV cache 不共享、log / model artifact 隔離、跨用戶 prompt 洩漏面">llm-multi-tenant-isolation</a>）。</li>
<li>log 保留期限跟資料居住地政策不一致時、代表治理流程不收斂。</li>
<li>客戶刪除請求無法產生證據鏈時、代表合規對應失效。</li>
</ul>
<h2 id="llm-場景的特殊判讀">LLM 場景的特殊判讀</h2>
<p>LLM log 治理相對一般資料保護的特殊性：</p>
<ol>
<li><strong>Prompt 跟 Response 比 API log 隱私敏感度高一個量級</strong>：一般 API log 主要記 endpoint / status / latency、prompt log 記的是使用者實際「在問什麼」、Response log 是模型「在說什麼」。</li>
<li><strong>模型 hallucinate 的 PII 也是 PII</strong>：LLM 生成虛構的姓名 / 電話 / 地址、即使不對應真人、也屬於 PII 處理範圍、需要對應的 masking 跟保留政策。</li>
<li><strong>KV cache 是非典型 log 載體</strong>：傳統 log 治理工具不掃 GPU memory / RAM cache、但這些 cache 可能跨 request / 跨 tenant 殘留 PII；需要 inference engine 配合做 cache 清理。</li>
<li><strong>RAG context 是雙向載體</strong>：RAG 既把 corpus 注入 prompt（corpus 中的 PII 進 log）、也把 user query 注入 corpus（user query 變 future retrieval 的對象）；治理範圍要覆蓋雙向。</li>
<li><strong>vendor 政策直接影響合規承諾</strong>：用雲端 LLM 時、vendor 的 log 保留政策（如 30 天 abuse log）直接限制自家對下游客戶能承諾的最短保留期、合約鏈要對齊。</li>
<li><strong>abuse detection 跟 PII 治理的張力</strong>：abuse detection 需要 log prompt（看 abuse pattern）、PII 治理要求 minimize、兩者要在 mask 後 detection 跟全文 detection 中找平衡。</li>
</ol>
<h2 id="防禦設計的核心原則">防禦設計的核心原則</h2>
<ol>
<li><strong>累積階段做 PII detection + masking</strong>：log 寫入前過 PII detector、敏感欄位 mask 或不 log。</li>
<li><strong>儲存階段加密 + 訪問權對齊 IAM</strong>：跟一般敏感資料一致。</li>
<li><strong>保留期限明確 + 自動刪除</strong>：用 policy-driven 自動 lifecycle、不依賴人工。</li>
<li><strong>KV cache / context cache 跨 tenant 清理</strong>：inference engine 配合、tenant boundary 明確。</li>
<li><strong>刪除證據鏈</strong>：客戶刪除請求觸發時、產生 audit trail、能證明已刪除所有副本（包含 backup / log archive）。</li>
<li><strong>vendor 政策對齊</strong>：用雲端 LLM 時、vendor 的條款拉進自家政策一致審視。</li>
</ol>
<h2 id="案例觸發參考">案例觸發參考</h2>
<p>LLM log 治理的公開案例累積中、值得追蹤的方向：</p>
<ul>
<li>大型 LLM vendor 的 log 政策變更引發的合規震盪</li>
<li>模型 hallucinate 出真人 PII 的訴訟案例</li>
<li>KV cache 跨用戶洩漏的 incident 報告</li>
</ul>
<p>LLM-specific 案例累積後會補入 <code>red-team/cases/llm-log-pii/</code>。一般資料保護案例見 <a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 data-protection-and-masking-governance</a> 跟 <a href="/blog/backend/07-security-data-protection/data-residency-deletion-and-evidence-chain/" data-link-title="7.11 資料駐留、刪除與證據鏈" data-link-desc="定義跨區資料駐留、刪除請求與可驗證證據鏈問題">7.8 data-residency-deletion-and-evidence-chain</a>。</p>
<blockquote>
<p><strong>事實查核註</strong>：LLM log / PII 議題的具體 incident 跟法律判例累積還在早期、各 vendor 政策跟監管要求依時段快速變化、建議引用前以最新的監管文件（GDPR、CCPA、AI Act 等）跟 vendor 當前政策為準。</p></blockquote>
<h2 id="引用標準">引用標準</h2>
<table>
  <thead>
      <tr>
          <th>標準</th>
          <th>版本 / 年份</th>
          <th>適用場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GDPR</td>
          <td>2016/679</td>
          <td>歐盟 PII 治理</td>
      </tr>
      <tr>
          <td>CCPA / CPRA</td>
          <td>2020 / 2023</td>
          <td>加州 PII 治理</td>
      </tr>
      <tr>
          <td>EU AI Act</td>
          <td>2024</td>
          <td>AI 系統 PII 處理特殊規定</td>
      </tr>
      <tr>
          <td>NIST Privacy Framework</td>
          <td>1.0 (2020)</td>
          <td>隱私治理 reference</td>
      </tr>
      <tr>
          <td>OWASP LLM Top 10</td>
          <td>2025</td>
          <td>LLM06 Sensitive Information Disclosure</td>
      </tr>
  </tbody>
</table>
<p>引用版本與 cadence 規則見 <a href="/blog/report/security-citation-currency-and-precision/" data-link-title="Security 標準引用的時效性與精確度" data-link-desc="資安 citation 跟一般技術引用不同——best practice 時效短（MD5 / SHA-1 / bcrypt 100k / TLS 1.0 都曾是 best practice）、原文常被引用扭曲（conditional → unconditional drift）、版本不標 reader 會套用過時 spec。citation 同時涵蓋外部標準（OWASP / RFC / NIST / CIS）跟內部 citation（knowledge-cards / 跨章引用作為 control-of-record）；後者因無版本號 anchor 反而更易 silent drift / broken。每條 citation 必須附：版本 / 年份、引用句意可回溯、deprecated / superseded 標記、強度參數對應 actor 能力的 review trigger（外部）/ last-checked &#43; sync owner（內部）。">security-citation-currency-and-precision</a>。Last reviewed: 2026-05-12。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>通用資料保護：<a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 data-protection-and-masking-governance</a></li>
<li>資料居住地與刪除：<a href="/blog/backend/07-security-data-protection/data-residency-deletion-and-evidence-chain/" data-link-title="7.11 資料駐留、刪除與證據鏈" data-link-desc="定義跨區資料駐留、刪除請求與可驗證證據鏈問題">7.8 data-residency-deletion-and-evidence-chain</a></li>
<li>多租戶 isolation：<a href="/blog/backend/07-security-data-protection/llm-multi-tenant-isolation/" data-link-title="LLM 多租戶推論隔離" data-link-desc="production LLM 服務的多租戶隔離：KV cache 不共享、log / model artifact 隔離、跨用戶 prompt 洩漏面">llm-multi-tenant-isolation</a></li>
<li>偵測訊號：<a href="/blog/backend/07-security-data-protection/llm-as-service-detection-coverage/" data-link-title="LLM Service 偵測訊號覆蓋" data-link-desc="production LLM 服務的 detection 訊號設計：tool call 異常模式、prompt injection 觸發徵兆、abuse 跟濫用模式、跟既有 detection-coverage 框架的接合">llm-as-service-detection-coverage</a></li>
<li>事件案例工作流：<a href="/blog/backend/07-security-data-protection/incident-case-to-control-workflow/" data-link-title="7.16 從公開事故到工程 Workflow：案例如何回寫控制面" data-link-desc="建立公開事故如何轉成控制面失效樣式與 workflow 回寫的大綱">7.10 incident-case-to-control-workflow</a></li>
</ul>
]]></content:encoded></item></channel></rss>