Security Architecture
Defense-in-depth, cryptographic tokens, and strict tenant isolation.
Job-Easy implements defense-in-depth, relying on strict server-side enforcement rather than client-side UI hiding.
The Gate Chain
app/(app)/layout.tsx and every /api/* route enforce this strict sequence. Failing any step halts the chain. Admins are explicitly exempt from maintenance, subscription, legal, and onboarding gates so they can resolve global lockouts.
Authentication & Sessions
- No Third-Party Auth: The platform owns its identity store (no dependency on Auth0/Clerk).
- Hashed Tokens: The browser cookie holds a random secret token; the database stores its SHA-256 hash. A stolen database dump cannot forge live sessions.
- Immediate Revocation: Deleting a session row revokes access instantly on the next request.
- bcrypt Limits: Passwords are hashed using bcrypt. The platform explicitly accounts for bcrypt's internal 72-byte ceiling to prevent silent truncation vulnerabilities.
Data Protection
Encrypted OAuth Tokens
Gmail refresh tokens are symmetrically encrypted at rest using AES-256-GCM. The decryption key never leaves the environment variables.
Private Resumes & HMAC
Resumes are stored as authenticated assets in Cloudinary. Public share links use strict cryptographic HMAC shareTokens to prevent IDOR attacks.
Strict Tenant Isolation
Every user-facing query enforces a userId: session.user.id clause in the WHERE statement, completely avoiding the dangerous fetch-then-compare anti-pattern.
Non-Production Mail Guard
Platform mail in staging/dev silently drops or redirects all emails unless an explicit whitelist is configured, guaranteeing the platform never accidentally spams real users during testing.
Audit Logging
Every significant action—login, setting change, password reset, admin impersonation, or approval—writes an immutable AuditLog row. The admin settings PATCH endpoint dumps the entire diff into the audit log metadata.
Secrets never go into SystemSetting
SystemSetting would expose them in plain text to all admins. Secrets must only live in environment variables.