Academic Dashboard

Centralized Campus SSO for Faculty Modules

On-goingWorkFull-stack engineer5 min read

Designed and developed from end-to-end, a campus platform that hosts faculty modules: central Google SSO and EduColab - A faculty module for 'Agile Curriculum Development', cross-course focus group requests, meetings, and follow-ups, and a shared AI job service in front of a private model. Design focus was clear login vs product permissions, safe releases with live users, and one authenticated path to GPU inference.

Stack · Java 17 · Spring Boot · Spring Security · OAuth2 · JWT · Angular · PrimeNG · PostgreSQL · Redis · Node.js · Docker · Caddy · AWS · GitHub Actions

Private projectPrivate repo

Images coming soon

The brief

I built parts of a campus web platform faculty use every day. Sign in once, open use modules, and (when a team needs it) request AI help without each app inventing its own stack. A privately hosted LLM was selected for privacy.

My work covers three areas. A central login service. EduColab, the faculty product in this codebase for coordinating across courses. A shared AI service that sits in front of a private model so apps do not talk to the GPU machine directly. Other teams plug their own apps into the same login and site with a strict module integration API contract. I own the shared pieces and EduColab.

What I'm solving

Two problems sit next to each other.

On the product side, faculty often need a structured way to pull the right instructors into a conversation when a course depends on others (prerequisites, corequisites, courses that build on it). That work used to live in email threads and one-off meetings. EduColab is meant to make that coordination visible: a request, the right stakeholders, meetings, and follow-ups that can be closed.

On the platform side, campus tools often start as separate logins. That is fine for one app. It gets messy when several teams ship on the same site, share users, and later want access to the same AI hardware.

I was solving for a few practical needs:

  • One sign-in for people who belong on campus
  • EduColab (and later apps) that can say "you are logged in" and separately "you are allowed to use this tool"
  • A faculty workflow for cross-course coordination instead of scattered email
  • Several UIs and APIs behind one public website
  • A shared way to call an LLM without exposing the private model host
  • Safe updates after real users were already live

We also had limited machine capacity. Every new heavy service competed for the same memory, so I had to stay picky about what ran where.

How it works

Login lives in one place. Faculty authenticate through the campus Google path we support. The browser keeps a secure session cookie. Apps check that session on each request. Permissions for a given product still live in that product's own database. The home page shows which tools you can open based on a server-side list, not hard-coded links in every frontend.

EduColab is the main faculty app after that check. The core object is a focus group request: a faculty member opens a request to coordinate discussion across related courses, pulls in instructors for a course and its neighbors in the curriculum graph, schedules meetings from that request, and tracks action items until they are done. Faculty and admin roles live inside EduColab's own data. Admins also get tools for users, academic terms, requisites, and bulk data work. If the session is missing, the app stops you. If you are logged in but not set up for EduColab, you get a different failure. Support is much easier when those two cases are not mixed together.

For AI, apps submit a job and check back later instead of holding a long chat connection to the GPU. The shared service authenticates the caller, queues work, applies simple limits, and talks to the model runtime in private. I also built the option to power the GPU down when idle; turning that on waits on product agreement, because a cold start changes how the UI feels.

There is a small admin area on the gateway for operators: who has access, which apps are registered, and a trail of sensitive changes. Edge routing updates are meant to be deliberate publishes, not ad hoc edits on the live host.

Architecture choices

The stack includes Java and Spring Boot for the login API and the EduColab API - Angular and PrimeNG for the gateway UI and EduColab UI. PostgreSQL for product data, Redis for session and rate-limit state. I used Node for a light AI queue to manage requests made to a privately hosted LLM. Docker and Caddy on AWS for how it all sits behind HTTPS. GitHub Actions for release automation.

Certain key design choices were as follows:

  1. Login only answers who you are - This was a deliberate choice, allowing module developers to freely define own role/attribute based access control, allowing various departments and areas to function in ways they desire to. The gateway only checks if you are a valid RIT faculty, and allows modules to verify this fact securely.

  2. Ship the piece you meant to change - Once faculty were live, I stopped treating "rebuild everything" as the default. Each module has their own workflow, which should not (hopefully) break other modules and/or the gateway itself.

  3. Do not give every app a private path to the GPU - A shared, authenticated queue costs a bit of ceremony up front and saves you from five different configs pointing at the same expensive box. Also helps with logging, managing the requests better etc.

What shipped

  • Live campus sign-in and EduColab for faculty coordination (focus group requests, meetings, follow-ups, admin data tools)
  • A path for other teams to join the same login and site without rebuilding auth
  • A shared AI job API in production (usage and idle-cost policy still being settled with callers)
  • Operator tools for access, app registry, and change history
  • Written integration notes so the next team has something better than tribal knowledge

TODO: confirm which screenshots or short demos I may show publicly

What I'd do again

Agree early on what login owns and what EduColab owns. Vague boundaries turn into confusing "access denied" bugs later.

Treat "users are already here" as a design constraint. Small, targeted releases beat heroic full rebuilds.

Put authentication and a queue in front of private AI early, then look at real usage before you leave a GPU running all day.

Write down what is actually live. When someone asks what changed, or why cost moved, you want a short honest picture, not a reconstruction from chat history.