From f557146635d23a764e1a7570b6475ffe34b6a3a3 Mon Sep 17 00:00:00 2001 From: Proactive Runtime Bot Date: Fri, 22 May 2026 15:13:13 +0200 Subject: [PATCH] migration(0004): backfill workspace_token kind for cloud-agent-box keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pre-#42 `/v1/tokens/workspace` route in @relayauth/server@0.2.9 landed rows in api_keys with `kind='api_key'` and `workspace_id=NULL` even when the caller asked for a workspace token. The key value uses the relay_ws_ prefix, so the apiKeyAuth middleware accepts it as a bearer, but resolveWorkspaceToken (used by /v1/tokens/path) rejects because kind != 'workspace_token' — surfacing as 401 workspace_token_required in the cloud-agent box-warm flow. The route fix that correctly sets kind/workspace_id at mint time is in PR #42 (`feat(tokens): implement path-scoped relayfile tokens`), part of the next published release. This migration cleans up rows that were already stored incorrectly so they resolve as workspace tokens once the new route code is deployed. Scope is narrow: only rows whose name matches the documented `cloud-agent-box:` shape (cloud-web-worker mint pattern in packages/web/lib/relay-workspaces.ts:mintRelayAuthWorkspaceToken). Idempotent — the `kind='api_key' AND revoked_at IS NULL` guards keep re-runs harmless. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../0004_workspace_token_kind_backfill.sql | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 packages/server/src/db/migrations/0004_workspace_token_kind_backfill.sql diff --git a/packages/server/src/db/migrations/0004_workspace_token_kind_backfill.sql b/packages/server/src/db/migrations/0004_workspace_token_kind_backfill.sql new file mode 100644 index 0000000..5520697 --- /dev/null +++ b/packages/server/src/db/migrations/0004_workspace_token_kind_backfill.sql @@ -0,0 +1,21 @@ +-- Backfill api_keys.kind = 'workspace_token' for rows minted through +-- /v1/tokens/workspace before the route reliably set the kind / workspace_id +-- fields. Specifically: `cloud-agent-box:` keys minted by the +-- cloud-web-worker landed with kind='api_key' and workspace_id=NULL even +-- though they were intended to be workspace tokens (relay_ws_* prefix on +-- the key value, scopes scoped to a workspace). +-- +-- Without this backfill, /v1/tokens/path's resolveWorkspaceToken returns +-- null for these rows (because kind != 'workspace_token'), and downstream +-- cloud-agent box-warm calls fail with 401 workspace_token_required. +-- +-- The workspace id is recoverable from the key name, which has the +-- documented shape `cloud-agent-box:` (see +-- packages/web/lib/relay-workspaces.ts:mintRelayAuthWorkspaceToken). + +UPDATE api_keys +SET kind = 'workspace_token', + workspace_id = SUBSTR(name, LENGTH('cloud-agent-box:') + 1) +WHERE name LIKE 'cloud-agent-box:%' + AND kind = 'api_key' + AND revoked_at IS NULL;