Security Features
Comprehensive security measures including JWT authentication, two-factor authentication, rate limiting, and multi-tenant data isolation.
Overview
Testify implements multiple layers of security to protect user accounts, data, and system integrity. The security architecture includes JWT-based authentication with short-lived access tokens and long-lived refresh tokens, optional two-factor authentication (2FA) using TOTP, email verification, account lockout protection, session management, five-tier rate limiting, input sanitization, and strict multi-tenant data isolation. These measures work together to provide enterprise-grade security for educational institutions.
How It Works
Authentication Flow
Sign-Up
- Users register with email, password, first name, and last name.
- Email format is validated and password must be at least 8 characters.
- The password is hashed using bcrypt before storage.
- A verification token is generated and a verification email is sent.
- Optionally, a tenant code can be provided to join an organization.
- A referral code can be applied during sign-up for bonus credits.
Login
- User submits email and password.
- The system checks for account lockout -- too many failed attempts result in a temporary lockout.
- If 2FA is enabled, the user must provide a valid TOTP code.
- On success, the system generates:
- Access token (JWT) -- valid for 15 minutes, contains user ID, roles, org info, and tenant data.
- Refresh token -- valid for 30 days, stored as a hashed value in the session table.
- A session record is created tracking device info, IP, and last activity.
- Failed login attempts are recorded; successful login clears the failure count.
Token Refresh
- When the access token expires, the client sends the refresh token to get a new access token.
- The refresh token is verified against the stored hash in the sessions table.
- A new access token is issued without requiring re-authentication.
Logout
- The access token is added to a blacklist to prevent further use.
- The session is revoked.
- Users can revoke all sessions (sign out everywhere).
Two-Factor Authentication (2FA)
Testify supports TOTP-based 2FA using authenticator apps (Google Authenticator, Authy, etc.):
Enabling 2FA
- Go to Security Settings in your account.
- Click Enable 2FA.
- The system generates a TOTP secret and displays a QR code.
- Scan the QR code with your authenticator app.
- Enter the verification code from the app to confirm setup.
- 2FA is now active on your account.
TOTP Secret Storage
TOTP secrets are encrypted using AES-256-GCM before storage:
- A dedicated encryption key (
TOTP_ENCRYPTION_KEY) is used. - Secrets are stored in the format
iv:authTag:ciphertext. - The encryption key is derived from the environment variable via SHA-256.
Logging In with 2FA
- Enter your email and password as usual.
- If 2FA is enabled, a second prompt asks for the 6-digit TOTP code.
- Enter the current code from your authenticator app.
- The code is verified server-side and login proceeds if valid.
Email Verification
- New accounts receive a verification email with a unique token.
- The token encodes the user ID, IP address, and user agent for security.
- Users must click the verification link to activate their account.
- Unverified accounts may have restricted access depending on organization policy.
Account Lockout
- Failed login attempts are tracked per user.
- After a configurable number of failures, the account is temporarily locked.
- The lockout duration increases with repeated failures.
- Successful login clears the failure counter.
Key Features
JWT Token Architecture
| Token | Lifetime | Purpose | Storage |
|---|---|---|---|
| Access Token | 15 minutes | API authorization | Client-side (memory/localStorage) |
| Refresh Token | 30 days | Obtain new access tokens | Client-side; hash stored server-side |
Access tokens contain:
- User ID.
- Email.
- Roles (array).
- Organization ID.
- Tenant ID.
- Token expiration.
Session Management
Each login creates a session record that tracks:
- Device information (user agent).
- IP address.
- Last activity timestamp.
- Session status (active/revoked).
Users can:
- View all active sessions.
- Revoke individual sessions.
- Revoke all sessions (useful if a device is lost or compromised).
Rate Limiting (5 Tiers)
Testify implements five tiers of rate limiting to protect against abuse:
| Tier | Window | Max Requests | Use Case |
|---|---|---|---|
| Standard | 1 minute | 100 | General API endpoints |
| Auth | 15 minutes | 10 | Login, signup, password reset |
| AI | 1 minute | 20 | AI generation, PDF extraction |
| Credit | 1 minute | 30 | Credit operations, billing |
| Strict | 1 minute | 5 | Sensitive operations |
Rate limiting uses:
- Redis for distributed rate limiting in production (supports multiple server instances).
- In-memory fallback when Redis is unavailable.
- Rate limit keys are based on authenticated user ID (preferred) or IP address.
- Response headers include
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reset.
Input Sanitization
- All user-generated content is sanitized using DOMPurify before rendering.
- This prevents Cross-Site Scripting (XSS) attacks.
- Sanitization is applied on both the client side (before display) and server side (before storage where applicable).
Multi-Tenant Data Isolation
Testify is a multi-tenant platform where each organization's data is strictly isolated:
- Every non-superadmin query filters by
tenant_id. - The
tenantMiddlewareextracts tenant information from the JWT and attaches it to the request. - Database queries enforce tenant boundaries -- users cannot access data from other organizations.
- Super Admin bypasses tenant isolation for cross-organization administration.
Token Blacklisting
- When a user logs out, their access token is added to a blacklist.
- The authentication middleware checks the blacklist before accepting a token.
- This prevents the use of stolen or leaked tokens after logout.
Password Security
- Passwords are hashed using bcrypt with an appropriate salt factor.
- Password reset uses a time-limited token sent via email.
- Minimum password length of 8 characters is enforced.
Security Best Practices for Users
- Enable 2FA on your account for an extra layer of protection.
- Use a strong, unique password -- at least 8 characters with a mix of letters, numbers, and symbols.
- Verify your email promptly after registration.
- Review active sessions periodically and revoke any you do not recognize.
- Log out from shared devices to prevent unauthorized access.
- Do not share your refresh token -- it provides long-term access to your account.
For Administrators
- Ensure
JWT_SECRETis set to a strong, unique value in production. - Configure
TOTP_ENCRYPTION_KEYfor 2FA secret encryption. - Monitor rate limit hits to identify potential attacks or abusive users.
- Review audit logs for suspicious login patterns.
- Use Redis for rate limiting in multi-server deployments.
- Regularly rotate secrets and encryption keys.
- Enforce email verification for all users in your organization.
Related Features
- Notifications -- security events (login from new device, password changes) can trigger notifications.
- Classroom -- multi-tenant isolation ensures class data is organization-scoped.