Skip to content

Pipeline Plan 15

Seth Ford edited this page Feb 12, 2026 · 2 revisions

The plan file is in a protected directory. Let me present the plan directly here instead.


Implementation Plan: Dashboard Authentication (GitHub OAuth) — Issue #15

Analysis Summary

After thorough codebase exploration, the OAuth authentication flow already exists in dashboard/server.ts. The server has:

  • OAuth config (lines 33-41): GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, DASHBOARD_REPO
  • Session management (lines 173-254): In-memory Map + file-backed persistence, fleet_session cookie (HttpOnly, SameSite=Lax)
  • Auth mode detection (lines 356-367): OAuth / PAT / None modes
  • Public routes (lines 370-385): /login, /auth/*, /api/health, connect endpoints
  • Auth gate (lines 2188-2202): Redirects unauthenticated users to /login
  • OAuth handlers (lines 1921-2003): /auth/github redirect, /auth/callback token exchange, /auth/logout
  • PAT fallback (lines 2005-2064): Username-based login using server PAT
  • Login page (lines 387-510): Styled login UI with OAuth button and PAT form
  • WebSocket auth (line 2194): Rejects unauthenticated WS upgrades

Gaps to Close

  1. CSRF protection: No state parameter in OAuth flow
  2. Developer auto-registration: OAuth callback doesn't register user in developer registry
  3. Session-authenticated heartbeats: Heartbeat endpoint doesn't validate dashboard sessions
  4. Frontend auth awareness: app.js has no user menu, logout, or session display
  5. OAuth error handling: Callback doesn't handle error parameter (user denies consent)
  6. Secure cookie: Cookie lacks Secure flag when running over HTTPS

Files to Modify

# File Action Purpose
1 dashboard/server.ts Modify CSRF state, developer auto-registration, heartbeat session validation, secure cookie, OAuth error handling, /api/session endpoint
2 dashboard/public/app.js Modify User session display, logout, auth-aware UI
3 dashboard/public/index.html Modify User menu in header
4 dashboard/public/styles.css Modify User menu styles

Implementation Steps

Step 1: Add CSRF state parameter to OAuth flow

  • Add Map<string, number> for pending OAuth states (state → expiry)
  • In handleAuthGitHub(): generate random state, store with 10-min TTL, include in GitHub authorize URL
  • In handleAuthCallback(): validate state matches, delete after use

Step 2: Handle OAuth error responses

  • In handleAuthCallback(), check for error query parameter before code
  • Redirect to /login with error message when GitHub returns an error

Step 3: Auto-register developer on first OAuth/PAT login

  • After session creation in handleAuthCallback() and handlePatLogin(), add user to developerRegistry
  • Use developer_id: username, machine_name: "dashboard", platform: "web"

Step 4: Add Secure cookie flag for HTTPS

  • Check process.env.DASHBOARD_SECURE === "true"
  • Append ; Secure to cookie string when appropriate

Step 5: Add session-based identity to heartbeat endpoint

  • When auth is enabled and fleet_session cookie is present, extract session
  • Enrich heartbeat with authenticated githubUser from session
  • CLI heartbeats without cookies continue to work via invite-token path

Step 6: Add GET /api/session endpoint

  • Protected route returning { user, avatarUrl, isAdmin } from current session
  • Lets frontend display user info

Step 7: Add user menu to frontend

  • index.html: Add <div id="user-menu"> in header
  • styles.css: Avatar circle, dropdown, logout link styles
  • app.js: Fetch /api/session on load, populate menu, logout handler

Step 8: Add test coverage

  • New scripts/sw-dashboard-test.sh following bash test harness conventions
  • Register in package.json

Task Checklist

  • Task 1: Add CSRF state parameter to OAuth redirect and validate on callback
  • Task 2: Handle OAuth error responses in callback
  • Task 3: Auto-register developer in registry on successful OAuth/PAT login
  • Task 4: Add Secure cookie flag when serving over HTTPS
  • Task 5: Add session-based identity enrichment to heartbeat endpoint
  • Task 6: Add GET /api/session endpoint
  • Task 7: Add user menu HTML to index.html header
  • Task 8: Add user menu CSS styles to styles.css
  • Task 9: Add auth-aware JavaScript to app.js
  • Task 10: Add sw-dashboard-test.sh with auth test coverage
  • Task 11: Register new test in package.json
  • Task 12: Run all existing tests to verify no regressions

Testing Approach

Unit Tests (sw-dashboard-test.sh): OAuth state generation/validation, session creation/expiry, developer auto-registration, heartbeat identity enrichment, public vs protected route classification.

Manual E2E: Full OAuth flow with real GitHub app, PAT mode, no-auth mode, WebSocket auth rejection.

Regression: npm test — all 22 existing suites pass.


Definition of Done

  • CSRF state parameter in OAuth redirect, validated on callback
  • OAuth error responses handled gracefully
  • Developer auto-registered on first login
  • Session cookie includes Secure flag when appropriate
  • Heartbeat endpoint enriches identity from session
  • GET /api/session endpoint works
  • Frontend displays user menu with avatar, username, logout
  • New test suite passes
  • All 22 existing test suites pass
  • No OWASP Top 10 vulnerabilities introduced

Clone this wiki locally