Skip to content

GitHub OAuth Token Scope Silently Overwritten Between Login and Connect Flows #225

@Ridanshi

Description

@Ridanshi

Summary

GitHub OAuth tokens stored during authentication and GitHub-connect flows overwrite each other despite requiring different permission scopes.

As a result, users can silently lose GitHub follow permissions after re-authentication.


Affected Files

  • apps/backend/src/routes/auth.ts
  • apps/backend/src/routes/connect.ts

Root Cause

Both flows upsert into the same token record:

(userId, 'github')

but store different OAuth scopes.

Login flow (auth.ts)

Stores:

read:user user:email

Connect flow (connect.ts)

Stores:

user:follow

Whichever flow runs last overwrites the previously stored token.


Realistic Failure Scenario

  1. User connects GitHub for follow functionality.
  2. Backend stores token with user:follow.
  3. User later logs in again using GitHub OAuth.
  4. Login flow overwrites token with lower-privilege scope.
  5. Follow actions now fail because the token lacks user:follow.

This failure is silent during login and only surfaces later during follow operations.


Impact

Users unexpectedly lose follow capability after re-authentication.

This creates:

  • broken follow flows,
  • confusing reconnect loops,
  • inconsistent OAuth behavior,
  • and invalid token capability assumptions.

The issue is especially difficult to debug because:

  • authentication still succeeds,
  • token storage succeeds,
  • failures occur only later during GitHub API usage.

Proposed Fix

Separate authentication tokens from follow-capable tokens.

Possible approaches:

Option 1

Store separate platform keys:

github_auth
github_follow

Option 2

Merge scopes intelligently and retain the most permissive token.

Option 3

Store scope metadata explicitly and validate capability before overwriting.


Acceptance Criteria

  • Login flow no longer removes follow capability.
  • Follow-capable tokens remain persistent after re-authentication.
  • Token scope ownership is explicit and deterministic.
  • Existing OAuth login behavior remains unchanged.

Severity

Medium

This is a significant OAuth lifecycle/data-integrity flaw affecting persistent GitHub integrations.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions