Staging — 僅供部落格預覽。
跳至主要內容

Workers 被允許看見什麼

排程中

閱讀時間 7 分鐘 作者 NT²

零知識不是關於 HTTPS 的口號。它是邊緣的權限清單:Workers 可以儲存、路由、計費什麼—— 以及它們永遠不得得知什麼。

Workers 被允許看見什麼

主張:邊緣有權限清單,不是信任演說

多數產品把雲端說成「已加密」就停住。傳輸有 TLS。磁碟靜止時加密。儀表板亮綠勾。這些控制很重要。它們不是保管箱的安全模型。

NT² Vault 的邊緣主張更窄、也更有用:Cloudflare Workers 被允許看見帳號與帳單事實、公開身份材料,以及不透明的密文訊框——除此之外,任何能讓它們讀取你的保管箱的東西都不行。

這是一份權限清單。坐在 api.nt2.me 後面的 Workers 可以:

  • 以保管箱金鑰 DID 註冊雲端帳號,並儲存公開驗證材料;
  • 發出短挑戰、驗證簽章,並為同步與中繼路由核發工作階段;
  • 接受並回傳不透明的 replica 批次與附件訊框;
  • 保存權益與帳單狀態,好在不必開啟項目的前提下強制執行 NT² Premium 雲端同步;
  • 為共用中繼建立投遞詮釋資料索引(誰把密文寄給誰、到期、檢視上限)——絕不含解密後欄位。

它們不可以

  • 接收主密碼;
  • 持有 KDF 鹽值或密碼驗證器,好把資料庫傾印變成離線猜測裝置;
  • 解密項目負載、附件位元組或收件匣信封;
  • 變成可搜尋的雲端副本——標題、筆記、登入憑證或證件號碼;
  • 把在 se.nt2.me 的解鎖當成伺服器登入,去抓回足以打開閣樓的材料。

對這個產品而言,零知識意味著依建構而盲目:綱要與路由不含會迫使邊緣理解保管箱內容的欄位或端點。若功能需要明文,就在已持有金鑰的裝置上執行。

限制:「好幫手」邊緣會變成可讀保管箱

擴大 Workers 可見範圍的壓力持續存在,而且通常出於好意。

客服想要「只要最新五筆項目標題」好分流工單。分析想要明文類別做漏斗。還原想要伺服器持有的鹽值,好讓新手機「開箱即用」。搜尋想要確定性權杖,好讓雲端能回答查詢。管理主控台想要「檢視保管箱」按鈕——因為別家 SaaS 都有。

每個請求聽起來都像小例外。合在一起,就重建了我們拒絕的架構:一個碰巧旁邊還存了些密文的雲端應用。

還有第二條容易被低估的限制:來源與環境。預備環境的 Worker 若接受正式環境保管箱流量,或正式環境 API 仍暴露「為了遷移」的舊鹽值擷取,權限清單在實務上就崩了——即使行銷頁仍寫零知識。預備與正式必須是分開的主機與分開的綁定。正式環境的公開表面很清楚:保管箱應用在 se.nt2.me、API 在 api.nt2.me、行銷在 nt2.me、本部落格在 blog.nt2.me。預備環境落在 Cloudflare 的 Workers 預備主機上——對維運有用,不是使用者祕密的第二個正式閣樓。客戶端不得被教導「就這一次」去呼叫錯誤的環境。

因此限制是雙重的:

  1. 能力: 不要把會讓邊緣變成保管箱讀取者的資料交給它。
  2. 拓撲: 不要把預備與正式混在一起,讓「暫時」路徑變成永久信任破口。

任一失敗,權限清單就是戲碼。

設計:兩套綱要,一個盲目中繼

NT² 維持兩個不同的資料世界。

在裝置上,保管箱是結構化的本機資料庫:項目、附件詮釋資料、收件匣、聯絡人、同步游標,以及僅本機的解鎖材料。解密是短暫且在記憶體中。列表在本機分頁與搜尋。解鎖在客戶端衍生金鑰;鎖定則清除它們。

在邊緣,服務是帳號與中繼層。Cloudflare D1 帳號列持有服務身份與權益事實——不是保管箱明文。NT² Premium 雲端同步的 replica 協調以保管箱金鑰 DID 為鍵,讓一個身份對應一個同步中樞。物件儲存以不透明識別碼持有密文位元組。共用中繼為盲目投遞儲存投遞詮釋資料與密文 blob。WebSocket 通知說「有東西變了」,不是「這是你護照標題的預覽」。

為同步跨越網路的單位,是 replica 批次裡的不透明訊框——與可攜備份使用的同一家族密封位元組。Worker 儲存、排序並回傳訊框。它不會把它們解讀成銀行名稱、筆記內文或登入憑證 URL。

flowchart LR
  subgraph device [裝置]
    Unlock[本機解鎖]
    Vault[(本機保管箱)]
    Encrypt[上傳前加密]
  end

  subgraph edge [邊緣 Workers]
    Auth[保管箱金鑰 DID 工作階段]
    Meta[(帳號/帳單詮釋資料)]
    Frames[不透明同步訊框]
  end

  Unlock --> Vault
  Vault --> Encrypt
  Encrypt --> Auth
  Auth --> Meta
  Auth --> Frames

驗證強化這道分割。打開保管箱是本機事件:主密碼(或其他本機因素)在裝置上衍生金鑰。與雲端交談是另一件事:已解鎖的保管箱以保管箱金鑰 DID 的挑戰–回應簽章證明身份。伺服器得知某個公開身份在場且獲授權。它不會得知主密碼,也不需要鹽值來驗證簽章。

帳單遵守同一紀律。支付代理流程可附上帳單 email 做收據。該地址不是保管箱身份、不是解鎖材料,也不是解密訊框的查找鍵。NT² Premium 是帳號上的權益旗標,不是索引祕密的執照。

讓這件事保持誠實的設計規則是否定式:若某個欄位會幫助偷走資料庫的人打開或搜尋保管箱,那個欄位就不出貨。 帳號身份與公開金鑰留下。可被用來核對密碼的解鎖材料留在裝置上。密文繼續是密文。

取捨:較少伺服器魔法,較多使用者持有的保管責任

盲目的 Workers 對經典 SaaS 習慣不方便。

客服打不開保管箱。 維運者可以看到服務健康、驗證失敗、權益狀態、物件數量與時間。他們不能點進可讀項目來解釋一篇奇怪的筆記。那不是未完成的管理功能。那是邊緣拒絕變成明文控制室。需要真人協助的使用者必須在不把祕密貼進工單的前提下描述症狀——因為伺服器本來就沒有那些內容,也就無法自動填上。

密碼重設不是 Workers 功能。 若每個解鎖因素與每條使用者持有的還原路徑都沒了,邊緣無法憑空發明它們。沒有「email 給我一條能重新衍生保管箱金鑰的重設連結」。這道拒絕與可攜備份、本機鹽值成對:所有權包含保管責任。

新裝置註冊需要帶外材料。 鹽值與設定檔區段隨使用者旅行——備份檔、還原包或 replica 交接——而不是透過方便的 GET,把可核對密碼的狀態重新集中化。註冊完成後,同步可以移動不透明訊框;它不能用雲端擷取解鎖神諭來取代註冊。

產品分析保持粗粒度。 需要明文標題或解密類別的漏斗指標,不會因為「我們只存雜湊」就拿到通行證。讓雲端能搜尋保管箱內容的確定性權杖,仍然是伺服器上的保管箱索引。優先本機側量測與粗粒度帳號事件。

環境紀律是維運工作。 分開的 Workers 預備主機、分開的正式來源,以及拒絕混用它們的客戶端,需要設定上的細心。回報是可稽核性:審查者可以問「這個 Worker 能看見什麼?」並得到不依賴「希望沒人把正式 UI 指到預備儲存」的答案。

我們換回的是一句話就能說清楚、在綱要審查就能核對的邊界:邊緣做中繼與帳號;裝置負責理解。 帳號資料庫或物件儲存被攻破仍然嚴重——密文與詮釋資料仍是使用者資料——但不會自動變成明文外洩或離線密碼實驗室。

我們拒絕什麼

我們拒絕在 Workers 上託管鹽值或密碼驗證器。 解鎖材料活在本機保管箱設定檔。邊緣綁定身份;它不組裝猜測系統。

我們拒絕「為了同步方便」的明文項目 API。 同步移動不透明批次與附件訊框。沒有可讀標題的雲端表去「幫忙」衝突解決。

我們拒絕能解密保管箱內容的客服工具。 健康與權益可見性可以;「檢視保管箱」不行。

我們拒絕把解鎖與雲端登入壓成一次伺服器往返。 本機衍生與保管箱金鑰 DID 挑戰–回應維持為分開的事件與分開的失敗模式。

我們拒絕擴大 Workers 可見範圍的預備–正式捷徑。 暫時遷移端點、跨環境共用資料庫,或硬編碼到錯誤來源的客戶端,視為安全缺陷,不是方便。

我們拒絕把帳單身份當成保管箱身份。 可選的收據 email 不是主密碼重設通道,也不是保管箱金鑰 DID 驗證的替代品。

我們拒絕預覽祕密的通知負載。 「有新的加密訊框可用」就夠了。標題與類別等到本機解密。

這些拒絕讓權限清單熬過路線圖壓力。每一個被回絕的功能,都是 D1 裡永不出現的欄位,以及日誌裡永不出現筆記內文的一行。

刻意盲目

NT² 背後的 Workers 不是天空中的微型保管箱。它們是可選的邊緣:身份、權益、不透明 replica 傳輸,以及盲目共用投遞。閣樓留在你於 se.nt2.me 解鎖的裝置上。正式來源保持具名且分離,好讓這項主張可被核對,而不是氣氛。

那條邊界是同一則故事從不同門說出。解鎖如何不同於雲端驗證,見解鎖本機保管箱,不等於登入雲端。replica 訊框如何保持不透明,見在邊緣進行盲目 replica 同步。一個保管箱金鑰 DID 如何對應一個同步中樞,見一個保管箱身份,一個同步中樞。為什麼帳號表不能成為密碼神諭,見帳號資料庫不能成為密碼神諭。為什麼鹽值永不變成雲端擷取,見KDF 鹽值留在你的裝置上

若你想要一個雲端層只被允許看見盲目中繼所需之物的保管箱——試試 NT² Vault,或到 nt2.me 了解更多。

最後更新 2026-10-15

相關故事