Skip to content

Provide a login path that works in Workbench against Connect < 2026.06 (legacy token flow and/or configurable redirect URI) #843

Description

@posit-connect-projects

Problem

rsconnect login <server> runs an OAuth authorization code flow with a loopback redirect URI (http://127.0.0.1:<port>/callback, rsconnect/oauth.py). In a hosted session — Posit Workbench, a remote container, a cloud IDE — the browser that opens is not on the same host as the CLI listener, so the callback never arrives and the login hangs.

--use-device-code is the current workaround, and posit-dev/#842 tracks falling back to it automatically. But device code only exists if the target Connect is new enough: the built-in OAuth authorization server gained RFC 8628 device code support in Connect 2026.06. Against an older Connect, login_with_device_code() correctly reports that the server does not support the flow (rsconnect/oauth.py, "Server does not support the device code flow"), and at that point there is no working path at all from a Workbench session. The error message tells the user what happened but leaves them with no route forward.

This is currently blocking agentic publishing from Workbench: see posit-dev/connect#42494 and posit-dev/connect#42503, where the connect-deploy skill was updated to prefer --use-device-code in Workbench. That fix is complete only for Connect >= 2026.06.

Requested change

Two options, not mutually exclusive:

1. Implement the legacy token claim flow as an alternate path

Posit Publisher already does this, and it works against older Connect versions because it polls rather than relying on a redirect:

  1. Generate an RSA 2048-bit keypair and a token ID.
  2. POST /__api__/tokens with the public key, which returns a claim URL.
  3. Show the claim URL to the user.
  4. Poll until the token is claimed, then use the private key to sign requests.

See extensions/vscode/src/auth/generateToken.ts in posit-dev/publisher for the reference implementation. rsconnect (R) connectUser() uses the same mechanism, so rsconnect-python is the odd one out here. Because it is poll-based, it needs no reachable callback and works in any hosted environment.

2. Allow the redirect URI to be supplied

Add something like --redirect-uri, or detect Workbench directly, so the authorization code flow can use a browser-reachable callback instead of loopback. In Workbench that URL is derived from RS_SERVER_URL: Workbench exposes a generic OAuth relay at /oauth_redirect_callback that records the authorization code against the state parameter, and /oauth_code?state= hands it back once. Publisher implements exactly this in extensions/vscode/src/auth/oauth/workbench.ts (with RS_SERVER_ADDRESS used for the polling side so the browser session cookie isn't required).

Note that register_client() currently hardcodes "redirect_uris": ["http://127.0.0.1/callback"] during Dynamic Client Registration, so a configurable redirect URI has to be threaded through registration too, and Connect has to accept the non-loopback value.

Longer term, a general mechanism for "use a public callback URL when one is available" is the better answer than every tool detecting Workbench on its own — but the legacy token flow is the pragmatic near-term fix for pre-2026.06 servers.

Related

Filed at the request of @mconflitti-pbc.

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