Skip to content

[TW-7617] Add device-code sign-in for remote CLI login and signup - #125

Open
radenkovic wants to merge 3 commits into
mainfrom
codex/tw-7617-cli-device
Open

radenkovic wants to merge 3 commits into
mainfrom
codex/tw-7617-cli-device

Conversation

@radenkovic

Copy link
Copy Markdown
Contributor

Remote CLI sign-in and signup now use the authorization server's RFC 8628 device endpoint with nylas oauth login --device or --no-browser. SSH sessions select device sign-in automatically; local browser/loopback remains the default on macOS and Windows even without DISPLAY. A region fixes the device request's audience and signup region.

The polling service follows the advertised interval, adds five seconds for every slow_down, backs off on network failure, and stops on denial, expiry or cancellation without automatic restart. Tokens use the existing session lock/storage/renewal path. Verification links are checked against the discovered issuer; only the user code and verification URLs are printed. Device errors never echo server response bodies or bearer codes.

Validation: focused OAuth packages pass; affected packages pass under the race detector; golangci-lint reports 0 issues. A real-binary fake-server integration test verifies pending-to-success polling, isolated encrypted session storage, status, and absence of device code/tokens in terminal output. Invalid metadata, cumulative slowing, expiry, cancellation, terminal errors, disabled device flow, non-first-party clients and region constraints have regression coverage.

make ci-full with Go 1.26.9 passed formatting, vet, lint, unit tests, race tests, repository security scan, govulncheck, build and CLI regression checks, then stopped because NYLAS_API_KEY is unavailable for provider agent integration. The older local Go 1.26.5 failed govulncheck on standard-library vulnerabilities; no dependency or module changes were made. Live staging SSH/signup validation remains outstanding, along with deployment/enablement of dashboard-account device flow and a supported CLI release.

Principal MCP-only login and multiple-authorization credential isolation are TW-7622, separate from this remote-login track. No deployment or release is performed by this PR.

radenkovic and others added 3 commits October 13, 2026 15:13
…er, and keep invalid_target

Device sign-in always sends the configured region's MCP server as the RFC 8707
resource, and those were hardcoded to production. Staging names
mcp-staging.us.nylas.com, so every US device login against it was refused with
invalid_target. NYLAS_MCP_US_URL / NYLAS_MCP_EU_URL now replace that region's
server for the resource, the accepted audience, and so the host a token is sent
to. They replace rather than add, so the CLI still trusts exactly one server per
region. An override must be an https origin (http only for loopback); a bad one
fails closed instead of falling back to production.

safeDeviceError also collapsed invalid_target into server_error, so the reader
saw `oauth error "server_error"` with no cause. invalid_target is kept, still
without the server's description, and the device flow says which variable to set.

Verified against staging: without the override the CLI explains the refusal;
with NYLAS_MCP_US_URL=https://mcp-staging.us.nylas.com staging issues a device
code for region us.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@radenkovic
radenkovic marked this pull request as ready for review October 14, 2026 15:42

@qasim-nylas qasim-nylas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants