跳到內容

NextPDF Connect 的安全性與維運

NextPDF Connect 以 API key bearer token 對網路傳輸進行驗證。它把本機 MCP 傳輸隔離為受信任的子行程。它會在每個高風險工具執行前加入明確的人為確認作為把關。本頁說明驗證模型、傳輸安全與威脅模型。

Terminal window
composer require nextpdf/server

伺服器有三道信任邊界,分別對應一種傳輸。

這裡的 MCP stdio 傳輸是由本機用戶端啟動的子行程。它從標準輸入讀取 JSON-RPC,並將回應寫回標準輸出。這個傳輸沒有網路監聽器,也沒有 API key。信任是從作業系統的行程邊界繼承而來,這正是 MCP 規範為 stdio 定義的信任模型。記錄會輸出到標準錯誤,因此絕不會汙染協定串流。

這裡的 REST 傳輸gRPC 傳輸屬於網路傳輸。除了不需要驗證的健康探測(health probe)外,兩者在每個請求上都要求提供一組 API key bearer token。兩種傳輸背後都由同一套金鑰儲存區、金鑰格式與常數時間驗證支撐。gRPC 傳輸會從呼叫的中繼資料(metadata)讀取 token,REST 則從 Authorization 標頭讀取。

驗證若實作不正確,就屬於 OWASP API Security Top 10 標記為 API2:2023 Broken Authentication 的那類失誤。這類實作瑕疵會損及 API 辨識呼叫端的能力,進而整體損害 API 的安全性(OWASP API Security Top 10,API2:2023)。弱或可預測的 token 也被明確點名為一種 broken-auth 反模式(同一來源,弱點清單)。以下設計即是針對這兩點而構建。

一組金鑰的格式是 npk_live_{kid}_{secret}kid 是一個八字元的識別碼,用於 O(1) 的記錄查找;entropy(亂度)則由 secret 承載。儲存區絕不保留原始金鑰,只保存完整金鑰材料的 SHA-256 摘要。每個請求進來時,伺服器會把提交的 token 做雜湊,再以常數時間比對(hash_equals)與儲存的摘要比較,因此錯誤金鑰不會透過時間差洩漏任何資訊。已停用或過期的金鑰會在雜湊檢查之後才被拒絕,而不是之前。

REST 與 gRPC 的驗證器共用這套邏輯。REST 中介層(middleware)會讀取 Authorization: Bearer npk_live_…。gRPC 驗證器則從 gRPC 的 authorization 呼叫中繼資料讀取同一組 bearer token,這份中繼資料會以 HTTP/2 標頭傳輸。它會以 gRPC 的 UNAUTHENTICATED 狀態讓該呼叫失敗。

兩種傳輸也都會對驗證前流量套用反自動化節流:來自同一用戶端身分的過量嘗試會被速率限制並拒絕——REST 上為 429 Too Many Requests,gRPC 上則為 gRPC RESOURCE_EXHAUSTED 狀態。此控制預設為啟用,因此即使部署未另行設定速率限制儲存區,它仍會提供保護;用戶端應退避(back off),而非立即重試。

若 REST 請求帶入的金鑰缺漏、格式錯誤、已停用或已過期,會收到 401 Unauthorized,並附帶一份 problem-details 主體與一個 WWW-Authenticate: Bearer 回應標頭。這符合 HTTP 的要求:401 回應必須帶一個至少含一項挑戰的 WWW-Authenticate 標頭欄位(RFC 9110 §11.6.1)。這項要求本身又源自另一條規則:對於省略憑證或帶有無效憑證的請求,應以 401 加上一個 WWW-Authenticate 挑戰來回應(RFC 9110 §11.6)。

每筆金鑰記錄都帶有一個最高產品層級。REST 管線會把已驗證用戶端的身分與層級附加到請求上,讓下游授權能依層級強制限制能力與酬載上限。即使已安裝那些套件,core 層級的金鑰也無法執行 Pro 或 Enterprise 操作。

  • **MCP 傳輸沒有 API key。**對本機子行程而言,這是刻意採用且正確的設計。不要透過任何網路 shim(相容層)把 MCP 伺服器對外暴露。如果網路 AI Agent(代理)需要這些工具,請讓它透過會做驗證的 REST 或 gRPC 傳輸存取。

  • **健康探測刻意設計為匿名。**其中 /healthz/readyz 會略過驗證,讓編排器無須憑證即可探測存活與就緒狀態。它們只回傳狀態,不會暴露任何工具或文件資料。

  • **確認 token 為單次使用且效期短暫。**human-in-the-loop 把關會發出一個綁定工具名稱、效期 300 秒的 token。該 token 首次使用時即會被消耗。它不是驗證憑證,也不能取代 API key。

