Skip to main content

Overview

Better Hub uses session-based authentication powered by Better Auth. All authenticated API requests require a valid session cookie. There are two ways to authenticate:
  1. GitHub OAuth - Standard OAuth flow (recommended for web apps)
  2. Personal Access Token (PAT) - Sign in with a GitHub PAT (useful for scripts and CLI tools)

Authentication Methods

The standard authentication flow uses GitHub OAuth with configurable scopes.
1

Initiate OAuth

Redirect users to the Better Auth OAuth endpoint:
GET /api/auth/sign-in/social
The OAuth flow will redirect to GitHub for authorization.
2

User Authorizes

Users authorize Better Hub to access their GitHub account with these default scopes:
  • read:user - Read user profile data
  • user:email - Access user email addresses
  • public_repo - Access public repositories
Users can grant additional scopes during sign-in for extended permissions (private repos, etc.)
3

Session Created

After successful authorization, Better Auth creates a session and sets a session cookie.The session is stored in the session table in PostgreSQL:
id
string
Unique session identifier
token
string
Unique session token
userId
string
Associated user ID
expiresAt
DateTime
Session expiration timestamp
ipAddress
string
IP address of the session
userAgent
string
Browser user agent string
4

Make Authenticated Requests

All subsequent API requests automatically include the session cookie.

Personal Access Token (PAT)

For scripts, CLI tools, or testing, you can authenticate using a GitHub Personal Access Token.
PAT authentication creates a session just like OAuth. The PAT is encrypted and stored in the Account table.

Create a GitHub PAT

  1. Go to GitHub Settings → Developer settings → Personal access tokens
  2. Generate a new token (classic) with these scopes:
    • read:user
    • user:email
    • public_repo (or repo for private repositories)

Sign In with PAT

curl -X POST https://www.better-hub.com/api/auth/pat-signin \
  -H "Content-Type: application/json" \
  -d '{
    "pat": "ghp_your_github_token_here"
  }'
Endpoint: POST /api/auth/pat-signin Request Body:
pat
string
required
GitHub Personal Access Token
Response:
{
  "success": true
}
Rate Limit: 5 requests per minute per IP
Never commit your GitHub PAT to version control. Use environment variables or secure secret management.

How PAT Authentication Works

  1. Better Hub validates the PAT against GitHub’s API
  2. Retrieves the authenticated user’s profile
  3. Creates or updates the user in the database
  4. Encrypts the PAT using AES symmetric encryption
  5. Stores the encrypted PAT in the Account table
  6. Creates a session and sets a session cookie
The PAT is stored encrypted and used for subsequent GitHub API calls on your behalf.

Session Management

Session Storage

Sessions are stored in two places:
  1. Database - PostgreSQL session table for persistence
  2. Cookie Cache - JWE-encrypted cookie for performance
Cookie Configuration:
  • Name: Set by Better Auth (typically better-auth.session_token)
  • Max Age: 7 days (604,800 seconds)
  • Strategy: JWE (JSON Web Encryption)
  • Secure: True in production
  • HttpOnly: True (prevents XSS attacks)
  • SameSite: Lax

Check Session Status

To verify if a session is active:
curl -X GET https://www.better-hub.com/api/auth/session \
  -H "Cookie: better-auth.session_token=your_cookie_value"
Response (if authenticated):
{
  "session": {
    "id": "session_abc123",
    "userId": "user_xyz789",
    "expiresAt": "2026-03-10T12:00:00.000Z"
  },
  "user": {
    "id": "user_xyz789",
    "name": "John Doe",
    "email": "john@example.com",
    "image": "https://github.com/avatars/..."
  }
}
Response (if not authenticated):
null

Sign Out

To end a session:
POST /api/auth/sign-out
This will invalidate the session and clear the session cookie.

Making Authenticated Requests

Once authenticated, include the session cookie with every API request.

Browser Requests

When making requests from a browser, cookies are included automatically:
const response = await fetch('/api/user-settings', {
  credentials: 'include' // Ensures cookies are sent
});

Server-Side Requests

For server-side or script-based requests, you need to manage cookies manually:
# Save cookies during PAT sign-in
curl -X POST https://www.better-hub.com/api/auth/pat-signin \
  -H "Content-Type: application/json" \
  -d '{"pat": "ghp_token"}' \
  -c cookies.txt

# Use saved cookies in subsequent requests
curl -X GET https://www.better-hub.com/api/user-settings \
  -b cookies.txt

Authorization Headers

Better Hub uses session cookies for authentication, not Authorization headers. This is different from many REST APIs that use Bearer tokens.
Do NOT use Authorization: Bearer <token> headers. Better Hub authenticates requests via session cookies only.

Error Responses

Authentication errors return these status codes:

401 Unauthorized

The request lacks valid authentication credentials.
{
  "error": "Unauthorized"
}
Causes:
  • No session cookie provided
  • Session expired
  • Invalid session token
Solution: Sign in again via OAuth or PAT

403 Forbidden

The authenticated user lacks permission for the requested resource.
{
  "error": "Forbidden"
}
Causes:
  • Insufficient GitHub scopes
  • Access denied by GitHub
  • User banned or restricted
Solution: Re-authenticate with additional scopes or check permissions

GitHub Token Management

OAuth Token Storage

GitHub OAuth access tokens are:
  • Encrypted using AES symmetric encryption
  • Stored in the Account table’s accessToken field
  • Automatically refreshed when expired (if refresh token available)

Token Scopes

The user’s current GitHub scopes can be checked via:
GET /api/user-scopes
Response:
{
  "scopes": ["read:user", "user:email", "public_repo"]
}
If a user needs additional scopes, they must re-authenticate through the OAuth flow.

Account Updates

Better Hub is configured with updateAccountOnSignIn: true, which means:
  • Scopes are updated on each sign-in
  • Access tokens are refreshed automatically
  • Account information stays in sync with GitHub

Security Best Practices

Use HTTPS

Always use HTTPS in production to prevent session hijacking

Secure Cookies

Session cookies are HttpOnly and Secure in production

Rotate PATs

Regularly rotate Personal Access Tokens

Minimal Scopes

Only request GitHub scopes you actually need
Session Impersonation: Better Hub includes an admin impersonation feature (via the admin plugin). Impersonated sessions have the impersonatedBy field set in the database.

Next Steps

User Settings API

Manage user preferences and settings

GitHub Data API

Access repositories, issues, and PRs

AI Features

Use AI-powered GitHub assistance

Billing API

Check credits and usage limits