GitHub OAuth & Tokens

Oversight uses GitHub for authentication (via Supabase OAuth) and for API access to fetch PRs, issues, diffs, and post review comments. This page covers setting up the OAuth app, token permissions, and the fallback PAT flow.

OAuth App Setup

Oversight authenticates users through Supabase, which delegates to a GitHub OAuth App. You need to create one and configure both GitHub and Supabase.

  1. Go to GitHub → Settings → Developer settings → OAuth Apps.
  2. Click New OAuth App.
  3. Fill in the fields:
    FieldValue
    Application name oversight (or any name you prefer)
    Homepage URL http://localhost:5173 (or your deployed URL)
    Authorization callback URL https://<project-ref>.supabase.co/auth/v1/callback
  4. After creation, copy the Client ID.
  5. Generate a Client Secret and copy it.
  6. Configure in two places:
    • Supabase Dashboard → Authentication → Providers → GitHub — paste Client ID and Client Secret.
    • .env file — set GITHUB_OAUTH_CLIENT_ID and GITHUB_OAUTH_CLIENT_SECRET.

Token Permissions

The OAuth flow requests the repo scope from GitHub. This grants oversight access to:

Scope details: The repo scope includes repo:status, repo_deployment, public_repo, repo:invite, and security_events. Oversight only uses the read/write access to repos, PRs, and issues.

How the OAuth Flow Works

Oversight has two OAuth flows — one for the web dashboard and one for the runner.

Web Dashboard

The standard Supabase OAuth flow. The browser redirects to GitHub, the user authorizes, and Supabase creates a session. The GitHub provider token is stored in the session and forwarded to the server as an x-github-token header on API requests.

Task Runner

When the runner starts and needs a GitHub token, it spins up a temporary local HTTP server and opens the browser to the Supabase OAuth URL. After authentication, the callback page extracts the provider_token from the URL hash fragment and posts it back to the local server. The runner caches this token on disk at ~/.oversight/github-token for subsequent restarts.

Personal Access Token Fallback

For headless environments where a browser is not available (CI, remote servers), you can set the GITHUB_PAT environment variable instead. The runner and server will use it as a fallback when no OAuth token is present.

.env env
# Fine-grained PAT or classic PAT with repo scope
GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxx

Creating a PAT

  1. Go to GitHub → Settings → Developer settings → Personal access tokens.
  2. Choose Tokens (classic) for broad access, or Fine-grained tokens for specific repos.
  3. For a classic token, select the repo scope.
  4. For a fine-grained token, grant Read and Write access to Pull requests and Issues, and Read access to Contents and Metadata.

Token Refresh

GitHub OAuth tokens expire. When a token expires, oversight handles it automatically:

  1. A GitHub API call returns 401 or 403.
  2. The server detects this via the isGitHubAuthError() check and returns { githubReauth: true } to the frontend.
  3. The frontend calls POST /api/auth/refresh-github with the stored refresh token.
  4. The server exchanges the refresh token with GitHub for a new access token and a rotated refresh token.
  5. If the refresh fails, the user is prompted to re-authenticate via the OAuth flow.
Note: GitHub rotates refresh tokens on each use. The frontend must store the new refresh token returned by the refresh endpoint.

Multi-Repo Access

Because the OAuth repo scope grants access to all repositories the user can see on GitHub, oversight automatically works with any repo the authenticated user has access to — including private repos across multiple organizations.

The server validates repo access on each request by calling the GitHub API. If a user tries to add a repo they cannot access, oversight returns a 403 error. When listing repos, oversight filters results to only show repos accessible to the current user's GitHub token.

Token Resolution Order

When the server needs a GitHub token for an API request, it checks in this order:

  1. x-github-token header — sent by the frontend from the OAuth session.
  2. GITHUB_PAT env var — fallback for headless environments.

The runner has its own resolution: OAuth provider token from browser login, then cached token at ~/.oversight/github-token, then GITHUB_PAT.