47 KiB
SSO Implementation for RE Workflow Management System
1. Landing Page
The RE Workflow Management System serves as a unified landing page and application portal for workflow request management. Users access the application through a web-based interface that provides:
- Unified Login Experience: Single sign-on (SSO) integration with Okta Identity Provider
- Application Dashboard: Centralized view of workflow requests, approvals, and activities
- Role-Based Access: Personalized interface based on user roles (USER, MANAGEMENT, ADMIN)
- Request Management: Create, view, and manage workflow requests with multi-level approvals
Landing Page Features
- Dashboard: Overview of open requests, pending approvals, and system metrics
- Request Creation: Guided wizards for creating custom requests and claim management workflows
- Request Tracking: Real-time status updates and activity tracking
- Document Management: Upload, preview, and download documents with GCS integration
- Work Notes: Collaborative communication within request context
- Notifications: Real-time alerts for approvals, assignments, and system events
2. System Architecture
2a. Architecture for Frontend (RE Workflow Application)
Technology Stack:
- Framework: React 18 with TypeScript
- Build Tool: Vite
- Routing: React Router v6
- State Management: Redux Toolkit (authSlice, storeSlice) + React Context (AuthContext)
- UI Components: shadcn/ui, Radix UI, Tailwind CSS
- HTTP Client: Axios with interceptors
- Authentication: Okta Sign-In Widget (production) / Token Exchange (development)
Frontend Architecture Components:
┌─────────────────────────────────────────────────────────────┐
│ User's Web Browser │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ React Application (Vite + React Router) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │ │
│ │ │ AuthContext │ │ Redux Store │ │ Components │ │ │
│ │ │ (SSO Flow) │ │ (State Mgmt) │ │ (UI Layer) │ │ │
│ │ └──────────────┘ └──────────────┘ └─────────────┘ │ │
│ │ │ │ │ │ │
│ │ └──────────────────┼──────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────▼────────┐ │ │
│ │ │ Axios Client │ │ │
│ │ │ (withCredentials) │ │
│ │ └───────┬────────┘ │ │
│ └────────────────────────────┼──────────────────────────┘ │
└────────────────────────────────┼──────────────────────────────┘
│
┌────────────▼────────────┐
│ Backend API Server │
│ (Express + Node.js) │
└────────────────────────┘
Mermaid Diagram - Frontend Architecture:
graph TB
Browser[User's Web Browser]
ReactApp[React Application<br/>Vite + React Router]
AuthContext[AuthContext<br/>SSO Flow]
ReduxStore[Redux Store<br/>State Management]
Components[Components<br/>UI Layer]
AxiosClient[Axios Client<br/>withCredentials]
BackendAPI[Backend API Server<br/>Express + Node.js]
Browser --> ReactApp
ReactApp --> AuthContext
ReactApp --> ReduxStore
ReactApp --> Components
AuthContext --> AxiosClient
ReduxStore --> AxiosClient
Components --> AxiosClient
AxiosClient --> BackendAPI
Key Frontend Files:
src/contexts/AuthContext.tsx: Authentication state management and SSO flowsrc/services/authApi.ts: API client with token refresh interceptorssrc/utils/tokenManager.ts: Token storage and management (localStorage in dev, httpOnly cookies in prod)src/pages/Auth/AuthCallback.tsx: Handles OAuth callback from Oktasrc/App.tsx: Main routing and application structure
Authentication Flow (Frontend):
-
Production Mode (SSO via Okta):
- User navigates to application
- Okta Sign-In Widget initiates authentication
- User authenticates with Okta (MFA if enabled)
- Okta redirects to
/login/callbackwith authorization code - Frontend exchanges code for tokens via
/api/v1/auth/token-exchange - Backend sets httpOnly cookies (
accessToken,refreshToken) - User is redirected to dashboard
-
Development Mode (Localhost):
- User navigates to application
- Okta Sign-In Widget initiates authentication
- After Okta authentication, frontend receives authorization code
- Frontend calls
/api/v1/auth/token-exchangewith code - Backend returns tokens in response body (for cross-port development)
- Tokens stored in localStorage for development convenience
- User is redirected to dashboard
Session Management:
- Production: Tokens stored in httpOnly cookies (secure, not accessible via JavaScript)
- Development: Tokens stored in localStorage (for debugging and cross-port setup)
- Token Refresh: Automatic refresh via Axios interceptor when access token expires
- Logout: Clears cookies and redirects to Okta logout endpoint
2b. Architecture for Backend (API Server)
Technology Stack:
- Runtime: Node.js 22 LTS
- Language: TypeScript 5.7
- Framework: Express.js 4.21
- Database: PostgreSQL 16
- ORM: Sequelize 6.37
- Authentication: JWT (JSON Web Tokens)
- Session: HttpOnly cookies (production) / JWT tokens (development)
Backend Architecture Components:
┌─────────────────────────────────────────────────────────────┐
│ Express.js Application Server │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Middleware Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ CORS │ │ Helmet │ │ Cookie │ │ Auth │ │ │
│ │ │ │ │ (Security)│ │ Parser │ │Middleware│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Route Handlers │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Auth │ │ Workflow │ │ Document │ │ User │ │ │
│ │ │Controller│ │Controller│ │Controller│ │Controller│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Service Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Auth │ │ Workflow │ │ Document │ │ User │ │ │
│ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Data Access Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ User │ │Workflow │ │ Document │ │ Activity │ │ │
│ │ │ Model │ │ Model │ │ Model │ │ Model │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ Okta API │ │ GCS Bucket │
│ Database │ │ (IdP) │ │ (Storage) │
└──────────────┘ └──────────────┘ └──────────────┘
Mermaid Diagram - Backend Architecture:
graph TB
ExpressApp[Express.js Application Server]
subgraph Middleware["Middleware Layer"]
CORS[CORS]
Helmet[Helmet Security]
CookieParser[Cookie Parser]
AuthMiddleware[Auth Middleware]
end
subgraph Controllers["Route Handlers"]
AuthController[Auth Controller]
WorkflowController[Workflow Controller]
DocumentController[Document Controller]
UserController[User Controller]
end
subgraph Services["Service Layer"]
AuthService[Auth Service]
WorkflowService[Workflow Service]
DocumentService[Document Service]
UserService[User Service]
end
subgraph Models["Data Access Layer"]
UserModel[User Model]
WorkflowModel[Workflow Model]
DocumentModel[Document Model]
ActivityModel[Activity Model]
end
PostgreSQL[(PostgreSQL Database)]
OktaAPI[Okta API IdP]
GCS[GCS Bucket Storage]
ExpressApp --> Middleware
Middleware --> Controllers
Controllers --> Services
Services --> Models
Models --> PostgreSQL
AuthService --> OktaAPI
DocumentService --> GCS
Key Backend Files:
src/app.ts: Express application setup, middleware configurationsrc/routes/auth.routes.ts: Authentication endpointssrc/controllers/auth.controller.ts: Authentication request handlerssrc/services/auth.service.ts: Authentication business logicsrc/middlewares/auth.middleware.ts: JWT token validation middlewaresrc/config/sso.ts: SSO configuration (Okta, JWT secrets)
Authentication Endpoints:
-
POST
/api/v1/auth/token-exchange(No auth required)- Exchanges Okta authorization code for JWT tokens
- Creates/updates user in database
- Sets httpOnly cookies (production) or returns tokens (development)
-
POST
/api/v1/auth/sso-callback(No auth required)- Legacy endpoint for direct SSO callback
- Accepts SSO user data, creates/updates user
- Returns JWT tokens
-
POST
/api/v1/auth/login(No auth required)- Username/password authentication via Okta Resource Owner Password flow
- For API clients (Postman, mobile apps)
- Returns JWT tokens
-
POST
/api/v1/auth/refresh(No auth required)- Refreshes access token using refresh token
- Accepts refresh token from request body or httpOnly cookie
- Returns new access token
-
GET
/api/v1/auth/me(Auth required)- Returns current authenticated user profile
-
POST
/api/v1/auth/logout(Optional auth)- Clears authentication cookies
- Logs user activity
Cookie Configuration:
- Name:
accessToken,refreshToken - HttpOnly:
true(prevents JavaScript access) - Secure:
truein production (HTTPS only) - SameSite:
lax(development) /none(production for cross-domain) - MaxAge: 24 hours (accessToken), 7 days (refreshToken)
- Path:
/
3. Deployment Architecture
Deployment Environment
Current Deployment:
- Environment: Development/Staging
- Region: To be configured based on organizational requirements
User Domain
- Domain: To be configured (e.g.,
rebridge.co.inor organization-specific domain) - Purpose: Unified domain for SSO and application access
- Integration: Federated with Okta Identity Provider
Deployment Components
Frontend Deployment:
- Build: Vite production build (
npm run build) - Static Hosting: Served via Express static middleware or CDN
- Environment Variables:
VITE_API_BASE_URL: Backend API URLVITE_OKTA_DOMAIN: Okta domain for authenticationVITE_OKTA_CLIENT_ID: Okta client ID
Backend Deployment:
- Runtime: Node.js 22 LTS
- Process Manager: PM2 (recommended for production)
- Reverse Proxy: Nginx (recommended for SSL termination and load balancing)
- Database: PostgreSQL 16 (managed service or self-hosted)
- File Storage: Google Cloud Storage (GCS) for document storage
- Environment Variables: See
.env.examplefor complete list
Key Environment Variables:
# Server Configuration
NODE_ENV=production
PORT=5000
FRONTEND_URL=https://rebridge.co.in
# Database
DB_HOST=postgresql-host
DB_PORT=5432
DB_NAME=re_workflow_db
DB_USER=postgres
DB_PASSWORD=secure_password
# JWT Configuration
JWT_SECRET=your-secret-key
JWT_EXPIRY=24h
REFRESH_TOKEN_EXPIRY=7d
# Okta Configuration
OKTA_DOMAIN=https://dev-830839.oktapreview.com
OKTA_CLIENT_ID=your-client-id
OKTA_CLIENT_SECRET=your-client-secret
# GCS Configuration
GCP_PROJECT_ID=re-platform-workflow-dealer
GCP_BUCKET_NAME=re-workflow-documents
GCP_KEY_FILE=./config/gcp-key.json
GCP_BUCKET_REGION=asia-south1
GCP_BUCKET_PUBLIC=true
4. Identity Provider (IdP) - Okta
IdP Configuration
Identity Provider: Okta
- Domain: Configurable via
OKTA_DOMAINenvironment variable - Default:
https://dev-830839.oktapreview.com - Protocol: OAuth 2.0 / OpenID Connect (OIDC)
- Grant Types: Authorization Code, Resource Owner Password Credentials
IdP Features
Authentication:
- Username/password authentication
- Multi-Factor Authentication (MFA) support
- Conditional Access Policies
- Session management
User Management:
- User directory management
- Group/role mappings
- User provisioning and deprovisioning
- Profile synchronization
Integration:
- OAuth 2.0 Authorization Code flow (web applications)
- Resource Owner Password Credentials flow (API clients)
- Token exchange and validation
- User info endpoint integration
IdP Integration Flow
-
User Authentication:
- User initiates login from frontend
- Frontend redirects to Okta Sign-In Widget
- User enters credentials (and MFA if enabled)
- Okta validates credentials and issues authorization code
-
Token Exchange:
- Frontend receives authorization code
- Frontend calls backend
/api/v1/auth/token-exchangewith code - Backend exchanges code for access token with Okta
- Backend fetches user info from Okta userinfo endpoint
- Backend creates/updates user in local database
- Backend generates JWT tokens (access + refresh)
- Backend sets httpOnly cookies (production) or returns tokens (development)
-
Token Validation:
- Backend validates JWT tokens on each API request
- Middleware (
authenticateToken) verifies token signature and expiry - User record is fetched from database to ensure active status
- User info is attached to request object for authorization
5. User Authentication Flow for RE Workflow System
5.1 Web Application Flow (Production)
Sequence:
- User navigates to RE Workflow application (e.g.,
https://rebridge.co.in) - Authentication: Frontend checks for existing session (httpOnly cookie)
- If no valid session, redirects to Okta Sign-In Widget
- User enters credentials (and MFA if enabled) on Okta login page
- Token Issuance: Upon successful authentication, Okta issues authorization code
- Token Exchange: Frontend exchanges authorization code for tokens via backend
- User Creation/Update: Backend creates or updates user in local database based on Okta user info
- JWT Generation: Backend generates JWT access and refresh tokens
- Cookie Setting: Backend sets httpOnly cookies (
accessToken,refreshToken) - Token Validation: On subsequent requests, backend validates JWT token from cookie
- Access Control: Backend applies role-based access controls (USER, MANAGEMENT, ADMIN)
Mermaid Sequence Diagram - Web Application Authentication Flow:
sequenceDiagram
participant User
participant Browser
participant ReactApp as React Application
participant Okta as Okta IdP
participant Backend as Backend API
participant DB as PostgreSQL
User->>Browser: Navigate to application
Browser->>ReactApp: Load application
ReactApp->>ReactApp: Check for httpOnly cookie
alt No valid session
ReactApp->>Okta: Redirect to Sign-In Widget
User->>Okta: Enter credentials + MFA
Okta->>Okta: Validate credentials
Okta->>ReactApp: Redirect with authorization code
ReactApp->>Backend: POST /api/v1/auth/token-exchange (code)
Backend->>Okta: Exchange code for tokens
Okta->>Backend: Return access token + user info
Backend->>DB: Create/Update user
DB->>Backend: User record
Backend->>Backend: Generate JWT tokens
Backend->>ReactApp: Set httpOnly cookies (accessToken, refreshToken)
ReactApp->>Browser: Redirect to dashboard
else Valid session exists
ReactApp->>Browser: Show dashboard
end
User->>ReactApp: Make API request
ReactApp->>Backend: API request (with cookie)
Backend->>Backend: Validate JWT token
Backend->>DB: Fetch user (verify active)
DB->>Backend: User data
Backend->>Backend: Apply RBAC
Backend->>ReactApp: Return data
ReactApp->>User: Display data
5.2 API Client Flow (Development/Postman)
Sequence:
- Client calls
POST /api/v1/auth/loginwith username and password - Okta Authentication: Backend authenticates with Okta using Resource Owner Password flow
- Token Retrieval: Backend receives access token and user info from Okta
- User Creation/Update: Backend creates or updates user in local database
- JWT Generation: Backend generates JWT access and refresh tokens
- Token Return: Backend returns tokens in response body (for API clients)
5.3 Token Refresh Flow
Sequence:
- Client makes API request with access token
- Token Expiry: If access token is expired, backend returns 401 Unauthorized
- Automatic Refresh: Frontend Axios interceptor catches 401 and calls
/api/v1/auth/refresh - Refresh Token Validation: Backend validates refresh token (from cookie or request body)
- New Token Generation: Backend generates new access token
- Cookie Update: Backend sets new access token in httpOnly cookie (production)
- Request Retry: Frontend retries original request with new token
Mermaid Sequence Diagram - Token Refresh Flow:
sequenceDiagram
participant User
participant ReactApp as React Application
participant AxiosInterceptor as Axios Interceptor
participant Backend as Backend API
participant DB as PostgreSQL
User->>ReactApp: Trigger API request
ReactApp->>Backend: API request (with accessToken cookie)
Backend->>Backend: Validate JWT token
alt Token expired
Backend->>ReactApp: 401 Unauthorized
ReactApp->>AxiosInterceptor: Catch 401 error
AxiosInterceptor->>Backend: POST /api/v1/auth/refresh (refreshToken)
Backend->>Backend: Validate refresh token
Backend->>DB: Fetch user (verify active)
DB->>Backend: User data
Backend->>Backend: Generate new access token
Backend->>ReactApp: Set new accessToken cookie
AxiosInterceptor->>Backend: Retry original request (with new token)
Backend->>Backend: Validate new JWT token
Backend->>DB: Fetch data
DB->>Backend: Return data
Backend->>ReactApp: 200 OK (data)
ReactApp->>User: Display data
else Token valid
Backend->>DB: Fetch data
DB->>Backend: Return data
Backend->>ReactApp: 200 OK (data)
ReactApp->>User: Display data
end
5.4 Logout Flow
Sequence:
- User clicks logout button
- Logout Request: Frontend calls
POST /api/v1/auth/logout - Cookie Clearing: Backend clears httpOnly cookies (
accessToken,refreshToken) - Okta Logout: Frontend redirects to Okta logout endpoint (if ID token available)
- Session Termination: User session is terminated on both application and IdP
Mermaid Sequence Diagram - Logout Flow:
sequenceDiagram
participant User
participant ReactApp as React Application
participant Backend as Backend API
participant Okta as Okta IdP
participant Browser as Browser Storage
User->>ReactApp: Click logout button
ReactApp->>Backend: POST /api/v1/auth/logout
Backend->>Backend: Clear httpOnly cookies (accessToken, refreshToken)
Backend->>Backend: Log logout activity
Backend->>ReactApp: 200 OK (logout successful)
ReactApp->>Browser: Clear localStorage (if any)
ReactApp->>Okta: Redirect to Okta logout endpoint (with ID token)
Okta->>Okta: Terminate Okta session
Okta->>ReactApp: Redirect to application
ReactApp->>User: Show login page
6. RE Workflow System Flow Diagram
6.1 Executive Summary
This document formalizes the technical architecture for the RE Workflow Management System, covering runtime architecture, routing, authentication/SSO, session & data flow, state management, integrations (Okta, GCS), configuration, security posture, error handling, and extensibility.
High-Level Architecture (Simple View)
User's Web Browser → RE Workflow Application (React) → Backend API (Express) → PostgreSQL Database
↓
Okta Identity Provider (IdP)
↓
Google Cloud Storage (GCS)
Mermaid Diagram - High-Level Architecture:
graph LR
Browser[User's Web Browser]
ReactApp[RE Workflow Application<br/>React]
BackendAPI[Backend API<br/>Express]
PostgreSQL[(PostgreSQL Database)]
Okta[Okta Identity Provider<br/>IdP]
GCS[Google Cloud Storage<br/>GCS]
Browser -->|HTTPS| ReactApp
ReactApp -->|API Calls| BackendAPI
BackendAPI -->|Data Storage| PostgreSQL
BackendAPI -->|Authentication| Okta
BackendAPI -->|File Storage| GCS
ReactApp -->|SSO Login| Okta
6.2 Technology Stack & Conventions
Frontend:
- Framework: React 18 with TypeScript
- Build Tool: Vite
- Routing: React Router v6
- Styling: Tailwind CSS; UI primitives via shadcn/ui & Radix
- State: Redux Toolkit (authSlice, storeSlice) + React Context (AuthContext)
- Data Fetching: Axios with interceptors (token refresh, error handling)
- Security: HttpOnly cookies (production) / localStorage (development)
Backend:
- Runtime: Node.js 22 LTS
- Language: TypeScript 5.7
- Framework: Express.js 4.21
- Database: PostgreSQL 16
- ORM: Sequelize 6.37
- Authentication: JWT (JSON Web Tokens)
- Validation: Zod schemas
- Logging: Winston logger
- Security: Helmet.js, CORS middleware, cookie-parser
6.3 Routing & Layout
Frontend Routes:
/or/dashboard- Dashboard (authenticated users)/login/callback- OAuth callback handler/request/:requestId- Request detail view/new-request- Create new request/my-requests- User's requests/open-requests- Open requests (management/admin)/closed-requests- Closed requests/admin- Admin control panel (admin only)/profile- User profile/settings- Application settings
Backend Routes:
/api/v1/auth/*- Authentication endpoints/api/v1/workflows/*- Workflow management/api/v1/documents/*- Document management/api/v1/users/*- User management/api/v1/activities/*- Activity logging/health- Health check endpoint
Route Protection:
- Frontend:
AuthContextchecks authentication status, redirects to login if not authenticated - Backend:
authenticateTokenmiddleware validates JWT token on protected routes - Role-Based:
requireRolemiddleware enforces role-based access control
6.4 Authentication (SSO) & Session
Login Flow:
- User navigates to application
- Frontend checks for existing session (httpOnly cookie in production, localStorage in development)
- If no session, redirects to Okta Sign-In Widget
- User authenticates with Okta (credentials + MFA if enabled)
- Okta redirects to
/login/callbackwith authorization code - Frontend calls
/api/v1/auth/token-exchangewith code - Backend exchanges code for tokens with Okta
- Backend creates/updates user in database
- Backend generates JWT tokens and sets httpOnly cookies (production) or returns tokens (development)
- User is redirected to dashboard
Cookie Configuration:
- Name:
accessToken,refreshToken - HttpOnly:
true(prevents XSS attacks) - Secure:
truein production (HTTPS only) - SameSite:
lax(development) /none(production for cross-domain) - MaxAge: 24 hours (accessToken), 7 days (refreshToken)
- Path:
/
Cookie Payload Schema:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
JWT Token Payload:
{
"userId": "uuid",
"employeeId": "EMP001",
"email": "user@royalenfield.com",
"role": "USER" | "MANAGEMENT" | "ADMIN",
"iat": 1234567890,
"exp": 1234654290
}
Cookie Consumers:
- Backend Middleware:
authenticateTokenreads token from cookie or Authorization header - Frontend: Axios automatically sends cookies with
withCredentials: true - Token Refresh: Automatic refresh via Axios interceptor when access token expires
Behavior: After login, the cookie is validated on each request, driving personalized UI and API authorization. Token refresh happens automatically in the background when access token expires.
6.5 Session & Application Data Flow
Session Endpoints:
- GET
/api/v1/auth/me: Returns current user profile (validates cookie, fetches user from database) - POST
/api/v1/auth/refresh: Refreshes access token using refresh token (from cookie or request body)
Data Flow:
- Request: Frontend makes API request with httpOnly cookie (production) or Authorization header (development)
- Validation: Backend middleware validates JWT token
- User Lookup: Backend fetches user from database to ensure active status
- Authorization: Backend applies role-based access control
- Response: Backend returns data with appropriate status code
Error Handling:
- 401 Unauthorized: Token missing, invalid, or expired → Frontend triggers token refresh or redirects to login
- 403 Forbidden: User lacks required role → Frontend shows access denied message
- 500 Internal Server Error: Backend logs error, returns generic error message to frontend
6.6 Security Posture
Cookies:
- HttpOnly:
true(prevents JavaScript access, mitigates XSS) - Secure:
truein production (HTTPS only, prevents man-in-the-middle) - SameSite:
lax(development) /none(production for cross-domain) - MaxAge: 24 hours (accessToken), 7 days (refreshToken)
- Path:
/(available to all routes)
Headers (Helmet.js):
- Content-Security-Policy (CSP): Restricts resource loading (scripts, styles, images, connections)
- X-Frame-Options: Prevents clickjacking attacks
- X-Content-Type-Options: Prevents MIME type sniffing
- Referrer-Policy: Controls referrer information
- Strict-Transport-Security (HSTS): Enforces HTTPS in production
TLS/SSL:
- Production: HTTPS enforced via reverse proxy (Nginx) or load balancer
- Development: HTTP allowed for local development
- Certificate: Managed via Let's Encrypt or enterprise CA
Secrets Management:
- JWT Secret: Stored in environment variable (
JWT_SECRET) - Okta Credentials: Stored in environment variables (
OKTA_CLIENT_ID,OKTA_CLIENT_SECRET) - Database Credentials: Stored in environment variables (never committed to repository)
- Recommendation: Use secret manager (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault) in production
Input Validation:
- Zod Schemas: All request bodies validated using Zod schemas
- SQL Injection Prevention: Sequelize ORM uses parameterized queries
- XSS Prevention: Input sanitization and output encoding
Rate Limiting:
- Recommendation: Implement rate limiting middleware (express-rate-limit) for authentication endpoints
- Current: Not implemented (to be added)
7. Key Components
7.1 User Directory
Current Implementation:
- User accounts stored in PostgreSQL database (
userstable) - Roles:
USER,MANAGEMENT,ADMIN - User data synced from Okta on each login
- Just-in-Time (JIT) provisioning: Users created automatically on first SSO login
7.2 User Management
Okta Integration:
- Primary identity provider for authentication
- User directory managed in Okta
- User attributes synced to local database on login
Local Database:
- User records stored in PostgreSQL
- Fields:
userId,email,employeeId,firstName,lastName,displayName,department,designation,role,isActive,oktaSub - User creation/update happens automatically on SSO callback
User Service:
src/services/user.service.ts: User CRUD operationssrc/services/auth.service.ts: User creation/update during SSO callback
7.3 Login and Dashboard
RE Workflow Portal:
- Unified login experience via Okta Sign-In Widget
- Dashboard provides overview of:
- Open requests (pending user action)
- My requests (user-initiated requests)
- Pending approvals (requests awaiting user approval)
- System metrics (TAT, completion rates)
Authentication Flow:
- Frontend:
src/contexts/AuthContext.tsxmanages authentication state - Backend:
src/controllers/auth.controller.tshandles authentication requests - Okta: Identity provider for user authentication
7.4 Database Configuration
PostgreSQL Database:
- Database Name:
re_workflow_db(configurable) - Tables:
users,workflow_requests,documents,work_note_attachments,activities, etc. - ORM: Sequelize for database operations
- Migrations: Database schema managed via Sequelize migrations
Database Models:
src/models/User.ts: User model with authentication fieldssrc/models/WorkflowRequest.ts: Workflow request modelsrc/models/Document.ts: Document model with GCS integrationsrc/models/WorkNoteAttachment.ts: Work note attachment model
7.5 File Storage
Google Cloud Storage (GCS):
- Bucket:
re-workflow-documents(configurable) - Region:
asia-south1(configurable) - Structure:
requests/{requestNumber}/{fileType}/{fileName}fileType:documentsorattachments
- Access: Public URLs (if
GCP_BUCKET_PUBLIC=true) or signed URLs - Service:
src/services/gcsStorage.service.ts
Local Storage (Fallback):
- Used when GCS is not configured or upload fails
- Files stored in
uploads/directory - Served via Express static middleware
7.6 API Access
OAuth2 Flows:
- Authorization Code Flow: Used by web application (frontend)
- Resource Owner Password Credentials Flow: Used by API clients (Postman, mobile apps)
Service-to-Service Authentication:
- Current: Not implemented (to be added for integrations)
- Recommendation: OAuth2 Client Credentials flow for service-to-service authentication
8. Security Considerations
8.1 Multi-Factor Authentication (MFA)
IdP Configuration:
- MFA enforced via Okta conditional access policies
- Users required to complete MFA challenge during login
- MFA methods: SMS, TOTP, Push notification (configurable in Okta)
Application Level:
- MFA handled entirely by Okta
- Application receives authenticated user info after MFA completion
- No MFA state management required in application
8.2 Conditional Access
IdP Policies:
- Location-based restrictions (e.g., block access from certain countries)
- Device compliance requirements
- Time-based access restrictions
- IP whitelist/blacklist
Application Level:
- Role-based access control (RBAC) enforced via middleware
- Routes protected by
authenticateTokenandrequireRolemiddleware - Frontend route guards prevent unauthorized access
8.3 Role Assignments and Permissions
Roles:
- USER: Standard user, can create requests and participate in workflows
- MANAGEMENT: Management user, can view all requests and perform management actions
- ADMIN: Administrator, full system access including user management
Permission Enforcement:
- Backend:
requireRolemiddleware enforces role-based access - Frontend:
hasManagementAccesshelper function checks user role - Database: Role stored in
users.rolecolumn
Regular Review:
- Recommendation: Implement periodic role review process
- Audit: All role changes logged in
activitiestable
8.4 Audit Logging
Application Logging:
- Winston Logger: Structured logging for all application events
- Activity Logging: All user actions logged in
activitiestable - Authentication Events: Login, logout, token refresh logged with user info and IP address
IdP Logging:
- Okta System Log: All authentication events logged in Okta
- Azure Entra Audit Logs: (Future) User access and role changes logged
Log Retention:
- Recommendation: Retain logs for 90 days (configurable)
- Compliance: Logs retained per organizational compliance requirements
8.5 Token Security
JWT Token Security:
- Secret: Strong secret key stored in environment variable
- Expiry: Short-lived access tokens (24 hours), longer-lived refresh tokens (7 days)
- Signature: HMAC SHA-256 algorithm
- Validation: Token signature and expiry validated on each request
Cookie Security:
- HttpOnly: Prevents JavaScript access (mitigates XSS)
- Secure: HTTPS only in production (mitigates man-in-the-middle)
- SameSite: CSRF protection
Token Refresh:
- Automatic: Frontend automatically refreshes expired tokens
- Secure: Refresh token validated before issuing new access token
- Rotation: (Future) Implement refresh token rotation for enhanced security
9. Provisioning & Lifecycle
9.1 User Provisioning
Current Implementation:
- Just-in-Time (JIT) Provisioning: Users created automatically on first SSO login
- User Data Source: Okta user directory
- Sync Frequency: Real-time (on each login)
User Creation Flow:
- User authenticates with Okta
- Backend receives user info from Okta
- Backend checks if user exists in database (by email)
- If user exists, updates user record with latest info from Okta
- If user doesn't exist, creates new user record with default role
USER - User is granted access to application
Mermaid Sequence Diagram - User Provisioning Flow:
sequenceDiagram
participant User
participant Okta as Okta IdP
participant Backend as Backend API
participant AuthService as Auth Service
participant DB as PostgreSQL Database
User->>Okta: Authenticate (credentials + MFA)
Okta->>Okta: Validate credentials
Okta->>Backend: Return authorization code
Backend->>Okta: Exchange code for tokens
Okta->>Backend: Return access token + user info
Backend->>AuthService: handleSSOCallback(userData)
AuthService->>DB: Check if user exists (by email)
alt User exists
DB->>AuthService: User found
AuthService->>DB: Update user record (displayName, department, etc.)
DB->>AuthService: User updated
else User doesn't exist
DB->>AuthService: User not found
AuthService->>DB: Create new user (role: USER, isActive: true)
DB->>AuthService: User created
end
AuthService->>AuthService: Generate JWT tokens
AuthService->>Backend: Return tokens + user data
Backend->>User: Set cookies + redirect to dashboard
User Update Flow:
- User attributes updated on each login
- Fields updated:
displayName,department,designation,phone,lastLogin oktaSubupdated if changed in Okta
9.2 SCIM Provisioning (Future)
Recommendation: Implement SCIM 2.0 for automated user provisioning
Benefits:
- Automated user creation from HRMS
- Automatic role assignments based on HRMS data
- User deprovisioning when user is removed from HRMS
- Group/role synchronization
Implementation:
- SCIM Endpoint:
/api/v1/scim/v2/Users - SCIM Provider: Okta or Azure Entra
- SCIM Client: HRMS system
9.3 User Deprovisioning
Current Implementation:
- Manual Deactivation: Admin can deactivate user via admin panel
- Field:
users.isActiveset tofalse - Effect: User cannot authenticate (middleware checks
isActivestatus)
Future Implementation:
- Automatic Deprovisioning: User deactivated when removed from Okta
- SCIM Integration: User deprovisioned via SCIM DELETE request
- Data Retention: User data retained for audit purposes (soft delete)
9.4 Group/Role Assignments
Current Implementation:
- Default Role: New users assigned
USERrole - Manual Assignment: Admin can change user role via admin panel
- Role Storage: Role stored in
users.rolecolumn
Future Implementation:
- Okta Group Mapping: Map Okta groups to application roles
- Automatic Assignment: Assign roles based on Okta group membership
- HRMS Integration: Assign roles based on HRMS job title/department
9.5 Lifecycle Management
User Onboarding:
- User added to Okta directory (by IT admin)
- User receives welcome email with application URL
- User logs in via Okta SSO
- User account created automatically in application
- User assigned default role
USER - User can access application
User Offboarding:
- User removed from Okta directory (by IT admin)
- User cannot authenticate (Okta rejects login)
- User account remains in database (for audit)
- Admin can manually deactivate user account
- User data retained per retention policy
Role Changes:
- Admin updates user role in admin panel
- Role change logged in
activitiestable - User permissions updated immediately (no logout required)
- Role change synced to database
10. SSO Implementation Activity Tracker
This section tracks SSO implementation activities specific to the RE Workflow Management System.
| Sr | Activity | Owner | Status | Remarks |
|---|---|---|---|---|
| 1 | Okta Application Configuration | - | Completed | OAuth 2.0 / OIDC application configured |
| 2 | Backend SSO Integration | - | Completed | Token exchange endpoint implemented |
| 3 | Frontend SSO Integration | - | Completed | Okta Sign-In Widget integrated |
| 4 | JWT Token Implementation | - | Completed | Access and refresh tokens configured |
| 5 | HttpOnly Cookie Implementation | - | Completed | Secure cookie-based authentication |
| 6 | User Provisioning (JIT) | - | Completed | Automatic user creation on first login |
| 7 | Token Refresh Mechanism | - | Completed | Automatic token refresh implemented |
| 8 | Role-Based Access Control | - | Completed | USER, MANAGEMENT, ADMIN roles implemented |
| 9 | GCS Integration for Documents | - | Completed | Google Cloud Storage configured |
| 10 | Audit Logging | - | Completed | Authentication events logged |
| 11 | Domain Configuration | - | Pending | Configure production domain |
| 12 | Production Deployment | - | Pending | Deploy to production environment |
| 13 | MFA Enforcement | - | Pending | Configure MFA policies in Okta |
| 14 | SCIM Provisioning | - | Future | Automated user provisioning from HRMS |
| 15 | Session Management Dashboard | - | Future | Active session tracking and management |
11. Configuration Reference
11.1 Environment Variables
Backend (.env):
# Server
NODE_ENV=production
PORT=5000
FRONTEND_URL=https://rebridge.co.in
# Database
DB_HOST=postgresql-host
DB_PORT=5432
DB_NAME=re_workflow_db
DB_USER=postgres
DB_PASSWORD=secure_password
# JWT
JWT_SECRET=your-secret-key
JWT_EXPIRY=24h
REFRESH_TOKEN_EXPIRY=7d
# Okta
OKTA_DOMAIN=https://dev-830839.oktapreview.com
OKTA_CLIENT_ID=your-client-id
OKTA_CLIENT_SECRET=your-client-secret
# GCS
GCP_PROJECT_ID=re-platform-workflow-dealer
GCP_BUCKET_NAME=re-workflow-documents
GCP_KEY_FILE=./config/gcp-key.json
GCP_BUCKET_REGION=asia-south1
GCP_BUCKET_PUBLIC=true
Frontend (.env):
VITE_API_BASE_URL=https://api.rebridge.co.in/api/v1
VITE_OKTA_DOMAIN=https://dev-830839.oktapreview.com
VITE_OKTA_CLIENT_ID=your-client-id
11.2 Okta Application Configuration
Application Type: Single-Page App (SPA) Grant Types:
- Authorization Code
- Refresh Token Redirect URIs:
- Production:
https://rebridge.co.in/login/callback - Development:
http://localhost:3000/login/callbackLogout Redirect URI: - Production:
https://rebridge.co.in - Development:
http://localhost:3000
11.3 Database Schema
Users Table:
CREATE TABLE users (
user_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
employee_id VARCHAR(50),
okta_sub VARCHAR(255) UNIQUE,
first_name VARCHAR(100),
last_name VARCHAR(100),
display_name VARCHAR(200),
department VARCHAR(100),
designation VARCHAR(100),
phone VARCHAR(20),
role VARCHAR(20) DEFAULT 'USER' CHECK (role IN ('USER', 'MANAGEMENT', 'ADMIN')),
is_active BOOLEAN DEFAULT true,
last_login TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
12. Troubleshooting
12.1 Common Issues
Issue: "Token has expired"
- Cause: Access token expired (24 hours)
- Solution: Token should refresh automatically. If not, check refresh token validity.
Issue: "User not found or inactive"
- Cause: User account deactivated or removed from database
- Solution: Check
users.isActivestatus. Reactivate user if needed.
Issue: "Invalid token"
- Cause: Token signature invalid or JWT secret mismatch
- Solution: Verify
JWT_SECRETmatches between environments.
Issue: "Okta authentication failed"
- Cause: Invalid Okta credentials or network issue
- Solution: Verify
OKTA_CLIENT_IDandOKTA_CLIENT_SECRET. Check Okta domain accessibility.
Issue: Cookies not being set
- Cause: Cookie options mismatch or CORS configuration
- Solution: Verify
FRONTEND_URLmatches frontend domain. CheckwithCredentials: truein Axios config.
12.2 Debugging
Enable Debug Logging:
LOG_LEVEL=debug
Check Token Validity:
# Decode JWT token (without verification)
echo "YOUR_TOKEN" | base64 -d
Verify Cookie Settings:
- Check browser DevTools → Application → Cookies
- Verify
HttpOnly,Secure,SameSiteflags - Check cookie
PathandDomain
Test Authentication Flow:
- Clear browser cookies and localStorage
- Navigate to application
- Complete Okta login
- Check network tab for
/api/v1/auth/token-exchangerequest - Verify cookies are set in response headers
- Check subsequent API requests include cookies
13. Future Enhancements
13.1 Planned Features
- SCIM 2.0 Provisioning: Automated user provisioning from HRMS
- Refresh Token Rotation: Enhanced security for token refresh
- Rate Limiting: Protect authentication endpoints from brute force
- Session Management: Active session tracking and management
- Device Management: Track and manage user devices
- Audit Dashboard: Visual interface for authentication and access logs
13.2 Integration Opportunities
- Azure Entra Integration: Federation with Azure Entra for enterprise SSO
- Tanflow Integration: Full integration with Tanflow IdP
- HRMS Integration: Direct integration with HRMS for user data
- Active Directory Integration: LDAP/AD integration for on-premises users
Document Version
- Version: 1.0
- Last Updated: December 2024
- Author: RE Workflow Development Team
- Review Status: Draft
Appendix
A. Glossary
- IdP: Identity Provider (Okta, Tanflow)
- SSO: Single Sign-On
- JWT: JSON Web Token
- OAuth 2.0: Authorization framework
- OIDC: OpenID Connect
- SAML: Security Assertion Markup Language
- SCIM: System for Cross-domain Identity Management
- MFA: Multi-Factor Authentication
- RBAC: Role-Based Access Control
- CSP: Content Security Policy
- HSTS: HTTP Strict Transport Security
B. References
- Okta Developer Documentation
- OAuth 2.0 Specification
- OpenID Connect Specification
- JWT.io
- SCIM 2.0 Specification
End of Document