Authentication & Sessions

KubeStellar Console uses GitHub OAuth 2.0 for user authentication and JWT-based sessions for maintaining login state. This page documents the full authentication lifecycle.

Overview

The console separates two types of credentials:

CredentialPurposeFlow
GitHub OAuthUser identity (who you are)Browser > GitHub > Backend
KubeconfigCluster access (what you can see)Backend > MCP Bridge > Clusters

GitHub login establishes your identity inside the console. Kubernetes cluster credentials come from your kubeconfig and never pass through GitHub.


Authentication Modes

1. OAuth Mode (startup-oauth.sh)

Full GitHub authentication with multi-user support.

Flow:

  1. User clicks “Sign in with GitHub” on the console login page
  2. Browser redirects to GitHub’s authorization endpoint with the console’s client_id
  3. User authorizes the console on GitHub
  4. GitHub redirects back to http://localhost:8080/auth/github/callback with an authorization code
  5. The Go backend exchanges the authorization code for an access token using the client_secret
  6. Backend fetches the user’s GitHub profile (username, avatar, email)
  7. Backend creates a JWT session token containing the user identity
  8. JWT is stored as an HTTP-only cookie in the browser
  9. User is redirected to the dashboard

Security properties:

  • The client_secret never leaves the backend server
  • The authorization code is single-use and short-lived
  • The access token is used server-side only to fetch the user profile
  • CSRF protection is enforced on the callback (state parameter validation)

2. Development Mode (start-dev.sh)

No authentication required. A local dev-user session is created automatically.

Flow:

  1. Backend starts and detects no OAuth credentials are configured
  2. A dev-user session is created with a default profile
  3. All API requests are treated as authenticated
  4. No login page is shown

This mode is suitable for local development only and should never be used in production.


Session Lifecycle

JWT Structure

The console uses JSON Web Tokens (JWTs) for session management:

FieldDescription
subGitHub username
nameDisplay name
avatarGitHub avatar URL
emailGitHub email (if public)
iatToken issued-at timestamp
expToken expiration timestamp

Session Duration

  • Sessions are valid for the duration configured on the backend (default: 24 hours)
  • The JWT is stored as an HTTP-only, secure cookie
  • Sessions persist across browser restarts (cookie-based)
  • Closing all browser tabs does not end the session

Session Refresh

  • The frontend checks session validity on page load
  • If the JWT is expired, the user is redirected to the login page
  • There is no silent refresh — expired sessions require re-authentication

Logout

When a user logs out:

  1. The frontend calls the /auth/logout endpoint
  2. The backend invalidates the session cookie (sets expiry to the past)
  3. Any active WebSocket connections are closed
  4. The browser is redirected to the login page
  5. Local storage preferences (theme, dashboard layout) are preserved
  6. Cached cluster data is cleared from the frontend

WebSocket Authentication

The console uses WebSocket connections for real-time features (AI Missions, live updates). WebSocket authentication works as follows:

  1. The frontend establishes a WebSocket connection to the backend
  2. The session JWT cookie is sent with the WebSocket upgrade request
  3. The backend validates the JWT before accepting the connection
  4. If the JWT expires during an active WebSocket session, the backend closes the connection
  5. The frontend automatically attempts to reconnect and redirects to login if re-authentication is needed

Security Features

CORS Policy

The backend enforces strict CORS rules:

  • Only the configured origin (e.g., http://localhost:8080) is allowed
  • Credentials (cookies) are included in cross-origin requests
  • Preflight requests are cached to reduce latency

CSRF Protection

  • The OAuth flow uses a state parameter to prevent CSRF attacks
  • The state is generated server-side and validated on the callback
  • Mismatched state values result in a csrf_validation_failed error

XSS Prevention

  • All user-generated content is sanitized with DOMPurify before rendering
  • The Content-Security-Policy header restricts script sources
  • dangerouslySetInnerHTML usage has been eliminated in favor of safe rendering

Path Traversal Protection

  • API endpoints validate and sanitize file paths
  • Directory traversal sequences (../) are rejected
  • Static file serving is restricted to the frontend build directory

MCP Input Validation

  • All MCP (Model Context Protocol) query parameters are validated before being passed to cluster operations
  • Invalid or malicious inputs are rejected with descriptive error messages

Configuring OAuth for Different Environments

EnvironmentHomepage URLCallback URL
Local devhttp://localhost:8080http://localhost:8080/auth/github/callback
Kuberneteshttps://console.your-domain.comhttps://console.your-domain.com/auth/github/callback
OpenShifthttps://ksc.apps.your-cluster.comhttps://ksc.apps.your-cluster.com/auth/github/callback

Each environment requires its own GitHub OAuth App registration with matching callback URLs.


Troubleshooting

”exchange_failed” After GitHub Login

The Client Secret is wrong or has been regenerated:

  1. Go to GitHub Developer Settings > your OAuth App
  2. Generate a new Client Secret
  3. Update GITHUB_CLIENT_SECRET in your .env file
  4. Restart the console

”csrf_validation_failed”

The callback URL in GitHub does not match the console’s URL:

  1. Verify the Authorization callback URL in your GitHub OAuth App settings matches exactly
  2. Clear your browser cookies for localhost
  3. Restart the console

404 or Blank Page After Login

OAuth credentials are not configured correctly:

  1. Verify the .env file exists in the repository root
  2. Check that both GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are set
  3. View backend logs for error details

Session Expires Too Quickly

The JWT expiration is configured on the backend. If sessions expire unexpectedly:

  1. Check system clock synchronization (JWT validation is time-sensitive)
  2. Verify the backend has not been restarted (signing keys may change)