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>
This commit is contained in:
253
.prompts/001-oidc-auth-plan/completed/001-oidc-auth-plan.md
Normal file
253
.prompts/001-oidc-auth-plan/completed/001-oidc-auth-plan.md
Normal file
@@ -0,0 +1,253 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user