從設計就顧到隱私
在資料庫層級強制的隔離、以使用者為單位的欄位加密金鑰,以及對端對端加密這一層到底給了你什麼、又沒給你什麼的誠實說明。
這一頁是寫來給人查證的。如果你經手的是別人的法律、移民或醫療事務,底下這些說法,你的客戶遲早會要你拿出證據。
兩道互相獨立的邊界
同一批資料上有兩道互相獨立的保證——任一道都不依賴另一道成立。
隔離是由資料庫強制的,不是靠應用程式碼。 資料列層級安全性代表:一個忘了加篩選條件的查詢,回傳的是空的,而不是別人的資料。應用層的範圍限縮,離資料外洩永遠只差一個被忘記的 WHERE;資料庫層級是另一個等級的保證,這也是平台把邊界放在那裡的原因。
加密則與它無關。 就算拿到資料庫存取權,對話與文件內容也仍然是密文。
加密封包
加密欄位以固定版面儲存:
Not to scale. 實務上密文佔絕大部分,標頭欄位只有寥寥幾個位元組。
這個版面帶出兩個結果。
金鑰可以輪替,不需要遷移。 版本號跟著密文走,所以一位使用者可以同時持有好幾把資料加密金鑰:新的寫入使用當前金鑰,讀取則挑出當初寫入時所用的那一把。輪替因此變成漸進式的重新加密,而不是要全世界停下來的大事——這很重要,因為需要停機的輪替機制,通常永遠不會被真的執行。
密文搬不了家。 AEAD 的附加驗證資料把每個值綁定到它的 (tenant, user, space, field)。把一段密文複製到另一列、另一個欄位或另一個租戶的紀錄裡,結果是解密失敗,而不是悄悄吐出內容——所以資料庫層級的竄改嘗試,不會變成資料外洩。
金鑰放在哪裡
每位使用者的資料加密金鑰由一把金鑰加密金鑰包覆,並藏在一層金鑰供應者抽象之後。目前的實作是從應用程式機密中讀取 KEK。這道接縫存在的意義,是讓 KMS、保管庫或以租戶為單位的自帶金鑰能透過設定接進來,而不必改動資料模型或任何呼叫端程式碼。
把現況講清楚:今天 KEK 是由應用程式持有的。這對目前的部署方式是恰當的,但它和「客戶自管金鑰」不是同一回事。
任何託管型智慧代理的極限,以及該怎麼辦
敏感對話可以加上一層端對端加密:用戶端送出一把臨時的 ECDH(P-256)公鑰,伺服器透過 ECDH 與 HKDF 推導出工作階段金鑰,串流的每一個區塊都以 AES-GCM 加密,並在瀏覽器端解密。它在 TLS 之上,進一步降低串流層的暴露。
它不是零知識,而且沒有任何託管型智慧代理做得到零知識。 這一點值得直白講出來,因為它是問題本身的性質,不是這套實作的缺陷:要從你的知識庫檢索,伺服器就必須把你的內容向量化並比對;要作答,就必須根據取回的段落生成。一個讀不到材料的系統,既搜不了它,也答不出來。「零知識的知識庫」本身就是矛盾,任何同時宣稱兩者的供應商,其中至少有一項講得很鬆。
所以誠實的問法不是「營運方能不能讀到內容」,而是營運方是誰。
在我們的雲端上,我們把暴露面壓到最小
- 內容以每位使用者專屬的金鑰靜態加密,把資料庫整份倒出來也讀不出東西。
- 隔離由資料庫強制執行,不是靠應用程式碼。
- 送進模型的只有當前訊息、為它取回的段落,以及該終端使用者的記憶——不會整份知識庫送出去,也絕不會送出另一位使用者的資料。
- 端對端這一層保護的是回應串流。
這確實顯著降低了暴露程度,但它不等於我們無法讀取一段對話。這句話,我們寧可由我們自己告訴你,而不是由你客戶的稽核人員告訴你。
要求是絕對的時候,就自己跑
如果你的義務代表內容真的一點都不能到第三方手上,答案不是更強的加密宣稱,而是一種我們不在路徑上的部署方式。
平台可以部署到你自己掌控的基礎設施,包括你自己的雲端帳號,並把模型端點指向你自行託管的模型。在這個配置下,你的文件與對話從不離開你的網路,而有存取權的營運方就是你自己。它比共用資源貴,這就是取捨:法遵是用基礎設施買來的,不是用形容詞買來的。
專屬部署怎麼劃定範圍、怎麼營運、怎麼計費,見企業方案。
有哪些東西會送給模型
回覆一則訊息時,送給模型的是:這則訊息、為它取回的段落,以及為該終端使用者取回的記憶。 不是整份知識庫,也絕不會是另一位使用者的資料——檢索在任何東西被組裝起來之前,就已經限縮在空間範圍內。
若你設定了自己的模型供應商,內容會依你與該供應商之間的約定送過去,適用的是他們的保留與訓練條款。那是你的合約,不是我們的,值得仔細讀。
刪除
刪除一份文件時,它對衍生記憶所貢獻的內容也會一併移除,而不是留下一條比來源活得更久的記憶,讓內容還能被撈回來。保留期限與帳號關閉時的刪除流程寫在隱私權政策,針對商業客戶的處理承諾寫在 DPA。
實務上的意義
- 查詢寫錯不可能暴露另一位客戶的對話,因為資料庫會直接拒絕。
- 資料庫被整份偷走,也拿不到可讀的內容。
- 金鑰可以在正常營運中輪替,所以輪替才會真的發生。
- 端對端這個選項是真的,但有其邊界——當要求是絕對的,答案是換一種部署模式,而不是對共用模式提出更強的宣稱。