Warp tunnel: verify OAuth access tokens so 'decocms link' can use per-user auth
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 407
- Forks
- 57
- Avg merge
- 5h 6m
- Merged PRs (30d)
- 880
Description
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
-
On the Warp server side:
- Accept an OAuth bearer token in the existing
apiKeyfield of the register message (or read from a newAuthorizationheader — 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.
- Accept an OAuth bearer token in the existing
-
On the CLI side (one-line change once Warp is ready):
- Flip
defaultTunnelOpenerinapps/mesh/src/cli/commands/link.tsfrom:
```ts
apiKey: process.env.DECO_TUNNEL_SERVER_TOKEN ?? LEGACY_TUNNEL_TOKEN,
```
back to:
```ts
apiKey: params.apiKey,
``` - Remove the
LEGACY_TUNNEL_TOKENconstant. - 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.
- Flip
-
Token refresh (nice-to-have, not strictly blocking):
- The CLI session already persists
refreshTokenandexpiresAtfrom 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.
- The CLI session already persists
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.registerednever resolves on silent rejection — that's the silent-hang failure mode #3283 papers over)
Acceptance
- A
decocms linkrunning 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_TOKENconstant is removed from the CLI source.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/mesh/src/cli/commands/link.ts and apps/mesh/src/auth/index.ts, then inspect the @deco-cx/warp-node register handshake and its handling of Connected.registered. Confirm how the Warp server can validate the OAuth token and report rejection. Done means end-to-end linking works without the shared key and invalid or missing tokens fail explicitly within 15 seconds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- authentication, backend-api-design, cli, networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100