Skip to content

[Enhancement] Add GitHub OAuth Device Authorization Flow (RFC 8628) for direct, brokerless local auth #340

Description

@dhruvbhavsar0612

Problem Statement

Currently, connecting OpenWorker to GitHub either requires:

  1. Cloud OAuth Broker Relay: Routing OAuth authorization codes through a centralized relay service to handle redirect callbacks.
  2. Manual Personal Access Tokens (PAT): Requiring users to leave OpenWorker, navigate GitHub Developer Settings, configure token scopes manually, and copy-paste the token back into OpenWorker.

While the cloud relay simplifies web-style OAuth, it introduces an unnecessary external dependency for GitHub authentication in a native desktop app. On the other hand, manually generating PATs introduces friction for non-technical users.


Proposed Solution

Implement support for GitHub OAuth 2.0 Device Authorization Grant (Device Flow / RFC 8628).

GitHub natively supports the Device Flow for desktop applications and CLI tools (such as the official gh CLI). This allows OpenWorker to authenticate directly with GitHub without:

  • Any cloud relay or proxy service
  • Any embedded client_secret
  • Any localhost web server, browser redirects, or deep-link protocol handlers

How It Works

┌─────────────────┐             ┌─────────────────────┐             ┌─────────────────┐
│ OpenWorker App  │             │   User's Browser    │             │   GitHub.com    │
└────────┬────────┘             └──────────┬──────────┘             └────────┬────────┘
         │                                 │                                 │
         │  1. POST /login/device/code     │                                 │
         ├──────────────────────────────────────────────────────────────────►│
         │  (Returns user_code & device_code)                                │
         │◄──────────────────────────────────────────────────────────────────┤
         │                                 │                                 │
         │  2. Display user_code           │                                 │
         │     & open verification URI ───►│  3. User enters user_code       │
         │                                 │     and approves access ───────►│
         │                                 │                                 │
         │  4. Poll /login/oauth/access_token                                │
         ├──────────────────────────────────────────────────────────────────►│
         │  (Returns access_token when approved)                             │
         │◄──────────────────────────────────────────────────────────────────┤
         │                                                                   │
         │  5. Save access_token to local OS Secret Store                    │
         ▼                                                                   ▼
  1. Initiate Request: OpenWorker sends a POST request to https://github.com/login/device/code using OpenWorker's public GitHub OAuth App client_id and requested scopes (repo, read:user, workflow, etc.).
  2. Display Prompt: OpenWorker receives a user_code (e.g. WDJB-MJQX) and verification_uri (https://github.com/login/device). OpenWorker presents an interactive UI card displaying the 8-character code with a "Copy Code & Open GitHub" button.
  3. User Approval: The user opens https://github.com/login/device in their web browser, pastes the code, and clicks Authorize.
  4. Local Polling: OpenWorker background-polls https://github.com/login/oauth/access_token at the requested interval.
  5. Token Storage: Once approved, GitHub returns the access_token directly to OpenWorker, which stores it securely in the user's local OS keyring.

Key Benefits

  1. 100% Local & Private: Direct peer-to-peer communication between OpenWorker and GitHub. Zero traffic through OpenWorker cloud infrastructure.
  2. No Client Secret Required: Device Flow works with public client IDs and does not require bundling or hiding secret keys in client binaries.
  3. No Network Hooks Needed: Eliminates the need for opening temporary local HTTP ports (http://127.0.0.1:8765/callback) or registering custom OS URI schemes (openworker://oauth/callback).
  4. Superior User Experience: Smoother and less error-prone than creating and pasting fine-grained Personal Access Tokens.
  5. Enterprise / Air-Gapped Friendly: Works seamlessly in corporate networks that restrict or block unknown external cloud relays.

Proposed Implementation Steps

1. Backend (coworker/connectors/github/auth.py)

  • Implement a GitHubDeviceAuth class:
    • start_device_flow(client_id, scopes) -> returns device_code, user_code, verification_uri, expires_in, interval.
    • poll_for_token(client_id, device_code, interval) -> returns access_token upon user approval or raises timeout/denied error.

2. Desktop GUI (surfaces/gui/src/components/connectors/GitHubDeviceAuthModal.tsx)

  • Add a modal/card component for GitHub Device Auth:
    • Displays formatted user_code with one-click copy.
    • Automatically opens verification_uri in default browser.
    • Shows spinner / status indicator ("Waiting for approval on GitHub...").
    • Handles expiration timeout and retry state.

Checklist for PR / Issue Creation

  • Verified GitHub API supports OAuth Device Authorization Grant (https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#device-flow).
  • Implement backend DeviceFlowAuthenticator in coworker/connectors/github.
  • Add UI card for GitHub Device Code authorization in React/Tauri frontend.
  • Add unit tests for polling and token storage in tests/connectors/test_github_auth.py.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions