In enterprise education platforms, security isn’t a feature — it’s the foundation. When you’re handling student records, assessment data, and institutional credentials across multiple organizations on a shared infrastructure, the margin for error is zero.
At Genfinish, we built Cognaxa from the ground up with a zero-trust architecture. This means every request, every query, and every data access is verified against the principle of least privilege. Here’s how we do it.
The Multi-Tenancy Challenge
Most SaaS platforms handle multi-tenancy at the application layer — a WHERE tenant_id = ? clause appended to every query. This works until someone forgets a filter, a join leaks data, or a new engineer writes a raw query without the guard clause.
We decided early that application-level filtering is not sufficient for enterprise security requirements.
PostgreSQL Row-Level Security (RLS)
Instead of relying on application code to enforce tenant isolation, we push that responsibility down to the database itself using PostgreSQL’s Row-Level Security:
-- Enable RLS on the courses table
ALTER TABLE courses ENABLE ROW LEVEL SECURITY;
-- Create a policy that restricts visibility to the current tenant
CREATE POLICY tenant_isolation ON courses
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
-- Force RLS even for table owners
ALTER TABLE courses FORCE ROW LEVEL SECURITY;
Every table that holds tenant-specific data has RLS policies. Before any query executes, our database middleware sets the tenant context:
// Set tenant context before every query
await pool.query(
`SET LOCAL app.current_tenant_id = $1`,
[user.tenantId]
);
This means even if application code has a bug — a missing filter, a poorly constructed join — the database will not return data from another tenant. The isolation is enforced at the storage layer, not the application layer.
Session Architecture
Our session model follows zero-trust principles:
- Opaque tokens: Sessions use UUID tokens stored in Redis, not JWTs. This means sessions can be revoked instantly — there’s no window of valid-but-revoked tokens
- Server-side validation: Every request validates the session token against Redis. No client-side trust
- Scoped sessions: Each session is bound to a specific tenant. Cross-tenant access requires re-authentication
- Configurable TTL: Session lifetimes can be tuned per deployment (24h default, up to 30 days for low-risk environments)
// Session validation middleware (simplified)
const session = await redis.get(`session:${token}`);
if (!session) {
return res.status(401).json({ error: 'Session expired' });
}
const user = JSON.parse(session);
// Set tenant context for all subsequent database queries
req.user = user;
Defense in Depth
Zero-trust means layers. Here’s what sits between a request and your data:
| Layer | Mechanism | Purpose |
|---|---|---|
| Edge | Rate limiting (5000 req/15min) | DDoS mitigation |
| Transport | TLS 1.3 | Encryption in transit |
| Application | Helmet.js security headers | XSS, clickjacking prevention |
| Authentication | Bearer token + Redis lookup | Identity verification |
| Authorization | Role-based middleware | Permission enforcement |
| Database | PostgreSQL RLS | Tenant data isolation |
| Passwords | bcrypt (12 rounds) | Credential hashing |
| 2FA | TOTP (speakeasy) | Second factor verification |
Exam Integrity: A Special Case
Proctored exams introduce additional security challenges. Our proctoring system implements:
- Server-synced timers: The exam clock runs on the server, not the client. Browser DevTools can’t manipulate time
- Face detection: Real-time face monitoring using face-api.js with violation logging
- Tab-switch detection: Every tab switch is recorded with a timestamp
- Snapshot capture: Periodic webcam snapshots stored in S3 for manual review
All violation data is stored as JSONB in the attempt record, giving administrators a complete audit trail.
What’s Next
We’re actively working on:
- SOC 2 Type II compliance — Formalizing our security controls for enterprise audit requirements
- SSO integration — SAML 2.0 and OIDC support for institutional identity providers
- End-to-end encryption for sensitive assessment content at rest
Security is a journey, not a destination. Every feature we ship goes through threat modeling, and every quarter we review our attack surface. Because in education, trust isn’t optional — it’s the product.
Questions about our security architecture? Reach out to our team — we’re happy to discuss our approach in detail with your security team.