Files
claude-web-ui/.prompts/001-oidc-auth-plan/completed/001-oidc-auth-plan.md
Nikolas Syring 1186cb1b5e feat: Add OIDC authentication with Authentik integration
- Add OIDC login flow with Authentik provider
- Implement session-based auth with Redis store
- Add avatar display from OIDC claims
- Fix input field performance with react-textarea-autosize
- Stabilize callbacks to prevent unnecessary re-renders
- Fix history loading to skip empty session files
- Add 2-row default height for input textarea

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 06:07:22 +01:00

9.7 KiB

Create an implementation roadmap for OIDC authentication with Authentik for Claude Web UI.

Purpose: Guide phased implementation of OIDC authentication with clear milestones Input: Current codebase structure, Authentik configuration requirements Output: oidc-auth-plan.md with 4-5 implementation phases

Project: Claude Web UI - Web interface for Claude Code CLI URL: https://agents.sneakercloud.de Stack: - Backend: Node.js/Express (server.js) with WebSocket - Frontend: React/Vite with JSX components - Auth Provider: Authentik (https://auth.sneakercloud.de)

Current backend structure:

  • Single file: backend/server.js (~999 lines)
  • Express app with CORS, WebSocket server
  • No authentication currently implemented
  • REST endpoints: /api/hosts, /api/projects, /api/health, /api/browse, /api/upload, /api/history

Current frontend structure:

  • src/App.jsx - Main application
  • src/contexts/SessionContext.jsx - Session state management
  • src/hooks/useClaudeSession.js - WebSocket connection hook
  • src/components/ - UI components (ChatPanel, Sidebar, Header, etc.)

Authentication requirements:

  • OIDC Provider: Authentik
  • Auth Flow: Redirect Flow (Authorization Code)
  • Token Storage: httpOnly Cookies (XSS-safe)
  • Groups: agent-admin (full access), agent-users (standard access)
  • Session Duration: Configurable, with refresh token support

<planning_requirements> Requirements to address:

  1. Authentik OIDC Application setup (Provider + Application)
  2. Backend OIDC middleware with session management
  3. Frontend AuthContext with login/logout flow
  4. Protected routes and API endpoints
  5. Group-based access control (admin vs users)
  6. httpOnly cookie-based token storage

Constraints:

  • Must work with existing WebSocket architecture
  • Minimal changes to existing components
  • Single-file backend (server.js) - consider refactoring into modules
  • Production-ready security (no localStorage tokens)

Success criteria:

  • Unauthenticated users see login page
  • Login redirects to Authentik, returns with session
  • WebSocket connections are authenticated
  • API endpoints check authentication
  • Admin users have additional capabilities
  • Sessions persist across browser refresh </planning_requirements>

<output_structure> Save to: .prompts/001-oidc-auth-plan/oidc-auth-plan.md

Structure the plan using this XML format:

