CORTEX
All projects

CampusSync

PROTOTYPE

Multi-tenant certificate verification for universities and recruiters.

Personal project · Sep–Dec 2025 · 165 commits

THE PROBLEM

Certificates are checked by hand and are easy to forge, so recruiters can't trust the ones they receive.

HOW IT WORKS

  • Students upload certificates; Gemini vision extracts the fields and regular expressions normalise them; faculty approve.
  • Approved certificates are issued as signed credentials (RS256 JWS in a W3C-VC-shaped JSON) with revocation and public verification.

THE PIPELINE

  1. Student uploadThe student uploads a certificate.
  2. Gemini visionExtracts the fields; regular expressions normalise them.
  3. Faculty approvalA reviewer verifies or rejects.
  4. Signed credentialRS256 JWS in a W3C-VC-shaped JSON, with revocation.
  5. Public verificationAnyone can check a credential.
Only faculty-approved certificates are issued as credentials.

ENGINEERING EVIDENCE

  • 101 API route files (138 handlers), guarded by role and organisation checks.
  • 91 passing tests across 6 files, and architecture documents in my-app/docs.
  • A Sep 2026 security review of every route found and fixed real holes: role assignment and signup that did not require a session, credential issuing for arbitrary claims, unauthenticated document-status routes that used the service role, unsigned webhooks and open redirects. Dependency audit findings went from 71 to 2. safeRedirect.ts ↗

WHAT ISN'T DONE

  • Credentials are JWT-style, not full W3C proofs, and signing keys are held in memory.
  • The review found that the early version was much less secure than the README suggested. The fixes are checked by typecheck, lint, the unit tests and a build, not against a live deployment.
  • Rate limiting is in memory and per server instance.
  • The database schema and row-level-security SQL are not in the repository (the migrations were removed from the main branch), so the policies could not be reviewed from the code.

NEXT STEPS

Each one comes from a gap listed above. It says what fixing the gap would take; it is not a promise.

  • Put the database schema and row-level-security SQL back in the repository so the policies can be reviewed.
  • Replace the in-memory rate limiter with a shared store.
  • Keep signing keys outside process memory.

STACK

  • Next.js
  • TypeScript
  • Supabase
  • PostgreSQL
  • Gemini
  • Vitest