Skip to content

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

@melvincarvalho

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions