Skip to content

Conversation

@EhabY
Copy link
Collaborator

@EhabY EhabY commented Dec 16, 2025

Implements OAuth 2.1 with PKCE as an alternative authentication method to session tokens. When connecting to a Coder deployment that supports OAuth, users can choose between OAuth and legacy token authentication.

Key changes:

OAuth Flow:

  • Add OAuthSessionManager to handle the complete OAuth lifecycle: dynamic client registration, PKCE authorization flow, token exchange, automatic refresh, and revocation
  • Add OAuthMetadataClient to discover and validate OAuth server metadata from the well-known endpoint, ensuring server meets OAuth 2.1 requirements
  • Handle OAuth callbacks via vscode:// URI handler with cross-window support for when callback arrives in a different VS Code window

Token Management:

  • Store OAuth tokens (access, refresh, expiry) per-deployment in secrets
  • Store dynamic client registrations per-deployment in secrets
  • Proactive token refresh when approaching expiry (via response interceptor timers)
  • Reactive token refresh on 401 responses with automatic request retry
  • Handle OAuth errors (invalid_grant, invalid_client) by prompting for re-authentication

Integration:

  • Add auth method selection prompt when server supports OAuth
  • Attach OAuth interceptors to CoderApi for automatic token refresh (+ detach when no longer using OAuth)
  • Clear OAuth state when user explicitly chooses token auth
  • DeploymentManager coordinates OAuth session state with deployment changes

Error Handling:

  • Typed OAuth error classes (InvalidGrantError, InvalidClientError, etc.)
  • Parse OAuth error responses from token endpoint
  • Show re-authentication modal for errors requiring user action

Closes #586

@EhabY
Copy link
Collaborator Author

EhabY commented Dec 19, 2025

#633 includes some open threads that I addressed here but unsure about whether to revert or refine so please check open threads out, mainly:

@EhabY EhabY force-pushed the oauth-support branch 3 times, most recently from 24ebec5 to aa0e6b0 Compare December 24, 2025 13:54
Copy link
Member

@code-asher code-asher left a comment

Choose a reason for hiding this comment

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

I have not reviewed the test code yet but I tried it out and it looks good!

Implements OAuth 2.1 with PKCE as an alternative authentication method
to session tokens. When connecting to a Coder deployment that supports
OAuth, users can choose between OAuth and legacy token authentication.

Key changes:

OAuth Flow:
- Add OAuthSessionManager to handle the complete OAuth lifecycle: dynamic
  client registration, PKCE authorization flow, token exchange, automatic
  refresh, and revocation
- Add OAuthMetadataClient to discover and validate OAuth server metadata
  from the well-known endpoint, ensuring server meets OAuth 2.1 requirements
- Handle OAuth callbacks via vscode:// URI handler with cross-window
  support for when callback arrives in a different VS Code window

Token Management:
- Store OAuth tokens (access, refresh, expiry) per-deployment in secrets
- Store dynamic client registrations per-deployment in secrets
- Proactive token refresh when approaching expiry (via response interceptor)
- Reactive token refresh on 401 responses with automatic request retry
- Handle OAuth errors (invalid_grant, invalid_client) by prompting for
  re-authentication

Integration:
- Add auth method selection prompt when server supports OAuth
- Attach OAuth interceptors to CoderApi for automatic token refresh
- Clear OAuth state when user explicitly chooses token auth
- DeploymentManager coordinates OAuth session state with deployment changes

Error Handling:
- Typed OAuth error classes (InvalidGrantError, InvalidClientError, etc.)
- Parse OAuth error responses from token endpoint
- Show re-authentication modal for errors requiring user action
EhabY added 4 commits January 8, 2026 17:09
- Fix tests after rebase
- Add proper OAuth error handling with re-authentication prompts
- Remove in-memory token storage, rely on SecretStorage
- Attach/detach OAuth interceptor based on auth method
- Replace refreshIfAlmostExpired with smarter timer-based refresh
- Combine OAuth tokens with session auth storage
- Split OAuthAuthorizer (login flow) from OAuthSessionManager (token lifecycle)
- Add axios interceptor for automatic token refresh on 401
- Add comprehensive tests for session manager and interceptor
- Rename oauthInterceptor to axiosInterceptor for clarity
- Fix critical issues from self-review
- Fix URI handler for OAuth callback across windows
- Add more tests for edge cases
- Fix rebase conflicts
Copy link
Member

@code-asher code-asher left a comment

Choose a reason for hiding this comment

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

Looks good to me! I think we may want to consider an always-attached 401 interceptor, and I wonder if we should remove the clearing from getStoredTokens() to avoid accidentally deleting tokens due to races (we could just return undefined without clearing I think).

@EhabY
Copy link
Collaborator Author

EhabY commented Jan 13, 2026

I think we may want to consider an always-attached 401 interceptor, and I wonder if we should remove the clearing from getStoredTokens() to avoid accidentally deleting tokens due to races (we could just return undefined without clearing I think).

I've made the 401 interceptor always attached but re-auths using a callback because I didn't want to change the behavior now (could be a follow up). So now remote.ts uses that to show a dialog and login while extension.ts would just tell the user to login from the workspaces view.

Also I've removed the clearing of tokens in getStoredTokens()!

Copy link
Member

@code-asher code-asher left a comment

Choose a reason for hiding this comment

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

sublime!

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.

feat: support OAuth in the VS Code extension

2 participants