Skip to Content
操作流程管理逐操作存取

管理逐操作存取

誰: 部門管理者(服務帳號的角色是 0,所以會先被角色門檻以 403 Insufficient permissions. 拒絕;見驗證與角色)。這裡所有操作的前提: Worker 已部署且為 active,且上線 release 以 builder 政策 department-worker-project-v2.8 或更新版本建置 — 否則回 409 Department Worker must be deployed and active 或 409 {"code":"operation_settings_require_supported_release","message":"Re-upload and deploy this Worker with the operation-settings runtime policy before changing per-operation access"}。路徑相對於 /private/module/edge-workers;每個成功回應都是 Cache-Control: no-store。概念:逐操作存取。

讀取

GET /worker/operation-settings GET /worker/operation-settings?version_id=<version-uuid> → 200 { "state": "reconciled", "version_id": "<version-uuid>", "revision": 3, "default_service_account_id": null, "default_service_account": null, "operations": [ { "operation_id": "createOrder", "method": "POST", "path": "/orders", "access": { "mode": "api_key_and_ip", "ip_allowlist": ["203.0.113.0/24"] }, "service_account_id": null, "effective_access": { "mode": "api_key_and_ip", "ip_allowlist_configured": true, "api_key_configured": true, "source": "operation" }, "effective_service_account": null }, { "operation_id": "getStatus", "method": "GET", "path": "/status", "access": { "mode": "public", "ip_allowlist": [] }, "service_account_id": null, "effective_access": { "mode": "public", "ip_allowlist_configured": false, "api_key_configured": false, "source": "operation" }, "effective_service_account": null }, { "operation_id": "listOrders", "method": "GET", "path": "/orders", "access": null, "service_account_id": null, "effective_access": { "mode": "teamsync_internal", "ip_allowlist_configured": false, "api_key_configured": false, "source": "worker" }, "effective_service_account": null } ] }
  • revision 是 PUT 的 CAS 權杖。從未儲存過設定的 Worker 會讀到 state: "legacy"、revision: 0,且每個操作都是 access: null。
  • effective_access 依目前的 Worker 層級政策計算,所以 /worker/access-policy 改變時它也會跟著變。
  • ?version_id= 讓你在部署前預覽另一個 release:它必須是這個 Worker 的 ready 或 deployed 版本(否則 404 Department Worker not found),且以 v2.8 或更新版本建置(否則 409 {"code":"operation_settings_require_supported_release","message":"The selected release does not support operation settings"})。該 release 尚無設定表時,回應呈現不帶 operation_settings 部署時會帶過去的內容 — 目標中也存在之操作的上線列,加上上線中的預設服務帳號 — 且仍回報 state: "pending"、revision: 0。

替換設定

PUT /worker/operation-settings { "base_revision": 3, "operations": [ { "operation_id": "createOrder", "access": { "mode": "api_key_and_ip", "ip_allowlist": ["203.0.113.0/24"] } }, { "operation_id": "getStatus", "access": { "mode": "public" } }, { "operation_id": "listOrders", "access": null } ] } → 200 { "state": "reconciled", "revision": 4, "operations": [ … ], … }
  • 整份清單替換:上線 manifest 的每個操作都要恰好列出一次。少列或多列 → 422 [{"loc":["body","operations"],"msg":"operation settings must list every manifest operation","type":"operation_settings_incomplete"}]。要繼承 Worker 層級政策就用 "access": null。
  • base_revision 必須等於目前的 revision(legacy 或 pending 的表為 0);否則 409 Operation-settings revision is stale — 重新 GET 後再套用。成功時回傳的 revision = base_revision + 1。
  • 既有的操作金鑰與金鑰擁有權一律留在各自的操作 id 上,不受請求內容影響。
  • 請求也帶出站身分欄位 operations[].service_account_id 與 default_service_account_id(省略 = 保留目前綁定,null = 清除);見服務帳號。從不送這兩個欄位的用戶端永遠不會改動綁定。
  • 狀態為 pending 的表在公開通道上失敗即關閉;以 base_revision: 0 送出 PUT 即可讓它 reconciled。只存在其他 release generation 的金鑰不會被帶進來,所以曾擁有金鑰的操作需要新金鑰。
  • Schema 驗證(422)拒絕重複的 id(operation settings must contain unique operation ids)、總數超過 256 條的 CIDR(operation settings contain too many IP allowlist entries)、沒有 CIDR 的 ip_allowlist/api_key_and_ip 覆寫(the selected access mode requires at least one CIDR)、其他模式帶 CIDR(IP allowlist is supported only by IP-restricted modes),以及重複的 CIDR(IP allowlist entries must be unique)。未知欄位也會被拒絕。

