Skip to content

add device auth and token endpoints #2692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft

add device auth and token endpoints #2692

wants to merge 11 commits into from

Conversation

mslynch
Copy link
Collaborator

@mslynch mslynch commented Jul 1, 2025

Intent

Resolves #2670.
Resolves #2671.

Adds two endpoints which will be used to authenticate through the OAuth device flow for Connect Cloud. The steps to use these will be as follows:

  1. Extension calls the device auth endpoint
  2. Extension starts polling the token exchange endpoint in the background
  3. Extension opens the verification URI in the browser
  4. User logs in and confirm the auth request
  5. Token exchange succeeds, returning the access and refresh tokens

API requests and responses are as follows:

POST /connect-cloud/device-auth
Cloud-Auth-Base-Url: https://api.login.staging.posit.cloud

// response body
{
  "deviceCode": "abc",
  "userCode": "abc",
  "verificationURIComplete": "https://login.staging.posit.cloud/wherever-this-page-will-be",
  "interval": 5
}
POST /connect-cloud/oauth/token
Cloud-Auth-Base-Url: https://api.login.staging.posit.cloud

// request body
{
  "deviceCode": "abc"
}

// response body
{
  "accessToken": "abc",
  "refreshToken": "abc",
  "expiresIn": 1800
}

// response body - HTTP 400
{
  "code": "deviceAuthPending" // values: deviceAuthPending, deviceAuthSlowDown, deviceAuthAccessDenied, deviceAuthExpiredToken, unknown
}

Type of Change

    • Bug Fix
    • New Feature
    • Breaking Change
    • Documentation
    • Refactor
    • Tooling

Approach

The device auth endpoint is a very simple passthrough to our authorization server. It should always succeed at initiating a device auth request.

The token exchange endpoint has specific error handling for certain error codes.

User Impact

No user impact until we start calling this from the extension code.

Automated Tests

Added unit tests for the auth client methods and new endpoints.

Directions for Reviewers

@tyatposit This is WIP - we need to wait for Kyle's auth changes (https://github.com/rstudio/lucid-auth/issues/1320) before we can actually use this.

  1. Call POST /connect-cloud/device-auth
  2. Call POST /connect-cloud/oauth/token - it should fail with deviceAuthPending.
  3. Visit the verificationURIComplete URL from the response, log in if necessary, and approve the request
  4. Call POST /connect-cloud/oauth/token - it should succeed.

Checklist

@mslynch mslynch changed the title add device auth endpoint add device auth and token endpoints Jul 2, 2025
@mslynch mslynch requested a review from Copilot July 2, 2025 15:42
Copilot

This comment was marked as outdated.

@mslynch mslynch requested a review from Copilot July 2, 2025 15:51
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for the OAuth 2.0 Device Authorization Grant flow by exposing two new API endpoints and wiring up a form-encoded HTTP client to back them.

  • Introduces /connect-cloud/device-auth and /connect-cloud/oauth/token handlers with request/response models.
  • Extends the internal HTTP client (PostForm) for form-encoded calls and implements a CloudAuthClient using it.
  • Updates routing and renames existing clientFactory to connectClientFactory across service handlers and tests.

Reviewed Changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/types/error.go Added new ErrorDeviceAuth* codes for device flow
internal/types/api_errors.go Mapped device-auth error strings to API error codes
internal/services/api/post_connect_cloud_device_auth.go Implements device-auth endpoint handler
internal/services/api/post_connect_cloud_oauth_token.go Implements token-exchange endpoint handler
internal/services/api/post_test_credentials.go Renamed clientFactory to connectClientFactory
internal/services/api/get_snowflake_connections.go Swapped clientFactory to connectClientFactory
internal/services/api/get_deployment_env.go Swapped clientFactory to connectClientFactory
internal/services/api/api_service.go Registered the two new endpoints in the router
internal/clients/http_client/http_client.go Added PostForm and doFormEncoded for form data
internal/clients/cloud_auth/client_cloud_auth.go Added CreateDeviceAuth/ExchangeToken implementations
Comments suppressed due to low confidence (1)

internal/clients/http_client/http_client.go:179

  • The doFormEncoded method references context.Background() and slog.LevelDebug but this file doesn’t import context or log/slog. Please add the necessary imports or adjust to use the existing logging.Logger API.
	if log.Enabled(context.Background(), slog.LevelDebug) {

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.

Add Cloud auth token exchange endpoint Add Device Auth API for Connect Cloud
1 participant