Authentication & Authorization
This document covers the authentication and authorization system used in LyfeAI Provider.
Overview
LyfeAI Provider currently implements a mock authentication system for development and demonstration purposes. The system uses localStorage-based session management with predefined demo accounts. A role-based access control (RBAC) system is implemented to demonstrate healthcare-appropriate access patterns.
⚠️ Important: This is a demonstration authentication system and should NOT be used in production. See the "Migration to Production Auth" section for production requirements.
Authentication Flow
Login Process
sequenceDiagram
participant User
participant LoginPage
participant AuthService
participant LocalStorage
participant AppShell
User->>LoginPage: Enter credentials
LoginPage->>AuthService: Validate credentials
AuthService->>AuthService: Check against predefined users
AuthService->>LocalStorage: Store user session
AuthService->>LoginPage: Return success/failure
LoginPage->>AppShell: Redirect to dashboard
AppShell->>LocalStorage: Check auth status
AppShell->>User: Render authenticated UI
Session Management
The mock authentication system uses browser localStorage for session persistence:
// Session structure stored in localStorage
interface UserSession {
id: string;
email: string;
name: string;
role: UserRole;
permissions: Permission[];
loginTime: string;
expiresAt?: string; // Not currently enforced
}
Current Implementation Details:
- Sessions are stored in
localStorageunder the keycurrentUser - No actual session expiration is enforced
- No server-side session validation
- Credentials are checked against hardcoded user list in
lib/mock-users.ts
Demo Accounts
For development and demonstration, the system includes predefined accounts:
| Password | Role | Description | |
|---|---|---|---|
| [email protected] | admin123 | Admin | Full system access (auto-login enabled) |
| [email protected] | doctor123 | Doctor | Clinical access, orders, care plans |
| [email protected] | nurse123 | Nurse | Patient care, limited ordering |
| [email protected] | staff123 | Staff | Basic patient access |
Note: The admin account automatically logs in when visiting the application for demonstration convenience.
Role-Based Access Control (RBAC)
User Roles
Admin
- Full system access
- User management
- System configuration
- Audit log access
- All clinical features
Doctor
- Full patient access
- Create/modify orders
- Care plan management
- AI clinical tools
- Communication features
Nurse
- Patient access
- Care plan execution
- Limited ordering
- Communication features
- Vital signs management
Staff
- Basic patient access
- View-only medical records
- Schedule management
- Basic communication
Patient (Portal Only)
- Personal health records
- Appointment scheduling
- Secure messaging
- Document upload
Permission Matrix
| Feature | Admin | Doctor | Nurse | Staff | Patient |
|---|---|---|---|---|---|
| View Patients | ✓ | ✓ | ✓ | ✓ | Own only |
| Edit Patients | ✓ | ✓ | ✓ | Limited | Own only |
| Delete Patients | ✓ | - | - | - | - |
| Create Orders | ✓ | ✓ | Limited | - | - |
| View Orders | ✓ | ✓ | ✓ | ✓ | Own only |
| Manage Care Plans | ✓ | ✓ | ✓ | - | View own |
| AI Tools | ✓ | ✓ | ✓ | Limited | Limited |
| User Management | ✓ | - | - | - | - |
| System Config | ✓ | - | - | - | - |
| Audit Logs | ✓ | - | - | - | - |
| EHR Integration | ✓ | ✓ | - | - | - |
| Analytics | ✓ | ✓ | Limited | - | - |
Permission Implementation
// lib/rbac.ts
export const permissions = {
// Patient permissions
'patients:view': ['admin', 'doctor', 'nurse', 'staff'],
'patients:create': ['admin', 'doctor', 'nurse'],
'patients:update': ['admin', 'doctor', 'nurse'],
'patients:delete': ['admin'],
// Order permissions
'orders:view': ['admin', 'doctor', 'nurse', 'staff'],
'orders:create': ['admin', 'doctor'],
'orders:create:limited': ['nurse'], // Only certain order types
'orders:acknowledge': ['admin', 'doctor'],
// Care plan permissions
'care-plans:view': ['admin', 'doctor', 'nurse'],
'care-plans:create': ['admin', 'doctor', 'nurse'],
'care-plans:update': ['admin', 'doctor', 'nurse'],
// System permissions
'system:config': ['admin'],
'users:manage': ['admin'],
'audit:view': ['admin'],
// AI permissions
'ai:document-processing': ['admin', 'doctor', 'nurse'],
'ai:clinical-insights': ['admin', 'doctor', 'nurse'],
'ai:image-analysis': ['admin', 'doctor'],
};
Authorization Patterns
Server-Side Authorization
All server actions check permissions before executing:
// Example from patient-actions.ts
export async function deletePatient(id: string) {
const user = await getCurrentUser();
if (!hasPermission(user, 'patients:delete')) {
return {
success: false,
error: 'Unauthorized: Insufficient permissions'
};
}
// Proceed with deletion...
}
Client-Side Authorization
UI elements are conditionally rendered based on permissions:
// Example component
function PatientActions({ patient }) {
const { user } = useAuth();
const canEdit = hasPermission(user, 'patients:update');
const canDelete = hasPermission(user, 'patients:delete');
return (
<>
{canEdit && <EditButton patient={patient} />}
{canDelete && <DeleteButton patient={patient} />}
</>
);
}
Route Protection
The AppShell component enforces route-level access:
// components/app-shell.tsx
const protectedRoutes = {
'/admin': ['admin'],
'/orders': ['admin', 'doctor', 'nurse'],
'/analytics': ['admin', 'doctor'],
};
function AppShell({ children }) {
const { user } = useAuth();
const pathname = usePathname();
if (!user) {
redirect('/login');
}
const requiredRoles = protectedRoutes[pathname];
if (requiredRoles && !requiredRoles.includes(user.role)) {
redirect('/unauthorized');
}
return <>{children}</>;
}
Security Best Practices
1. Password Security (Current State)
- ⚠️ Passwords are stored in plain text in the mock system
- No password hashing implemented
- No password requirements enforced
- No password reset functionality
- Production Note: Must implement bcrypt hashing and secure password policies
2. Session Security (Current State)
- ⚠️ Sessions stored in localStorage (vulnerable to XSS)
- No session expiration implemented
- No secure tokens or cookies
- No CSRF protection
- Production Note: Must implement secure session management with HttpOnly cookies
3. API Security (Current State)
- Basic authentication checks in server actions
- Limited input validation
- Database operations use Supabase client (provides some SQL injection protection)
- Basic XSS protection from React's default escaping
- Production Note: Needs comprehensive security audit and hardening
4. Data Access Security (Current State)
- ⚠️ RLS policies defined but may not be properly enforced
- No field-level encryption implemented
- No audit logging system
- Production Note: Must implement comprehensive data security measures
5. HIPAA Compliance (Current State)
- ⚠️ NOT HIPAA compliant in current state
- Basic access control demonstration only
- No audit trails implemented
- No encryption at rest
- HTTPS provides encryption in transit (when deployed)
- Production Note: Extensive work required for HIPAA compliance
Implementation Details
useAuth Hook
The central authentication hook provides:
interface UseAuthReturn {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
hasPermission: (permission: string) => boolean;
hasRole: (role: UserRole) => boolean;
}
Permission Checking
// Check single permission
if (hasPermission(user, 'patients:view')) {
// User can view patients
}
// Check multiple permissions
if (hasAnyPermission(user, ['orders:create', 'orders:create:limited'])) {
// User can create some type of order
}
// Check all permissions
if (hasAllPermissions(user, ['patients:view', 'patients:update'])) {
// User can both view and update patients
}
Custom Authorization Rules
Complex authorization logic can be implemented:
// Provider can only see their own patients
function canViewPatient(user: User, patient: Patient): boolean {
if (user.role === 'admin') return true;
if (user.role === 'doctor' && patient.primaryProviderId === user.id) return true;
if (hasPermission(user, 'patients:view:all')) return true;
return false;
}
Testing Authorization
Unit Tests
describe('Authorization', () => {
test('admin can delete patients', () => {
const admin = { role: 'admin', permissions: ['patients:delete'] };
expect(hasPermission(admin, 'patients:delete')).toBe(true);
});
test('nurse cannot delete patients', () => {
const nurse = { role: 'nurse', permissions: [] };
expect(hasPermission(nurse, 'patients:delete')).toBe(false);
});
});
Integration Tests
test('unauthorized user cannot access admin routes', async () => {
const user = await loginAs('[email protected]');
const response = await fetch('/admin');
expect(response.status).toBe(403);
});
Migration to Production Auth
When moving to production, replace the demo auth system with:
-
OAuth2/OIDC Provider
- Integration with hospital SSO
- Multi-factor authentication
- Token-based authentication
-
Database-Backed Sessions
- PostgreSQL session store
- Redis for session caching
- Distributed session management
-
Enhanced Security
- JWT tokens with refresh
- IP whitelisting
- Device fingerprinting
- Anomaly detection
Troubleshooting
Common Issues
-
"Unauthorized" errors
- Check user role and permissions
- Verify session hasn't expired
- Ensure proper permission string
-
Login failures
- Verify credentials
- Check localStorage availability
- Clear browser cache
-
Permission denied on UI
- Confirm hasPermission usage
- Check permission constants
- Verify role assignments
Debug Mode
Enable auth debugging in development:
// In .env.local
AUTH_DEBUG=true
// This will log all permission checks
API Reference
See the Server Actions Reference for detailed information on authorization requirements for each action.