輪替操作金鑰

POST /worker/operation-settings/createOrder/api-key → 200 { "api_key": "tsw_…", "header_name": "X-TeamSync-Worker-Key", "operation_id": "createOrder", "access": { "mode": "api_key_and_ip", "ip_allowlist_configured": true, "api_key_configured": true, "source": "operation" } }
  • 沒有請求本體:伺服器自行讀取目前的 revision。明文(tsw_ + 43 個字元)只出現一次 — 請立即保存;任何回應都不會顯示操作金鑰的後四碼提示。
  • 操作必須在上線 manifest 中(否則 404 Department Worker not found),且上線中的表為 reconciled(否則 409 {"code":"operation_settings_pending","message":"Write operation settings before assigning an operation API key"} — legacy 的 Worker 要先 PUT 一次設定)。
  • 輪替會立即取代先前的金鑰、把 revision 推進 1(下一次 PUT 前請重新 GET),且不改變模式。呼叫者在公開 URL 上以 X-TeamSync-Worker-Key 送出金鑰;只有在操作的有效模式為 api_key 或 api_key_and_ip 時才會檢查。

撤銷操作金鑰

DELETE /worker/operation-settings/createOrder/api-key → 200 { "operation_id": "createOrder", "revoked": true, "access": { "mode": "api_key_and_ip", "ip_allowlist_configured": true, "api_key_configured": false, "source": "operation" } }
  • 沒有請求本體。Worker 為 paused 時、以及部署進行中也可以撤銷:操作可以在上線 manifest 或暫存的目標 manifest 中(否則 404);若上線 release 在呼叫期間改變,改為撤銷暫存的 release。
  • 不是 reconciled → 409 Operation settings are pending。
  • 金鑰會在每個已儲存的 release generation 中清除。重複呼叫回 revoked: false,且不推進 revision(稽核為 operation_settings.api_key.revoke_noop)。
  • 擁有權是永久的:只要該操作的有效模式是金鑰模式,在你輪替出新金鑰之前,它不接受任何金鑰(絕不退回 Worker 層級金鑰)。

帶操作設定部署

POST /worker/deployments 接受選用的 operation_settings 區塊,形狀與 PUT 本體相同。票證機制、輪詢與其他部署錯誤見部署與輪詢。

POST /worker/deployments { "version_id": "<version-uuid>", "base_revision": 7, "operation_settings": { "base_revision": 4, "operations": [ { "operation_id": "cancelOrder", "access": { "mode": "api_key" } } ] } } → 202 { …EdgeWorkerDeploymentStatus ticket… }
  • 兩個不同的 revision:外層 base_revision 是 Worker 的 latest_revision(同部署與輪詢);operation_settings.base_revision 是上線中操作設定表的 revision(否則 409 Operation-settings revision is stale)。設定會在目標 release 開始服務之前先暫存。
  • 清單可以只列一部分:列出的操作覆寫;兩個 release 都有且未列出的操作保留完整的上線列(存取、金鑰、金鑰擁有權、綁定);目標 manifest 沒有的操作會被丟棄。列出目標 manifest 沒有的 id → 422 [{"loc":["body","operations"],"msg":"operation_id is not present in the target release manifest","type":"operation_not_found"}]。
  • 不帶 operation_settings 時,上線中的表會依同樣規則自動帶過去。
  • 暫存的表從自己的 revision 起算,所以部署完成後、下一次 PUT 之前要重新 GET。範例中的 cancelOrder 還沒有金鑰:部署後請為它輪替一把,否則它的公開呼叫會得到 401。
  • 完全相同的重試(同樣的 version_id、base_revision 與設定)回傳既有票證;同一組值但設定不同 → 409 {"code":"operation_settings_dedupe_mismatch","message":"Deployment settings differ from the existing ticket"}。