<plan>
  <summary>
    {One paragraph overview of the OIDC implementation approach}
  </summary>

  <phases>
    <phase number="1" name="authentik-setup">
      <objective>Create OIDC Provider and Application in Authentik</objective>
      <tasks>
        <task priority="high">Create OAuth2/OIDC Provider in Authentik</task>
        <task priority="high">Configure redirect URIs for agents.sneakercloud.de</task>
        <task priority="high">Create Application and bind to Provider</task>
        <task priority="medium">Create groups: agent-admin, agent-users</task>
        <task priority="medium">Configure group claims in OIDC scope</task>
      </tasks>
      <deliverables>
        <deliverable>Authentik OIDC app configured</deliverable>
        <deliverable>Client ID and Secret generated</deliverable>
        <deliverable>Groups created and mapped</deliverable>
      </deliverables>
      <dependencies>Admin access to Authentik</dependencies>
      <execution_notes>
        Document the exact Authentik configuration steps.
        Save Client ID/Secret to .env (not committed).
        Test OIDC endpoints manually before proceeding.
      </execution_notes>
    </phase>

    <phase number="2" name="backend-auth-module">
      <objective>Implement OIDC authentication in backend</objective>
      <tasks>
        <task priority="high">Install dependencies: openid-client, cookie-parser, express-session</task>
        <task priority="high">Create auth module with OIDC client configuration</task>
        <task priority="high">Implement /api/auth/login - redirect to Authentik</task>
        <task priority="high">Implement /api/auth/callback - handle OIDC response</task>
        <task priority="high">Implement /api/auth/logout - clear session</task>
        <task priority="medium">Implement /api/auth/me - return current user info</task>
        <task priority="medium">Create auth middleware for protected routes</task>
        <task priority="medium">Add session validation to WebSocket connections</task>
      </tasks>
      <deliverables>
        <deliverable>backend/auth.js module</deliverable>
        <deliverable>Session-based authentication with httpOnly cookies</deliverable>
        <deliverable>Protected API routes</deliverable>
      </deliverables>
      <dependencies>Phase 1 complete (Authentik configured)</dependencies>
      <execution_notes>
        Use openid-client for OIDC implementation.
        Store session in memory initially (can add Redis later).
        Validate ID tokens and extract user info.
        Pass user context to WebSocket sessions.
      </execution_notes>
    </phase>

    <phase number="3" name="frontend-auth-context">
      <objective>Implement React authentication context and UI</objective>
      <tasks>
        <task priority="high">Create AuthContext with user state management</task>
        <task priority="high">Create useAuth hook for components</task>
        <task priority="high">Create LoginPage component</task>
        <task priority="high">Implement protected route wrapper</task>
        <task priority="medium">Add login/logout buttons to Header</task>
        <task priority="medium">Show user info in UI</task>
        <task priority="low">Add loading state during auth check</task>
      </tasks>
      <deliverables>
        <deliverable>src/contexts/AuthContext.jsx</deliverable>
        <deliverable>src/hooks/useAuth.js</deliverable>
        <deliverable>src/components/LoginPage.jsx</deliverable>
        <deliverable>src/components/ProtectedRoute.jsx</deliverable>
      </deliverables>
      <dependencies>Phase 2 complete (backend auth working)</dependencies>
      <execution_notes>
        Check /api/auth/me on app load to determine auth state.
        Redirect to login page if not authenticated.
        After login, redirect back to original URL.
        Handle auth errors gracefully.
      </execution_notes>
    </phase>

    <phase number="4" name="group-permissions">
      <objective>Implement group-based access control</objective>
      <tasks>
        <task priority="high">Extract groups from OIDC claims in backend</task>
        <task priority="high">Add isAdmin flag to user context</task>
        <task priority="medium">Protect admin-only API routes</task>
        <task priority="medium">Show admin UI elements conditionally</task>
        <task priority="low">Add user management UI for admins (future)</task>
      </tasks>
      <deliverables>
        <deliverable>Group-based route protection</deliverable>
        <deliverable>Admin-specific UI elements</deliverable>
      </deliverables>
      <dependencies>Phase 3 complete</dependencies>
      <execution_notes>
        agent-admin: Full access, all hosts, all features
        agent-users: Limited hosts, standard features
        Check group membership on backend, pass to frontend.
      </execution_notes>
    </phase>

    <phase number="5" name="testing-polish">
      <objective>Test, document, and polish the implementation</objective>
      <tasks>
        <task priority="high">Test full auth flow end-to-end</task>
        <task priority="high">Test WebSocket reconnection after session refresh</task>
        <task priority="medium">Handle edge cases (expired sessions, revoked tokens)</task>
        <task priority="medium">Update BookStack documentation</task>
        <task priority="low">Add session timeout warnings</task>
      </tasks>
      <deliverables>
        <deliverable>Working OIDC authentication</deliverable>
        <deliverable>Updated documentation</deliverable>
      </deliverables>
      <dependencies>Phase 4 complete</dependencies>
    </phase>
  </phases>

  <metadata>
    <confidence level="high">
      OIDC with Authentik is well-documented pattern.
      httpOnly cookies with redirect flow is industry standard.
      openid-client is mature library for Node.js.
    </confidence>
    <dependencies>
      - Authentik admin access
      - DNS/SSL already configured (agents.sneakercloud.de)
      - Current app deployed and working
    </dependencies>
    <open_questions>
      - Session storage: In-memory vs Redis?
      - Token refresh strategy: Silent refresh vs re-login?
      - Should WebSocket auth use same session or separate token?
    </open_questions>
    <assumptions>
      - Authentik is accessible at auth.sneakercloud.de
      - User has admin access to create OIDC app
      - Current backend can be extended (single server.js file)
      - Frontend can add new components without major refactoring
    </assumptions>
  </metadata>
</plan>

</output_structure>

<summary_requirements> Create .prompts/001-oidc-auth-plan/SUMMARY.md

Structure:

# OIDC Auth Plan Summary

**{Substantive one-liner describing the plan}**

## Version
v1

## Key Findings
- {Phase 1 objective}
- {Phase 2 objective}
- {Phase 3 objective}
- {Key architectural decision}

## Decisions Needed
{Specific decisions requiring user input}

## Blockers
{External impediments, or "None"}

## Next Step
{Concrete forward action - likely "Execute Phase 1"}

---
*Confidence: High*
*Full output: oidc-auth-plan.md*

</summary_requirements>

<success_criteria>

  • Plan addresses all 5 requirements (Authentik, backend, frontend, routes, groups)
  • Phases are sequential and logically ordered
  • Each phase builds on previous deliverables
  • Tasks are specific and actionable
  • Metadata captures open questions and assumptions
  • SUMMARY.md created with phase overview
  • Ready for implementation prompts to consume </success_criteria>