Skip to content

Add OAuth login flow for admin dashboard#21

Open
adrw wants to merge 4 commits intoadrw/admin-dashboardfrom
adrw/admin-cookie-auth
Open

Add OAuth login flow for admin dashboard#21
adrw wants to merge 4 commits intoadrw/admin-dashboardfrom
adrw/admin-cookie-auth

Conversation

@adrw
Copy link
Copy Markdown
Collaborator

@adrw adrw commented Feb 20, 2026

Summary

  • Adds kairo-admin module: a full-featured admin dashboard for Kairo servers
  • Adds kairo-kdocs module: serves Dokka-generated API docs at /_kdocs
  • Adds OAuth 2.0 Authorization Code flow for admin dashboard login
  • Adds cookie-based browser auth via AuthReceiver.BearerTokenOverride

OAuth login flow

  1. User visits /_admin/ → no cookie → auth fails → redirect to /_admin/login
  2. /_admin/login → generates CSRF state cookie → redirects to OAuth provider (e.g. Auth0)
  3. User authenticates → provider redirects to /_admin/callback?code=...&state=...
  4. Server validates state, exchanges code for JWT access token, sets kairo_admin_token HttpOnly cookie
  5. Redirect to /_admin/ → cookie present → verify() succeeds via BearerTokenOverride

Key changes

kairo-admin (new module)

  • AdminDashboardFeature — Kairo feature with HTML dashboard, OAuth routes, and data collectors
  • AdminOAuthConfig — Generic OAuth 2.0 config (authorizeUrl, tokenUrl, clientId, clientSecret, scopes, audience, providerName, logoutUrl)
  • AdminDashboardHandler — Routes: GET /login (start OAuth), GET /callback (exchange code), POST /logout (clear cookie), plus authGet/authPost wrappers that redirect to login on auth failure
  • LoginView — Error page shown only when OAuth is not configured; when configured, /login redirects directly to provider

kairo-kdocs (new module)

  • KdocsFeature — Serves Dokka HTML docs from the classpath at /_kdocs

kairo-rest (modified)

  • AuthReceiver.kt — Added BearerTokenOverride attribute key so admin dashboard can supply JWT from cookie instead of Authorization header; added forCall() factory for non-endpoint auth checks

Consumer code

AdminDashboardFeature(
  config = AdminDashboardConfig(
    serverName = "AI",
    oauth = AdminOAuthConfig(
      authorizeUrl = "https://auth.example.com/authorize",
      tokenUrl = "https://auth.example.com/oauth/token",
      clientId = "...",
      clientSecret = "...",
      providerName = "Auth0",
    ),
  ),
  auth = { superuser() },
),
KdocsFeature(),

Test plan

  • Verify /_admin/ without cookie redirects to /_admin/login
  • Verify /_admin/login redirects to OAuth provider with correct params
  • Verify callback exchanges code for token and sets session cookie
  • Verify /_admin/ with valid cookie loads the dashboard
  • Verify /_admin/logout clears cookie
  • Verify CSRF state validation rejects tampered state
  • Verify Authorization: Bearer header still works for API access
  • Verify /_kdocs serves Dokka docs

🤖 Generated with Claude Code

The admin dashboard serves HTML pages, but verify() only checks
the Authorization header for bearer tokens. Browsers don't send
bearer tokens on page navigation, causing 401 errors when auth
is configured.

Changes:
- AuthReceiver: Add BearerTokenOverride attribute key so verify()
  checks call attributes before falling back to the Authorization
  header
- AdminDashboardHandler: Read kairo_admin_token cookie and set it
  as a BearerTokenOverride attribute on each request. On auth
  failure, redirect to login page instead of returning 401.
- LoginView: Simple login page where users paste a bearer token,
  which gets stored as an HttpOnly cookie

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adrw adrw requested a review from hudson155 as a code owner February 20, 2026 02:53
adrw and others added 2 commits February 19, 2026 22:07
Replace the manual JWT paste approach with a proper OAuth redirect flow.
When AdminOAuthConfig is provided, the login page shows a "Sign in with
[provider]" button that initiates the standard authorization code exchange.
Includes CSRF protection via state parameter cookie validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When OAuth is configured, GET /login now redirects directly to the OAuth
provider. The manual token textarea and POST /login route are removed.
If OAuth is not configured but auth is required, the login page shows
a configuration error message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adrw adrw changed the title Add cookie-based auth for admin dashboard Add OAuth login flow for admin dashboard Feb 20, 2026
GET /login now directly starts the OAuth flow when configured, removing
the intermediate redirect. LoginView is only rendered as an error page
when OAuth is not configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant