Authentication & Authorization System
MedFeed implements a comprehensive security framework with multi-layered authentication and role-based authorization to protect sensitive healthcare data.
Authentication Overview
[Screenshot placeholder: Authentication flow diagram]
Authentication Methods
Primary Authentication:
- Email/Password: Standard credential-based login
- Single Sign-On (SSO): SAML 2.0 and OAuth 2.0 integration
- Multi-Factor Authentication (MFA): SMS, email, and authenticator app support
- Biometric Authentication: Voice recognition and mobile biometrics
Token-Based Authentication:
- JWT Access Tokens: Short-lived (15 minutes) for API access
- Refresh Tokens: Long-lived (30 days) for token renewal
- API Keys: For system-to-system integration
- Session Tokens: For web application sessions
JWT Token Structure
Access Token Payload
[Screenshot placeholder: JWT token structure visualization]
{
// Standard claims
"iss": "medfeed.io", // Issuer
"sub": "user_id_here", // Subject (User ID)
"aud": "medfeed-api", // Audience
"exp": 1640995200, // Expiration time
"iat": 1640994300, // Issued at
"jti": "unique_token_id", // JWT ID
// Custom claims
"email": "doctor@hospital.com",
"name": "Dr. John Smith",
"role": "doctor",
"department": "cardiology",
"permissions": [
"patient:read",
"patient:write",
"notes:create",
"feedback:read"
],
"organization": "hospital_id",
"tenant": "tenant_workspace_id"
}
Refresh Token Structure
{
"iss": "medfeed.io",
"sub": "user_id_here",
"aud": "medfeed-refresh",
"exp": 1643587200, // 30 days from issue
"iat": 1640995200,
"jti": "refresh_token_id",
"type": "refresh",
"device": "mobile_app_ios", // Device identifier
"ip": "192.168.1.100" // IP address when issued
}
Role-Based Access Control (RBAC)
User Roles Hierarchy
[Screenshot placeholder: Role hierarchy diagram]
// Role definitions with inheritance
const roles = {
"super_admin": {
"inherits": [],
"permissions": ["*"], // All permissions
"description": "System administrator with full access"
},
"hospital_admin": {
"inherits": [],
"permissions": [
"user:*", "department:*", "organization:*",
"patient:read", "analytics:read", "reports:*"
],
"description": "Hospital administrator"
},
"doctor": {
"inherits": ["clinician"],
"permissions": [
"patient:*", "notes:*", "feedback:read",
"task:read", "task:create", "analytics:read"
],
"description": "Licensed physician"
},
"nurse": {
"inherits": ["clinician"],
"permissions": [
"patient:read", "patient:update", "notes:read",
"feedback:*", "task:*"
],
"description": "Registered nurse"
},
"clinician": {
"inherits": [],
"permissions": [
"patient:read", "notes:read", "feedback:read"
],
"description": "Base clinical role"
},
"quality_manager": {
"inherits": [],
"permissions": [
"feedback:*", "analytics:*", "reports:*",
"patient:read", "notes:read"
],
"description": "Quality assurance manager"
}
};
Permission System
[Screenshot placeholder: Permission matrix visualization]
Permission Format: resource:action
Resources:
patient- Patient records and informationnotes- Clinical documentationfeedback- Patient feedback datatask- Task managementuser- User managementdepartment- Department configurationanalytics- Analytics and reportingsystem- System administration
Actions:
create- Create new resourcesread- View existing resourcesupdate- Modify existing resourcesdelete- Remove resources*- All actions on resource
Dynamic Permissions
// Context-aware permissions
const contextualPermissions = {
// Department-based access
"patient:read": {
"condition": "user.department === patient.department || user.role === 'doctor'",
"description": "Can read patients in same department or if doctor"
},
// Ownership-based access
"notes:update": {
"condition": "note.authorId === user.id || user.role === 'attending_physician'",
"description": "Can update own notes or if attending physician"
},
// Time-based access
"task:complete": {
"condition": "task.assignedTo === user.id && task.status === 'in_progress'",
"description": "Can complete tasks assigned to user"
}
};
Multi-Factor Authentication (MFA)
MFA Methods
[Screenshot placeholder: MFA setup interface]
SMS Authentication
// SMS MFA flow
{
"method": "sms",
"phoneNumber": "+1234567890",
"code": "123456", // 6-digit code
"expiresAt": "2024-01-01T12:00:00Z",
"attempts": 0, // Failed attempts counter
"maxAttempts": 3
}
Authenticator App (TOTP)
// Time-based One-Time Password
{
"method": "totp",
"secret": "base32_encoded_secret",
"algorithm": "SHA1",
"digits": 6,
"period": 30, // 30-second window
"qrCode": "data:image/png;base64,..."
}
Email Authentication
// Email MFA flow
{
"method": "email",
"emailAddress": "user@hospital.com",
"code": "ABC123", // 6-character alphanumeric
"expiresAt": "2024-01-01T12:05:00Z",
"template": "mfa_verification"
}
Backup Codes
[Screenshot placeholder: Backup codes interface]
// One-time backup codes
{
"userId": "user_id_here",
"codes": [
{
"code": "ABCD-1234-EFGH-5678",
"used": false,
"usedAt": null
},
// ... 9 more codes
],
"generatedAt": "2024-01-01T10:00:00Z"
}
Single Sign-On (SSO) Integration
SAML 2.0 Configuration
[Screenshot placeholder: SAML configuration interface]
<!-- SAML Service Provider Configuration -->
<EntityDescriptor entityID="https://medfeed.hospital.com/saml/metadata">
<SPSSODescriptor>
<AssertionConsumerService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://medfeed.hospital.com/saml/acs"
index="0" />
<AttributeConsumingService index="0">
<ServiceName xml:lang="en">MedFeed</ServiceName>
<RequestedAttribute Name="email" isRequired="true"/>
<RequestedAttribute Name="firstName" isRequired="true"/>
<RequestedAttribute Name="lastName" isRequired="true"/>
<RequestedAttribute Name="department" isRequired="false"/>
<RequestedAttribute Name="role" isRequired="false"/>
</AttributeConsumingService>
</SPSSODescriptor>
</EntityDescriptor>
OAuth 2.0 / OpenID Connect
[Screenshot placeholder: OAuth configuration interface]
// OAuth 2.0 configuration
{
"clientId": "medfeed_hospital_client",
"clientSecret": "secure_client_secret",
"redirectUri": "https://medfeed.hospital.com/oauth/callback",
"scope": "openid profile email",
"responseType": "code",
"grantType": "authorization_code",
// Provider endpoints
"authorizationEndpoint": "https://idp.hospital.com/oauth/authorize",
"tokenEndpoint": "https://idp.hospital.com/oauth/token",
"userInfoEndpoint": "https://idp.hospital.com/oauth/userinfo",
"jwksUri": "https://idp.hospital.com/.well-known/jwks.json"
}
Session Management
Session Storage
[Screenshot placeholder: Session management interface]
// Session data structure
{
"sessionId": "sess_1234567890abcdef",
"userId": "user_id_here",
"createdAt": "2024-01-01T10:00:00Z",
"lastActivity": "2024-01-01T10:30:00Z",
"expiresAt": "2024-01-01T18:00:00Z",
// Device information
"device": {
"type": "desktop", // desktop, mobile, tablet
"browser": "Chrome 120.0",
"os": "Windows 11",
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0..."
},
// Security flags
"mfaVerified": true,
"riskScore": 0.1, // 0-1 risk assessment
"trusted": true, // Trusted device flag
// Session data
"data": {
"preferences": {},
"temporaryData": {}
}
}
Session Security
Security Measures:
- Automatic Expiration: 8-hour default timeout
- Idle Timeout: 30 minutes of inactivity
- Concurrent Session Limits: Maximum 5 active sessions
- Device Fingerprinting: Detect suspicious login patterns
- Geographic Validation: Flag logins from unusual locations
API Authentication
API Key Authentication
[Screenshot placeholder: API key management interface]
// API key structure
{
"keyId": "ak_1234567890abcdef",
"name": "EMR Integration Key",
"hashedKey": "sha256_hash_of_key",
"permissions": [
"patient:read",
"notes:create",
"feedback:read"
],
"rateLimit": {
"requestsPerMinute": 100,
"requestsPerHour": 1000
},
"ipWhitelist": [
"192.168.1.0/24",
"10.0.0.0/8"
],
"createdBy": "user_id_here",
"createdAt": "2024-01-01T10:00:00Z",
"lastUsed": "2024-01-01T11:30:00Z",
"isActive": true
}
Bearer Token Authentication
# API request with Bearer token
GET /api/v1/patients HTTP/1.1
Host: api.medfeed.hospital.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
Security Middleware
Authentication Middleware
[Screenshot placeholder: Middleware flow diagram]
// Express.js authentication middleware
const authMiddleware = async (req, res, next) => {
try {
// Extract token from header
const token = extractTokenFromHeader(req.headers.authorization);
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
// Verify and decode token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Check token blacklist
const isBlacklisted = await checkTokenBlacklist(decoded.jti);
if (isBlacklisted) {
return res.status(401).json({ error: 'Token revoked' });
}
// Load user and permissions
const user = await User.findById(decoded.sub);
if (!user || !user.isActive) {
return res.status(401).json({ error: 'User not found or inactive' });
}
// Attach user to request
req.user = user;
req.permissions = decoded.permissions;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
};
Authorization Middleware
// Permission-based authorization
const requirePermission = (permission) => {
return (req, res, next) => {
if (!req.permissions.includes(permission) && !req.permissions.includes('*')) {
return res.status(403).json({
error: 'Insufficient permissions',
required: permission
});
}
next();
};
};
// Usage example
app.get('/api/patients',
authMiddleware,
requirePermission('patient:read'),
getPatientsController
);
Password Security
Password Requirements
[Screenshot placeholder: Password policy interface]
Policy Rules:
- Minimum Length: 12 characters
- Character Requirements:
- At least 1 uppercase letter
- At least 1 lowercase letter
- At least 1 number
- At least 1 special character
- Dictionary Check: Prevent common passwords
- Personal Information: Cannot contain name or email
- History: Cannot reuse last 12 passwords
- Expiration: 90 days (configurable)
Password Hashing
// Password hashing with bcrypt
const bcrypt = require('bcrypt');
// Hash password during registration
const hashPassword = async (plainPassword) => {
const saltRounds = 12;
return await bcrypt.hash(plainPassword, saltRounds);
};
// Verify password during login
const verifyPassword = async (plainPassword, hashedPassword) => {
return await bcrypt.compare(plainPassword, hashedPassword);
};
Audit Logging
Security Event Logging
[Screenshot placeholder: Audit log interface]
// Security audit log entry
{
"eventId": "evt_1234567890",
"timestamp": "2024-01-01T10:00:00Z",
"eventType": "authentication",
"action": "login_success",
"userId": "user_id_here",
"sessionId": "sess_1234567890",
// Request context
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"location": {
"country": "US",
"region": "CA",
"city": "San Francisco"
},
// Security context
"riskScore": 0.1,
"mfaUsed": true,
"deviceTrusted": true,
// Additional metadata
"metadata": {
"loginMethod": "password",
"previousLogin": "2024-01-01T08:00:00Z"
}
}
Monitored Events
Authentication Events:
- Login attempts (success/failure)
- Password changes
- MFA setup/usage
- Account lockouts
- Token generation/refresh
Authorization Events:
- Permission grants/denials
- Role changes
- Privilege escalation attempts
- Resource access attempts
Security Events:
- Suspicious login patterns
- Multiple failed attempts
- Unusual geographic access
- Token manipulation attempts
Security Best Practices
Implementation Guidelines
[Screenshot placeholder: Security checklist interface]
Token Security:
- Use short-lived access tokens (15 minutes)
- Implement secure token storage
- Rotate refresh tokens regularly
- Blacklist compromised tokens
Session Security:
- Implement proper session timeout
- Use secure session cookies
- Validate session integrity
- Monitor concurrent sessions
API Security:
- Rate limiting per user/IP
- Input validation and sanitization
- HTTPS enforcement
- CORS configuration
Monitoring and Alerting:
- Real-time security monitoring
- Automated threat detection
- Incident response procedures
- Regular security audits
For API integration security, see the API Reference. For deployment security, refer to the Installation Guide.