From a312cc7f99243f1af181d88f1280de77a4d1bf29 Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Thu, 4 Jun 2026 15:44:07 +0800 Subject: [PATCH] fix(v02): proxy API key writes through cloud web --- internal/dev-entrypoint/cloud-web-routes.mjs | 12 ++++++++++- .../dev-entrypoint/cloud-web-routes.test.mjs | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/internal/dev-entrypoint/cloud-web-routes.mjs b/internal/dev-entrypoint/cloud-web-routes.mjs index ccce0288..7e248184 100644 --- a/internal/dev-entrypoint/cloud-web-routes.mjs +++ b/internal/dev-entrypoint/cloud-web-routes.mjs @@ -46,6 +46,7 @@ export function isCloudApiProxyRoute(method, pathname) { } if (normalizedMethod === "POST") { return POST_PROXY_ROUTES.has(normalizedPath) || + isApiKeyWriteProxyRoute(normalizedMethod, normalizedPath) || normalizedPath.startsWith("/v1/rpc/") || normalizedPath.startsWith("/v1/agent/sessions/") || isDevicePodPostProxyRoute(normalizedPath) || @@ -55,11 +56,20 @@ export function isCloudApiProxyRoute(method, pathname) { return isWorkbenchWorkspaceWriteProxyRoute(normalizedMethod, normalizedPath) || isAgentConversationWriteProxyRoute(normalizedMethod, normalizedPath); } if (normalizedMethod === "DELETE") { - return isAgentConversationWriteProxyRoute(normalizedMethod, normalizedPath); + return isApiKeyWriteProxyRoute(normalizedMethod, normalizedPath) || + isAgentConversationWriteProxyRoute(normalizedMethod, normalizedPath); } return false; } +function isApiKeyWriteProxyRoute(method, pathname) { + if (pathname === "/v1/api-keys" && method === "POST") return true; + if (!pathname.startsWith("/v1/api-keys/")) return false; + if (method === "DELETE") return true; + if (method !== "POST") return false; + return pathname.endsWith("/regenerate"); +} + function isDevicePodPostProxyRoute(pathname) { const parts = pathname.split("/").filter(Boolean); if (parts.length < 4 || parts[0] !== "v1" || parts[1] !== "device-pods") return false; diff --git a/internal/dev-entrypoint/cloud-web-routes.test.mjs b/internal/dev-entrypoint/cloud-web-routes.test.mjs index 452171f4..5566e08e 100644 --- a/internal/dev-entrypoint/cloud-web-routes.test.mjs +++ b/internal/dev-entrypoint/cloud-web-routes.test.mjs @@ -39,6 +39,27 @@ test("cloud web proxies authenticated REST RPC bridge routes", () => { }); }); +test("cloud web proxies authenticated API key management write routes", () => { + assert.deepEqual(cloudWebProxyRoutePolicy("POST", "/v1/api-keys"), { + proxy: true, + authRequired: true, + publicRoute: false, + routeKey: "POST /v1/api-keys" + }); + assert.deepEqual(cloudWebProxyRoutePolicy("POST", "/v1/api-keys/key_1/regenerate"), { + proxy: true, + authRequired: true, + publicRoute: false, + routeKey: "POST /v1/api-keys/key_1/regenerate" + }); + assert.deepEqual(cloudWebProxyRoutePolicy("DELETE", "/v1/api-keys/key_1"), { + proxy: true, + authRequired: true, + publicRoute: false, + routeKey: "DELETE /v1/api-keys/key_1" + }); +}); + test("cloud web proxies only supported authenticated device-pod write routes", () => { assert.deepEqual(cloudWebProxyRoutePolicy("POST", "/v1/device-pods/D601-F103-V2/jobs"), { proxy: true,