Skip to content

Tunnel: optional credential passthrough (Cookie / Authorization / Set-Cookie) so authenticated access & login work through the tunnel #530

@melvincarvalho

Description

@melvincarvalho

Problem

The tunnel proxy (src/tunnel/index.js) strips all credentials by design, so only public, unauthenticated content is reachable through a tunnel:

  • request → client: drops cookie and authorization (skipHeaders, ~line 163)
  • client → response: drops set-cookie (hopHeaders, ~line 197)

This means no authenticated access works through the tunnel — including interactive OIDC login. An OIDC login is a cookie-based session flow (the IdP sets a session/interaction cookie, reads it back across redirects, then issues the token); with cookie/set-cookie stripped, that session can never complete. Token/DPoP auth fails too (authorization stripped).

Concretely: serving a pod at https://<relay>/tunnel/<name>/ and trying to sign in fails — the credentials needed to authenticate never reach the tunnelled pod.

Why it matters

To make a tunnelled pod a fully usable, logged-in identity (not just a public read-only mirror) — e.g. sign in to a phone pod exposed via --tunnel — the IdP session cookie and bearer/DPoP auth must survive the proxy. This is the auth half of turning a reachable pod into an addressable one.

Proposal

Add opt-in, per-tunnel credential passthrough. When enabled by the tunnel owner at registration, forward Cookie + Authorization inbound and Set-Cookie outbound (instead of stripping them). e.g.:

{ "type": "register", "name": "phone", "passthrough": true }

Off by default; explicit per-tunnel opt-in.

Security considerations

Forwarding credentials means the relay passes a visitor's cookies/authorization to the registered tunnel client. That is only safe when the operator owns/trusts the client — which is the common case (you tunnel your own pod through your own relay). It must therefore be:

  • opt-in and off by default,
  • ideally surfaced clearly (the owner is asserting "I trust this relay with credentials bound for me"),
  • documented alongside the existing public-only behaviour.

Dependency / caveat (path vs subdomain)

Passthrough alone isn't sufficient for path-based serving (/tunnel/<name>/): the tunnelled pod's Set-Cookie Path, Location redirects, and root-relative URLs assume it's root-hosted, so they'd need rewriting under the /tunnel/<name>/ prefix (the classic reverse-proxy-at-a-subpath problem). Subdomain routing (<name>.<relay>) makes this clean — the pod is root-hosted on its own origin, so cookies/redirects/issuer align with no rewriting. So this pairs with subdomain routing and the issuer/host-locking work.

Related

Test plan

With passthrough enabled and the tunnelled pod's issuer set to its public tunnel URL (or, cleanly, a subdomain): an OIDC login through the tunnel completes — the IdP session cookie survives the round trips and a token with a matching iss is issued.

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