每個請求的驗證只是一次雜湊加上一次常數時間比對。相較於一次 render(繪製)的成本,這項開銷微不足道。支援熱重載的金鑰儲存區會在金鑰檔變動時重新讀取,因此輪替金鑰不需要重啟,也不會增加每個請求的成本。

每個工具都會宣告一個風險等級。位於最高等級的工具 ApprovalRequired,在第一次呼叫時不會執行。確認把關會回傳一個含單次使用 token 的挑戰。代理必須把這個挑戰呈現給人類,再帶著該 token 重新呼叫該工具。這是在自動化行動引入風險的那個點上所設的刻意控制。這正是 IEC 31010 所指出的位置:在人為(此處為代理)行動引入風險的當下或鄰近位置控制風險(IEC 31010:2019)。這道把關無法透過組態被削弱:組態覆寫只能提高某個工具的風險,絕不能調降一個 ApprovalRequired 工具。參見 /connect/hitl-risk-tiers/.

網路傳輸本身不負責終結 TLS;TLS 屬於部署層面的考量。參考的合併部署會以 mutual TLS(雙向 TLS)執行 gRPC 傳輸,其中金鑰、憑證與用戶端 CA 都以部署機密的形式提供。在 mutual TLS 之下,伺服器會出示一張憑證,並要求且驗證一張用戶端憑證。請把 REST 傳輸部署在 TLS 終結器(反向代理或服務網格)後方,並且絕不在不受信任的網路上暴露明文監聽器。組態的細節在 /connect/deployment/ 一節;這是一份態勢聲明,不是即裝即用的保證,安全傳輸需要正確的部署組態。

寫檔工具會以設定的基準目錄為基準,resolve(解析)並正規化所請求的路徑,並拒絕 null 位元組、protocol wrapper 以及 .. 路徑穿越。任何解析後落在基準目錄之外的路徑都會被拒絕。請把基準目錄放在一個專用磁碟區上,並套用最小權限的檔案系統權限。

伺服器只會在設定的 TTL(預設 1800 秒)與有界數量(預設 50)範圍內,把文件保存在記憶體內的文件儲存區。除非明確呼叫了寫檔工具且路徑通過封閉檢查,否則它不會把文件內容持久化到磁碟。伺服器不會為了繪製或檢視文件而發出任何對外網路呼叫,因此除非某個工具被明確設定為擷取遠端資源,文件位元組不會離開該部署。對於無狀態、資料落地敏感的部署,請停用檔案輸出(allow_file_output: false),並把 enabled_tools 限制到最小集合。

稽核日誌會記錄 Caution 風險等級以上的工具執行,以及每一次發出的確認挑戰。稽核記錄會包含工具名稱、風險等級與成功旗標。請把工具引數視為可能含有敏感資訊:將日誌導向具備存取控制的接收端,並且不要把全域日誌等級調到會在共用環境中重放引數酬載的詳細程度。MCP 傳輸把日誌寫到標準錯誤,正是為了讓日誌內容絕不會進入標準輸出上的協定串流。

主張來源reference_id
驗證失誤會損害 API 安全性OWASP API 安全性 Top 10,API2:2023
弱或可預測的 token 是一種 broken-auth 反模式OWASP API 安全性 Top 10,API2:2023
401 必須帶一個 WWW-Authenticate 挑戰RFC 9110 §11.6.1
缺漏/無效憑證 → 401 加挑戰RFC 9110 §11.6
在(人為)引入的當下控制風險IEC 31010:2019

Model Context Protocol 的 stdio 信任模型遵循官方 MCP 規範修訂版 2025-06-18。由於 MCP 規範不屬於受管的標準語料庫,因此它連同其網址記錄於 /transports/mcp/。

簽章、遮蔽、合規與鑑識工具,只有在 nextpdf/premium 與伺服器一同安裝時才會存在。它們的存在不會改變驗證模型。它們的風險層級仍會把具破壞性的工具置於 human-in-the-loop 把關之後。

  • /connect/hitl-risk-tiers/ — 風險模型與確認封套的詳細說明
  • /connect/deployment/ — TLS、mutual TLS、機密與 worker 調校
  • /transports/rest/ — REST 中介層管線與 OpenAPI 安全性方案
  • /transports/grpc/ — gRPC 中繼資料驗證與狀態碼
  • /connect/configuration/ — enabled_tools、金鑰儲存區選擇、風險覆寫