Skip to Content
操作流程管理 Worker 機密

管理 Worker 機密

誰: 部門管理者(含讀取;部門成員會得到 403 Insufficient permissions.)。前提: Worker 已部署且 active(否則 409),而且上線中的 release 必須支援機密(否則 409 worker_secrets_unsupported)。路徑位於 {BASE}/private/module/edge-workers 之下,並帶 Authorization: Bearer <jwt>(操作流程總覽)。回應為 no-store。沒有 base_revision:寫入會取代該名稱原有的內容,而且任何值都不會被回傳。概念、限制與清除規則:Worker 機密。

列出

GET /worker/secrets → { "items": [ { "name": "TS_API_KEY", "updated_at": "2026-08-19T08:01:00Z" } ] } # or { "items": [] }

只回傳名稱與 updated_at(ISO-8601 UTC),依名稱排序,最多 256 筆。需要以 builder policy v2.6 或更新版本建置的上線 release。

寫入(建立或取代)

PUT /worker/secrets/TS_API_KEY { "value": "<secret value>" } → { "name": "TS_API_KEY", "updated_at": "2026-08-19T08:02:00Z" }
  • 路徑中的名稱須符合 ^[A-Z][A-Z0-9_]{0,63}$,且不以 TEAMSYNC_ 開頭。
  • body 只有一個欄位 value:非空字串、不得含 NUL、格式正確的 Unicode、最多 65 536 個 UTF-8 位元組。任何其他欄位都會以 422 拒絕。整個 body 最多 409 600 位元組。
  • 每個 Worker 最多 256 個機密,所有值合計最多 16 MiB(16 777 216 位元組)。寫入已存在的名稱是取代,不會多占名額。
  • 需要以 builder policy v2.7 或更新版本建置的上線 release(政策表見 Worker 機密)。
  • 變更在下一次呼叫生效;不重新部署任何東西。

這次呼叫背後:後端先向 Worker 詢問目前的數量與總大小,提交一筆只含摘要的稽核意圖,再把值與全新的 salt 透過簽章控制通道送出一次,最後檢查 Worker 回報的名稱與加鹽摘要是否完全相同。不一致是 503,絕不當成成功。

刪除

DELETE /worker/secrets/TS_API_KEY → { "name": "TS_API_KEY", "deleted": true, "updated_at": "2026-08-19T08:09:00Z" }

沒有 body。刪除是冪等的:沒有設定的名稱會回 200 與 "deleted": false(updated_at 是處理這個請求的時間)。如果 Worker 的上線 release 早於 v2.6,回應是不含 updated_at 的 { "name": "TS_API_KEY", "deleted": false },因為這樣的 bundle 本來就無法持有機密。這兩種 no-op 的情況都會寫入稽核事實 secrets.delete_noop。

錯誤

detail 要嘛是字串,要嘛是物件 {code, message};是物件時請讀 detail.code。生成的 OpenAPI 把這些路由的 409 與 413 body 標成這種形式,卻把 503 body 標成純字串,儘管 worker_release_unavailable 是物件,所以每個狀態碼都請兩種形狀都接受。Edge Workers 的 403 系列見錯誤。自後端 5.22.0 起,變更也可能被拒絕並回 409 worker_serving_target_unavailable(後端無法驗證是哪個位置在服務該 Worker)。平台維運者搬移該 Worker 期間,會回 503 Department Worker control change is unavailable;但在搬移的短暫暫停期間,會先讀取該 Worker 狀態的呼叫改回該路由慣用的修訂版過期 409(錯誤、搬移 Worker)。

狀態detail原因與處理
403Insufficient permissions.呼叫者不是部門管理者;部門成員連名稱都不能列出。服務帳號的 JWT 也會得到同樣的 403:它建立時不具管理者角色
404Department Worker not found該部門還沒有 Worker
409Department Worker must be deployed and active沒有已部署且 active 的 release。先部署;部署進行中或 uncertain 時 Worker 是 paused,請等票證結算(部署與輪詢)
409{"code":"worker_secrets_unsupported","message":"This deployed Worker release does not support Worker secrets; re-upload and deploy the project"}GET:上線 release 早於 v2.6;PUT:早於 v2.7。重新提交專案並部署新的修訂版。DELETE 永遠不會回這個錯誤
409{"code":"secret_limit_exceeded","message":"The department Worker secret count limit is exhausted"}已有 256 個機密時 PUT 新名稱。刪除一個,或取代既有名稱。兩個寫入競爭最後一個名額時,輸家會得到相同的 code,訊息則是 Worker secret limit was reached
409Worker secret mutation is staleWorker 以衝突回應這次變更。重新列出,再重送請求
413Worker secret request exceeds limitPUT body 超過 409 600 位元組;在驗證之前檢查
413{"code":"secret_size_exceeded","message":"Department Worker secret storage exceeds its total size limit"}寫入後所有值合計會超過 16 MiB(被取代的值不計入)。寫入競爭時,Worker 的拒絕會保留原本的 code,訊息則隨狀態碼而定:413 為 Worker secret storage limit was reached,409 為 Worker secret limit was reached
422Worker secret name is invalid or reserved名稱以 TEAMSYNC_ 開頭(字串形式的 detail)
422{loc, type, msg} 的清單請求驗證失敗 — 見下文
503Department Worker secrets are unavailableWorker 沒有回應,或它的回應未通過驗證。寫入之後結果可能未知 — 見下文
503Department Worker control change is unavailable後端無法提交耐久的稽核意圖。沒有送出任何東西;重送請求
503{"code":"worker_release_unavailable","message":"Worker release changed; retry this request"}僅限 PUT 或 DELETE:上線 release 在後端讀取與呼叫之間改變了,變更被拒絕。重送請求
503Deployed department Worker release is unavailableWorker 目前的修訂版不是 deployed,或無法推導出它的 release 身分。檢查 Worker 的狀態與最近一次部署

