You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current pipefy auth login (PR #125) requires a working browser on the same host as the CLI:
Bind a loopback HTTP server on 127.0.0.1:<ephemeral>.
Launch the user's browser at the auth URL.
The browser redirects to http://127.0.0.1:<port>/callback — only reachable from the same host.
This breaks for:
SSH sessions to remote servers (no local browser; the redirect target is on the remote machine, not the user's laptop).
CI runners doing one-time interactive setup.
Container shells, locked-down corp laptops with restricted browser access, headless dev environments.
--no-browser (added in PR #125) only changes the launch step — the loopback callback still has to land on the host running the CLI. So it doesn't help.
The OAuth 2.0 Device Authorization Grant (RFC 8628) is the canonical solution: the CLI prints a short code + a URL; the user opens that URL on any device with a browser (laptop, phone), enters the code, signs in; the CLI polls the IdP until authorization completes.
The piporacle Keycloak realm already advertises device_authorization_endpoint in its discovery doc (confirmed in PR #125 smoke test step 0). The pipefy-cli Keycloak client config also has device-flow enabled (per the handoff doc's "Keycloak client config" section).
Proposed command surface
pipefy auth login --device
Behavior:
POST to device_authorization_endpoint (from discovery) with client_id=pipefy-cli + scope=openid profile email offline_access.
Print to the user:
To sign in:
1. Open https://signin.pipefy.com/device on any browser.
2. Enter code: WDJB-MJHT
Waiting for sign-in... (this will time out in 5 minutes)
Poll the token endpoint with grant_type=urn:ietf:params:oauth:grant-type:device_code at the interval the IdP specifies (typically 5s).
On success, persist tokens to the keychain via existing storage.store_session — same shape as the loopback flow.
On user denial or timeout, surface a clear error.
Implementation notes
New module: oauth/device.py — analogous to oauth/flow.py but for the device grant.
Motivation
The current
pipefy auth login(PR #125) requires a working browser on the same host as the CLI:127.0.0.1:<ephemeral>.http://127.0.0.1:<port>/callback— only reachable from the same host.This breaks for:
--no-browser(added in PR #125) only changes the launch step — the loopback callback still has to land on the host running the CLI. So it doesn't help.The OAuth 2.0 Device Authorization Grant (RFC 8628) is the canonical solution: the CLI prints a short code + a URL; the user opens that URL on any device with a browser (laptop, phone), enters the code, signs in; the CLI polls the IdP until authorization completes.
The piporacle Keycloak realm already advertises
device_authorization_endpointin its discovery doc (confirmed in PR #125 smoke test step 0). Thepipefy-cliKeycloak client config also has device-flow enabled (per the handoff doc's "Keycloak client config" section).Proposed command surface
Behavior:
POST to
device_authorization_endpoint(from discovery) withclient_id=pipefy-cli+scope=openid profile email offline_access.Print to the user:
Poll the token endpoint with
grant_type=urn:ietf:params:oauth:grant-type:device_codeat the interval the IdP specifies (typically 5s).On success, persist tokens to the keychain via existing
storage.store_session— same shape as the loopback flow.On user denial or timeout, surface a clear error.
Implementation notes
oauth/device.py— analogous tooauth/flow.pybut for the device grant.fetch_provider_metadata,store_session,_http.http_client.authorization_pending/slow_downerrors per RFC 8628 §3.5.Out of scope
Acceptance criteria
pipefy auth login --devicecompletes end-to-end against piporacle.intervalandslow_downsignals.authorization_pendingretry,slow_downinterval bump,expired_tokentimeout,access_denieduser denial.docs/cli/auth.md) include a "headless / SSH" section explaining when to use--device.References
pipefy auth login(PKCE-based user sign-in) #125 ("Validated technical facts" section confirmsdevice_authorization_endpointexists in piporacle discovery; client config has the grant enabled)packages/cli/src/pipefy_cli/oauth/flow.py(the loopback flow this complements)