狀態碼detail何時
409{"code":"operation_settings_require_supported_release","message":"Deploy the Worker once before adding operation settings"}送了設定,但沒有上線中的 active release
409{"code":"operation_settings_require_supported_release","message":"The live release does not support operation settings"}送了設定,上線 release 早於 v2.8
409{"code":"operation_settings_require_supported_release","message":"The target release does not support operation settings"}上線 release 為 v2.8 或更新、目標早於 v2.8 — 即使不帶設定也會拒絕
409{"code":"operation_settings_pending","message":"Reconcile the live release before deploying settings"}上線中的表為 pending
503{"code":"operation_settings_live_read_unavailable","message":"Retry the deployment after the live settings read recovers"}連續兩次讀不到上線設定

設定鎖

PUT、輪替、撤銷與每個新的部署請求(既有票證的完全相同重試除外)都會取得同一把部門層級的鎖(600 秒後過期);部署在暫存設定並寫入票證期間持有它。

  • 鎖被占用 → 409 {"code":"deployment_in_progress","message":"Another Worker settings mutation or deployment is in progress"}。稍後重試。
  • 鎖的儲存無法連線 → 503 Operation-settings mutation lock is unavailable。
  • 另外,只要有其他部署票證處於 pending、leased 或 uncertain,PUT、輪替與新的部署都會被拒絕:409 {"code":"deployment_in_progress","message":"Operation settings cannot change during a deployment"}。請等票證結束(撤銷不受此限)。

錯誤

detail 可能是字串或 {code, message} 物件;後端生成的 OpenAPI 把其中多數標為單純字串,所以兩種都要解析。「全部」指四個 /worker/operation-settings 路由。自後端 5.22.0 起,變更也可能被拒絕並回 409 worker_serving_target_unavailable(後端無法驗證是哪個位置在服務該 Worker)。平台維運者搬移該 Worker 期間,會回 503 Department Worker control change is unavailable;但在搬移的短暫暫停期間,會先讀取該 Worker 狀態的呼叫改回該路由慣用的修訂版過期 409(錯誤、搬移 Worker)。

狀態碼detail路由
404Department Worker not found全部 — 沒有 Worker、version_id 不是 ready/deployed 版本、operation_id 不在 manifest 中
409Department Worker must be deployed and active全部(撤銷也接受 paused)
409operation_settings_require_supported_release(訊息見上)全部
409deployment_in_progress(兩種訊息見上)PUT、輪替、撤銷(僅鎖)、部署
409Operation-settings revision is stalePUT、輪替、撤銷、部署
409{"code":"operation_settings_pending","message":"Write operation settings before assigning an operation API key"}輪替
409Operation settings are pending撤銷
413Worker operation settings request exceeds limit(本體超過 65 536 B)PUT、輪替、撤銷
422operation_settings_incomplete(僅 PUT)、operation_not_found(僅部署)、上述 schema 訊息、service_account_not_foundPUT、部署
503{"code":"worker_release_unavailable","message":"Worker release changed; retry this request"}全部 — 呼叫期間已部署的 release 改變了
503Department Worker operation settings are unavailable全部 — 讀寫失敗,或儲存的 revision 不是 base_revision + 1
503Department Worker operation key is unavailable輪替 — 儲存的金鑰回讀不符
503Department Worker control change is unavailablePUT、輪替、撤銷 — 無法寫入控制面稽核意圖
503Operation-settings mutation lock is unavailablePUT、輪替、撤銷、部署
503Deployed department Worker contract is unavailable全部 — 無法讀取已部署的 manifest

PUT 與部署上的服務帳號綁定錯誤(service_account_not_found、service_account_credentials_require_supported_release、api_base_unconfigured、憑證遞送)說明見服務帳號。

稽核

每次變更都走耐久的控制面稽核 outbox,最終成為回執背書的稽核事實:operation_settings.replaced、operation_settings.staged(部署)、operation_settings.api_key.rotated、operation_settings.api_key.revoked / operation_settings.api_key.revoke_noop — 只記摘要,絕不記金鑰內容。見稽核。

Last updated on