Warp tunnel: verify OAuth access tokens so 'decocms link' can use per-user auth
## Background
`bunx decocms link` (added in #3282, fixed in #3283) opens a tunnel through the Warp server (`@deco-cx/warp-node`). Today the tunnel is authenticated with a hardcoded shared key (`DECO_TUNNEL_SERVER_TOKEN`, with a fallback constant in the CLI source) — every CLI install uses the same secret.
PR #3282 pivoted the CLI auth flow to standard OAuth 2.1 + PKCE against Better Auth's MCP plugin, which means each user now has their own access token in `~/.deco/session.json`. The CLI was originally wired to send that access token as the Warp apiKey, but the Warp server doesn't know how to verify it — it dropped the registration silently and the CLI hung indefinitely. PR #3283 reverted to the shared key as a stop-gap.
## Goal
Update the Warp tunnel server so it accepts the user's OAuth access token (or an equivalent per-user credential) for the register handshake, and rejects requests that don't carry a valid one.
## What to do
1. **On the Warp server side:**
- Accept an OAuth bearer token in the existing `apiKey` field of the register message (or read from a new `Authorization` header — TBD which is cleaner).
- Validate the token against the decocms auth server (introspect via JWT signature + issuer, or hit a verification endpoint).
- Reject (with an explicit error message) registrations whose token is missing, expired, or invalid — currently rejection is silent.
- Optionally: bind the requested subdomain to the token's \`sub\` so a user can only register subdomains derived from their own identity.
2. **On the CLI side (one-line change once Warp is ready):**
- Flip `defaultTunnelOpener` in `apps/mesh/src/cli/commands/link.ts` from:
\`\`\`ts
apiKey: process.env.DECO_TUNNEL_SERVER_TOKEN ?? LEGACY_TUNNEL_TOKEN,
\`\`\`
back to:
\`\`\`ts
apiKey: params.apiKey,
\`\`\`
- Remove the `LEGACY_TUNNEL_TOKEN` constant.
- The 15s registration timeout (also added in #3283) acts as a safety net during the cutover so a misconfigured client surfaces an error rather than hanging.
3. **Token refresh (nice-to-have, not strictly blocking):**
- The CLI session already persists `refreshToken` and `expiresAt` from the OAuth response. Add transparent refresh in the CLI (or document that users re-run \`auth login\` on expiry) so long-running tunnels survive token rotation.
## References
- PR #3282 — original CLI feature + OAuth pivot (merged, shipped as decocms@2.304.0)
- PR #3283 — temporary revert to legacy shared key + 15s registration timeout
- \`apps/mesh/src/cli/commands/link.ts\` — `defaultTunnelOpener`
- \`apps/mesh/src/auth/index.ts\` — Better Auth MCP plugin config (already exposes `/api/auth/mcp/register`, `/authorize`, `/token`)
- Warp client code: \`@deco-cx/warp-node\` (`Connected.registered` never resolves on silent rejection — that's the silent-hang failure mode #3283 papers over)
## Acceptance
- A `decocms link` running against a Warp server that has been updated to verify OAuth tokens succeeds end-to-end without the legacy shared key.
- An invalid or missing token results in a fast, explicit error message on the CLI within 15s, not a hang.
- The shared `DECO_TUNNEL_SERVER_TOKEN` constant is removed from the CLI source.
0 条评论