Files
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

254 lines
9.7 KiB
Markdown

<objective>
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
</objective>
<context>
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
</context>
<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:
```xml
<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:
```markdown
# 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>