PUT /worker/secrets/{name} 的 422 絕不回顯機密值:每個項目恰好只有 loc、type、msg 三個鍵,msg 一律是 validation_error: 加上 type;沒有 input,也沒有 ctx。

PUT /worker/secrets/TS_API_KEY { "value": "" } → 422 { "detail": [ { "loc": ["body", "value"], "type": "string_too_short", "msg": "validation_error:string_too_short" } ] }

常見的 type:string_too_short(空的 value)、value_error(NUL、不合法的 Unicode,或超過 65 536 個 UTF-8 位元組)、missing(沒有 value)、extra_forbidden(任何其他欄位)、位於 ["path", "name"] 的 string_pattern_mismatch(不符合格式的名稱;超過 64 個字元的名稱在同一位置是 string_too_long)。GET 與 DELETE 維持標準的 422 body。

寫入後遇到 503

  • Department Worker control change is unavailable 或 worker_release_unavailable:沒有套用任何東西。重送請求。
  • Department Worker secrets are unavailable,或請求送出後連線中斷:結果未知,因為 Worker 可能在它的回應未通過驗證或遺失之前就已經套用了變更。重新列出並看那個名稱:寫入會把它的 updated_at 設為寫入時間,刪除則會讓名稱消失。或直接重送請求 — PUT 會取代值、DELETE 是冪等的,所以重送是安全的。
  • 結果未知的稽核事實,TeamSync 之後會依 Worker 的回執結算。

在 handler 中使用機密

const apiKey = await context.secrets.get("TS_API_KEY") // string, or undefined if not set

get 只接受一個引數,並在呼叫當下讀取機密;其語意、TypeError 訊息,以及「部署的任何程式碼都能讀取每一個機密」的警告,都在 Worker 機密。機密裡只放專用的低權限憑證。

起始範本的 README 示範了一種用儲存的金鑰呼叫 TeamSync API 的做法:由一位專用的低權限使用者透過 POST /private/auth/apikey 發出金鑰(scope=external_agent、domains=<your API host>),再把它存成 TS_API_KEY。API 金鑰的網域檢查讀的是 Referer 主機名稱,所以 Worker 必須明確送出 referer header,否則呼叫會被 403 拒絕:

const base = "https://api.your-company.example"; const apiKey = await context.secrets.get("TS_API_KEY"); const response = await fetch(`${base}/private/user/me`, { headers: { "x-api-key": apiKey ?? "", referer: base }, });

這個 scope 允許此範例的 GET;呼叫其他端點時,請選擇涵蓋該端點的 scope。若要以部門服務帳號的身分呼叫 TeamSync、不必儲存金鑰,見服務帳號。

本機開發

teamsync-worker dev(CLI)啟動時會讀取選用的檔案 .teamsync/dev-secrets.json,並把它同步進本機的 Durable Object,所以 context.secrets.get 在本機也能運作:

{ "TS_API_KEY": "local-api-key" }
  • 這個檔案把機密名稱對應到字串值,名稱與值的規則和 API 相同。它必須是一般檔案(不是符號連結、沒有硬連結),權限恰為 0600,大小介於 1 位元組與 16 MiB,最多 256 個名稱。
  • 啟動時,CLI 會列出本機的機密,刪除所有不在檔案中的已儲存名稱,再寫入每一筆項目(和 API 一樣,每筆都用全新的 salt 與摘要)。檔案不存在代表完全不同步:先前執行留下的機密維持原狀。
  • 檔案只在 dev 啟動時讀取;編輯之後請重新啟動 dev。
  • 範本的 .gitignore 會忽略 .teamsync/,上傳封存檔也會排除它,所以這個檔案絕不會被提交。存放本機機密值的 .teamsync/dev-storage 目錄,建立時權限為 0700,其中的檔案為 0600。

任何失敗都會印出 teamsync_worker_failed:<message> 並以結束碼 1 離開:

檢查<message>
檔案存在但無法檢查.teamsync/dev-secrets.json is not readable
不是一般檔案、是符號連結,或有硬連結.teamsync/dev-secrets.json must be a regular non-hardlinked file
權限不是 0600.teamsync/dev-secrets.json permissions must be exactly 0600
空檔或大於 16 MiB.teamsync/dev-secrets.json has an invalid size
不是合法的 UTF-8 JSON.teamsync/dev-secrets.json must contain valid UTF-8 JSON
不是 JSON 物件.teamsync/dev-secrets.json must contain an object of name/value pairs
超過 256 個名稱.teamsync/dev-secrets.json may contain at most 256 secrets
名稱不符合格式,或以 TEAMSYNC_ 開頭.teamsync/dev-secrets.json contains an invalid or reserved secret name
值不是非空字串,或含有 NUL.teamsync/dev-secrets.json contains an invalid secret value
值超過 65 536 個 UTF-8 位元組.teamsync/dev-secrets.json contains a value over the UTF-8 byte limit
本機 Worker 拒絕同步local Worker secret synchronization failed (HTTP <status>)
本機 Worker 回應的 JSON 不合法local Worker secret synchronization returned invalid JSON
Last updated on