Skip to content

[FEATURE]: connect the desktop app to a remote server behind OIDC SSO (device authorization grant + Bearer) #59248

Open

Description

@angelnu

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Let the clients (desktop, mobile) connect to a remote opencode serve that sits behind an OIDC proxy — the missing half after the SSH transport of #7790 and the pairing link.

Context (self-hosted, multi-tenant)

We run a managed platform where every user gets their own opencode server (a "box") in Kubernetes, exposed at its own hostname and fronted by oauth2-proxy against an OIDC provider (Dex → Keycloak). The proxy is the only public door: it accepts its own session cookie (which only a same-origin browser can hold) or a JWT Authorization: Bearer. Consequences, all measured against a live box:

  • GET https://<box>/oc/api/info without a credential → 302 to the IdP; with a valid OIDC JWT → 200.
  • the server's own Basic credential (the OPENCODE_SERVER_PASSWORD) is refused by the proxy → 302. So the pairing link (#……, single-use code → 30-day session token used as the password) is only usable for the internal case (port-forward, in-box, same-origin browser).
  • the desktop renderer's origin is a custom scheme (oc://renderer), so its calls are cross-origin: the proxy must answer the CORS preflight (we had to configure that), and since the IdP endpoints send no CORS headers at all, the OIDC flow can never run in the renderer.

What we implemented and it works (in our fork, happy to bring it upstream)

  • Device authorization grant (RFC 8628) + OIDC discovery, run in the main process (no CORS in play), with the ID token sent as Authorization: Bearer; offline_access gives a refresh token, refreshed before expiry and once on a 401 (single-flight), credentials re-read per request.
  • One header builder for the server credential: Bearer wins over Basic (the same three call sites the app already has: API client, health probe, attachment XHR).
  • A "Sign in with SSO" action in the "Connect to a server" dialog (user code + approval URL), desktop builds only.
  • Concretely it reuses the pattern the app already has for the Console/OpenCode Go sign-in (provider.connect.console.deviceCode), so no new flow concept is introduced.

How it could generalise (the parts a maintainer may want shaped differently)

  1. Issuer discovery: we derive the IdP issuer two ways — from the server's own 302 Location (generic), with a host-pattern fallback for our naming. Upstream probably wants only the first (or an explicit "issuer" field).
  2. Client id: we default to a fixed OIDC client. A cleaner shape is the server advertising it (e.g. server.info carrying sso: {issuer, clientId}) or an advanced field in the dialog.
  3. Credential choice: we send the ID token because the proxy validates its audience; a resource server that validates the access token would want that instead — a switch or a documented default.

Ask

This reads like a core product feature, so before writing a PR: is this wanted, and which shape? (extend the Add-server dialog with an SSO method; advertise the SSO metadata in server.info; or model it as a connection contributed by packages/gui-extensions like the SSH one). Related: #47692 (Remote Control, OIDC gateway), #7790 (SSH remote connections), #44760 (managed fleet).

If it fits, we will do the work and keep it rebaseable (it is ~600 lines, almost all in two new modules).

Activity

  1. opencode-agent commented on Oct 26, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed write-up, and for offering to upstream your implementation.

    To restate the request: the desktop (and mobile) app would be able to connect to a remote opencode serve behind an OIDC proxy such as oauth2-proxy. It would sign in with the device authorization grant (RFC 8628) in the main process and send the token as Authorization: Bearer. Today the app only sends the server password as Basic auth, so the pairing link only works when you can reach the server directly.

    Maintainers will look at whether they want this and which shape fits best: an SSO method in the Add-server dialog, SSO metadata advertised in server.info, or a connection contributed by packages/gui-extensions like the SSH and pairing ones. Please wait for their input before putting a lot of work into a PR.

    Related issues:

  2. apaul314 commented on Nov 4, 2026

    @apaul314

    Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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