Skip to main content

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 localStorage under the key currentUser
  • 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:

EmailPasswordRoleDescription
[email protected]admin123AdminFull system access (auto-login enabled)
[email protected]doctor123DoctorClinical access, orders, care plans
[email protected]nurse123NursePatient care, limited ordering
[email protected]staff123StaffBasic 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

FeatureAdminDoctorNurseStaffPatient
View PatientsOwn only
Edit PatientsLimitedOwn only
Delete Patients----
Create OrdersLimited--
View OrdersOwn only
Manage Care Plans-View own
AI ToolsLimitedLimited
User Management----
System Config----
Audit Logs----
EHR Integration---
AnalyticsLimited--

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:

  1. OAuth2/OIDC Provider

    • Integration with hospital SSO
    • Multi-factor authentication
    • Token-based authentication
  2. Database-Backed Sessions

    • PostgreSQL session store
    • Redis for session caching
    • Distributed session management
  3. Enhanced Security

    • JWT tokens with refresh
    • IP whitelisting
    • Device fingerprinting
    • Anomaly detection

Troubleshooting

Common Issues

  1. "Unauthorized" errors

    • Check user role and permissions
    • Verify session hasn't expired
    • Ensure proper permission string
  2. Login failures

    • Verify credentials
    • Check localStorage availability
    • Clear browser cache
  3. 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.