Skip to content

Tunnel WS endpoint (/.tunnel) should accept a ?token= query param like /.webrtc, so browser clients can authenticate #528

Description

@melvincarvalho

Problem

/.tunnel requires WebID auth but reads the credential only from the Authorization header (getWebIdFromRequestAsync(request) in src/tunnel/index.js). A browser WebSocket can't set request headers, so a browser-based tunnel client can't authenticate — it gets {type:"error", message:"Authentication required"} and the socket closes.

Node clients work fine (they set Authorization: Bearer <jwt>), which is why the existing demos work; only browser clients are blocked.

Precedent

/.webrtc already solved this — it injects a ?token= query param into the Authorization header before authenticating:

// src/webrtc/index.js
const queryToken = request.query?.token;
if (queryToken && !request.headers.authorization) {
  request.headers.authorization = `Bearer ${queryToken}`;
}

/.tunnel should do the same, for consistency.

Proposed fix

In src/tunnel/index.js, before the getWebIdFromRequestAsync(request) call in the /.tunnel route:

const queryToken = request.query?.token;
if (queryToken && !request.headers.authorization) {
  request.headers.authorization = `Bearer ${queryToken}`;
}

~4 lines, mirroring /.webrtc.

Test

  1. Obtain a WebID-bound JWT (POST /.pods).
  2. From a browser: new WebSocket("wss://<host>/.tunnel?token=<jwt>"), then send {type:"register", name:"demo"}.
  3. Expect {type:"registered", url:"/tunnel/demo/"}; confirm https://<host>/tunnel/demo/ proxies to the client.

Motivation

Enables a browser-based tunnel client (the solid-apps/tunnel control panel) — pods reachable on the web with no inbound ports, straight from the browser.

Security note

Same trade-off /.webrtc already accepts: the token rides in the WS upgrade URL. Acceptable parity; tokens are WebID-bound / short-lived. (Worth a docs note.)

Related

#527 (tunnel client mode: jss --tunnel-connect) — this resolves its "relay auth for the client" open question for browser clients; the same ?token= mechanism also supports a pre-shared-token outbound (Node) client.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions