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

403 lines
11 KiB
Markdown

# OIDC Authentication Implementation - Executive Summary
## Overview
This plan details the complete implementation of OIDC authentication for Claude Web UI using Authentik as the identity provider. The implementation adds secure, production-ready authentication with group-based access control while preserving the existing WebSocket architecture.
## Current State
**Backend:**
- Single-file Express server (`backend/server.js`, 999 lines)
- WebSocket-based Claude Code CLI interface
- No authentication or authorization
- In-memory session storage
**Frontend:**
- React application with SessionContext for state management
- Direct WebSocket connections
- localStorage for session persistence
- No authentication UI
## Target State
**Authentication:**
- OIDC provider: Authentik (auth.sneakercloud.de)
- Authorization flow: Authorization Code with PKCE
- Token storage: httpOnly cookies (XSS-safe)
- Session backend: Redis (persistent, scalable)
**Authorization:**
- Groups: `agent-admin` (full access), `agent-users` (standard access)
- Protected REST endpoints
- Authenticated WebSocket connections
- User-isolated sessions
## Implementation Approach
### 5 Phases, 11-16 Days
#### Phase 1: Foundation (2-3 days)
- Configure Authentik OIDC Provider/Application
- Refactor monolithic backend into modules
- Add dependencies (express-session, openid-client, Redis)
- Implement Redis session store
#### Phase 2: Authentication Flow (2-3 days)
- Implement OIDC client wrapper
- Create auth routes (login, callback, logout)
- Configure secure session cookies
- Handle token refresh
#### Phase 3: API Protection (2-3 days)
- Create authentication middleware
- Protect all REST endpoints
- Secure WebSocket connections
- Associate sessions with users
#### Phase 4: Frontend UI (3-4 days)
- Create AuthContext for authentication state
- Build login page component
- Add protected route wrapper
- Integrate with existing SessionContext
- Add user menu/logout
#### Phase 5: Production Hardening (2-3 days)
- Security enhancements (CSRF, rate limiting, CSP)
- Logging and monitoring
- Error handling and edge cases
- Documentation
- Testing
## Key Technical Decisions
### 1. Backend Refactoring
**Decision:** Split monolithic `server.js` into modular structure
**Rationale:**
- Improves maintainability
- Separates concerns
- Easier testing
- Supports future growth
**Structure:**
```
backend/
├── server.js # Entry point
├── config/auth.js # Auth configuration
├── middleware/ # Auth & session middleware
├── routes/ # API, auth, WebSocket routes
└── utils/ # OIDC client wrapper
```
### 2. Session Storage
**Decision:** Redis with express-session
**Rationale:**
- Persistent across restarts
- Scalable to multiple backend instances
- Fast session lookups (<10ms)
- Industry standard
**Alternative Considered:** In-memory sessions
- **Rejected:** Lost on restart, not scalable
### 3. Token Storage
**Decision:** httpOnly cookies with encrypted tokens in Redis
**Rationale:**
- httpOnly prevents XSS attacks
- Secure flag ensures HTTPS-only
- sameSite=lax prevents CSRF
- Encryption at rest protects Redis compromise
**Alternative Considered:** localStorage
- **Rejected:** Vulnerable to XSS
### 4. WebSocket Authentication
**Decision:** Cookie-based session validation on upgrade
**Rationale:**
- Cookies automatically included in upgrade request
- Consistent with REST API auth
- No need for separate token mechanism
**Implementation:**
- Parse cookies from upgrade request headers
- Load session from Redis
- Validate user before accepting connection
- Reject upgrade with 1008 code if unauthorized
### 5. OIDC Library
**Decision:** `openid-client` (certified OIDC client)
**Rationale:**
- Official OpenID Foundation certified
- Actively maintained
- Built-in PKCE support
- Automatic discovery
**Alternative Considered:** `passport-openidconnect`
- **Rejected:** More complex, passport overhead not needed
## Security Considerations
### Authentication
- Authorization Code flow with PKCE
- State parameter for CSRF protection
- Nonce validation in ID token
- Token signature verification
- HTTPS-only in production
### Session Management
- httpOnly cookies (no JavaScript access)
- Secure flag (HTTPS-only)
- sameSite=lax (CSRF protection)
- 24-hour expiry with refresh
- Encrypted tokens at rest
### API Protection
- All endpoints require authentication
- Group-based authorization
- Rate limiting on auth endpoints
- Origin validation on WebSocket upgrade
- Content Security Policy headers
### Token Handling
- Access tokens encrypted in Redis
- Refresh tokens encrypted in Redis
- Auto-refresh 5 minutes before expiry
- Tokens cleared on logout
- No tokens in logs
## Group-Based Access Control
### agent-users (Standard Access)
- View hosts and projects
- Create and manage own Claude sessions
- Upload files to own sessions
- View own session history
- Standard WebSocket access
### agent-admin (Full Access)
- All `agent-users` permissions
- View all users' sessions (future)
- Access admin endpoints (future)
- Modify system configuration (future)
**Note:** Initial implementation focuses on authentication and basic group enforcement. Fine-grained permissions can be expanded post-MVP.
## Integration Points
### Authentik Configuration
```yaml
Provider:
Name: Claude Web UI
Type: OAuth2/OIDC
Client Type: Confidential
Flow: Authorization Code
Scopes: openid, profile, email, groups
Application:
Name: Claude Web UI
Provider: [linked]
Launch URL: https://agents.sneakercloud.de
Redirect URI: https://agents.sneakercloud.de/auth/callback
```
### Environment Variables
```bash
# OIDC
OIDC_ISSUER=https://auth.sneakercloud.de/application/o/claude-web-ui/
OIDC_CLIENT_ID=<from_authentik>
OIDC_CLIENT_SECRET=<from_authentik>
OIDC_REDIRECT_URI=https://agents.sneakercloud.de/auth/callback
# Session
SESSION_SECRET=<generate_32_bytes>
SESSION_MAX_AGE=86400000 # 24 hours
REDIS_URL=redis://redis:6379
# App
NODE_ENV=production
FRONTEND_URL=https://agents.sneakercloud.de
```
### Docker Compose Updates
- Add Redis service
- Mount Redis volume for persistence
- Add environment variables
- Configure service dependencies
## Risk Assessment
### High Risk
**WebSocket Authentication Complexity**
- Mitigation: Thorough testing, fallback to polling
- Contingency: Feature flag to disable auth temporarily
**Authentik Downtime**
- Mitigation: Session caching, graceful degradation
- Contingency: Allow continued use of valid sessions
**Session Store Failure (Redis)**
- Mitigation: Redis persistence, backup strategy
- Contingency: Fallback to in-memory (degraded mode)
### Medium Risk
**Token Refresh Failures**
- Mitigation: Retry logic, clear error messages
- Contingency: Force re-login
**CORS/Cookie Issues**
- Mitigation: Proper domain configuration, testing
- Contingency: Documented troubleshooting steps
### Low Risk
**Group Mapping Errors**
- Mitigation: Default to `agent-users` if no groups
- Contingency: Manual group assignment in Authentik
## Testing Strategy
### Unit Tests
- OIDC client wrapper
- Authentication middleware
- Session management functions
### Integration Tests
- Full login flow
- Token exchange
- Session persistence
- WebSocket authentication
### Manual Tests
- Login/logout flow
- Session refresh
- Token expiry handling
- Group-based access
- Multiple concurrent users
- Admin vs user permissions
### Security Tests
- XSS prevention (httpOnly cookies)
- CSRF protection
- Unauthorized API access
- Session hijacking attempts
- Token replay attacks
## Rollback Plan
**Feature Flag:** `AUTH_ENABLED` environment variable
**Rollback Steps:**
1. Set `AUTH_ENABLED=false`
2. Restart backend service
3. Authentication middleware skipped
4. Frontend shows app without login
5. Investigate and fix issues
6. Re-enable with `AUTH_ENABLED=true`
**Data Preservation:**
- Sessions stored in Redis persist
- User data not lost
- Can re-enable seamlessly
## Success Criteria
### Functional
- [ ] Unauthenticated users cannot access app
- [ ] Login redirects to Authentik and back successfully
- [ ] WebSocket connections authenticated
- [ ] Sessions persist across browser refresh
- [ ] Logout clears session completely
- [ ] Group-based access control enforced
### Performance
- [ ] Auth middleware overhead <100ms
- [ ] Session lookup <10ms
- [ ] No WebSocket latency impact
- [ ] Token refresh transparent to user
### Security
- [ ] Zero XSS vulnerabilities
- [ ] Zero unauthorized access
- [ ] Tokens encrypted at rest
- [ ] HTTPS-only in production
- [ ] Rate limiting effective
### User Experience
- [ ] Login flow <5 seconds
- [ ] Clear error messages
- [ ] No unnecessary re-authentication
- [ ] Seamless session refresh
## Future Enhancements
**Post-MVP Features:**
- Multi-factor authentication via Authentik
- API keys for CLI/programmatic access
- Session management UI (view/revoke sessions)
- Audit log for all actions
- Fine-grained RBAC expansion
- User preferences/settings storage
- SSO with other internal services
## Dependencies
### NPM Packages
- `express-session@^1.18.0` - Session management
- `connect-redis@^7.1.0` - Redis session store
- `redis@^4.6.0` - Redis client
- `openid-client@^5.6.0` - OIDC client
- `cookie-parser@^1.4.6` - Cookie parsing
### Infrastructure
- Redis (session storage)
- Authentik (identity provider)
- Docker (containerization)
### External Services
- Authentik @ auth.sneakercloud.de
- Redis instance (new or existing)
## Documentation Deliverables
1. **AUTHENTICATION.md** - System overview and architecture
2. **SETUP.md** - Step-by-step Authentik configuration
3. **CONFIGURATION.md** - Environment variables reference
4. **TROUBLESHOOTING.md** - Common issues and solutions
5. **README.md** - Updated with authentication section
## Timeline Summary
| Phase | Duration | Key Deliverables |
|-------|----------|------------------|
| 1: Foundation | 2-3 days | Authentik setup, backend refactor, Redis |
| 2: Auth Flow | 2-3 days | OIDC routes, token handling, callbacks |
| 3: API Protection | 2-3 days | Middleware, protected endpoints, WebSocket auth |
| 4: Frontend UI | 3-4 days | AuthContext, login page, user menu |
| 5: Hardening | 2-3 days | Security, logging, testing, docs |
| **Total** | **11-16 days** | Production-ready OIDC authentication |
## Approval & Next Steps
**This Plan:**
- Provides complete roadmap for OIDC implementation
- Addresses all security requirements
- Maintains existing functionality
- Enables phased rollout
- Includes rollback strategy
**Next Steps:**
1. Review and approve plan
2. Set up Authentik provider/application
3. Begin Phase 1 implementation
4. Schedule checkpoints after each phase
5. Plan production deployment
**Questions/Concerns:**
- Authentik already configured or needs setup?
- Redis instance available or needs provisioning?
- Preferred timeline/priority adjustments?
- Additional requirements or constraints?