Skip to content

feat(auth): add OAuth device login - #5

Merged
ivankuznetsov merged 3 commits into
mainfrom
feat/device-authorization-current
Jul 13, 2026
Merged

feat(auth): add OAuth device login#5
ivankuznetsov merged 3 commits into
mainfrom
feat/device-authorization-current

Conversation

@ivankuznetsov

Copy link
Copy Markdown
Owner

Summary

Headless Screenote users can now sign in from SSH, tmux, containers, and remote agents with screenote login --device, without opening a browser or forwarding a callback port. The existing browser-based PKCE login remains the default for interactive machines.

The CLI treats the device credential as a secret throughout the flow: it emits only a safe JSON authorization prompt, follows RFC polling and slow_down behavior, bounds in-flight requests by the grant expiry, and redacts raw or escaped device codes from terminal failures. Successful OAuth login also replaces a legacy token stored in the config file so old onboarding cannot silently override the new refreshable session; explicit compatibility flags remain accepted but hidden from help.

Validation

  • go test ./...
  • go test -race ./...
  • go vet ./...
  • gofmt and diff checks
  • Exercised a real CLI-to-Rails flow: browser approval saved OAuth credentials and listed the authenticated project; browser denial returned access_denied without storing credentials.

New concepts

OAuth device authorization grant

Device authorization separates the terminal that requests access from the browser where the user approves it. That makes it a better fit than a loopback callback when the CLI runs on a remote machine with no reachable browser port.

flowchart TB
  CLI[Headless CLI] -->|request device and user codes| Server[Screenote OAuth server]
  CLI -->|show safe URL and short code| User[User]
  User -->|approve in any browser| Server
  CLI -->|poll with secret device code| Server
  Server -->|refreshable OAuth credentials| CLI
Loading

The default PKCE login remains preferable when the CLI and browser share a machine because it completes directly and avoids polling. Device authorization is reserved for explicit --device use on remote or browserless hosts.


Compound Engineering
GPT-5

@ivankuznetsov
ivankuznetsov merged commit e960bf5 into main Jul 13, 2026
1 check passed
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.

1 participant