Authentication
Overview
Section titled “Overview”Authentication is handled by Clerk, restricted to The Ohio State University email domains. The backend verifies Clerk-issued JWTs on every API request.
Behaviors
Section titled “Behaviors”Email Domain Restriction
Section titled “Email Domain Restriction”Only users with @osu.edu or @buckeyemail.osu.edu email addresses can create accounts. This is enforced at two layers:
- Clerk (client-side): Clerk is configured with an allowlist of permitted email domains, rejecting non-OSU sign-ups at the identity provider level.
- API middleware (server-side): The
requireAuthmiddleware validates the email domain from the Clerk JWT as defense-in-depth. Requests with non-OSU emails receive a 403 Forbidden response.
JWT Verification
Section titled “JWT Verification”Every API request includes a Clerk JWT in the Authorization: Bearer <token> header. The @hono/clerk-auth middleware validates the token and populates the request context with the authenticated user’s Clerk ID.
User Provisioning
Section titled “User Provisioning”When a user authenticates for the first time, the system creates a User record linked to their Clerk ID. Subsequent requests resolve the User record via clerkId.
Authenticated Shell Guard
Section titled “Authenticated Shell Guard”The authenticated client shell uses a shared route guard. Any navigation into an authenticated page tree checks Clerk auth state before page-specific loaders or components run. Unauthenticated visitors are redirected to the sign-in page through the shared parent route rather than through duplicated page-level checks.
Scenarios
Section titled “Scenarios”S-AUTH-1: Valid OSU email sign-up
Section titled “S-AUTH-1: Valid OSU email sign-up”GIVEN a user with email "student@osu.edu"WHEN they complete Clerk sign-upTHEN the system creates a User record with that email and their clerkIdS-AUTH-2: Valid BuckeyeMail sign-up
Section titled “S-AUTH-2: Valid BuckeyeMail sign-up”GIVEN a user with email "student@buckeyemail.osu.edu"WHEN they complete Clerk sign-upTHEN the system creates a User record with that email and their clerkIdS-AUTH-3: Non-OSU email rejected
Section titled “S-AUTH-3: Non-OSU email rejected”GIVEN a user with email "student@gmail.com"WHEN they attempt Clerk sign-upTHEN Clerk rejects the sign-upAND no User record is createdS-AUTH-3b: Non-OSU email rejected at API layer (defense-in-depth)
Section titled “S-AUTH-3b: Non-OSU email rejected at API layer (defense-in-depth)”GIVEN a valid JWT for a user whose primary email is "student@gmail.com"AND no User record exists with that clerkIdWHEN the user makes an API requestTHEN the API responds with 403 ForbiddenAND no User record is createdS-AUTH-4: Valid JWT on API request
Section titled “S-AUTH-4: Valid JWT on API request”GIVEN a request with a valid Clerk JWT for user "clerk_abc123"WHEN the request reaches any /api/* endpointTHEN the middleware extracts clerkId "clerk_abc123"AND the request proceeds with the authenticated user contextS-AUTH-5: Missing or invalid JWT
Section titled “S-AUTH-5: Missing or invalid JWT”GIVEN a request with no Authorization header OR an invalid JWTWHEN the request reaches any /api/* endpointTHEN the API responds with 401 UnauthorizedS-AUTH-6: First-time user provisioning
Section titled “S-AUTH-6: First-time user provisioning”GIVEN a valid JWT for clerkId "clerk_new_user"AND no User record exists with that clerkIdWHEN the user makes their first API requestTHEN the system creates a User record with clerkId "clerk_new_user" and the email from the JWTAND the request proceeds normallyS-AUTH-7: Unauthenticated user is blocked from the authenticated shell
Section titled “S-AUTH-7: Unauthenticated user is blocked from the authenticated shell”GIVEN a visitor is not signed inWHEN they navigate to any page inside the authenticated app shellTHEN the shared client-side auth guard redirects them to "/sign-in"AND the child page does not need to redefine its own auth redirectConfiguration
Section titled “Configuration”Clerk Dashboard — Email Domain Allowlist
Section titled “Clerk Dashboard — Email Domain Allowlist”The Clerk instance is configured to restrict sign-ups to OSU email domains. To set this up or verify the configuration:
- Open the Clerk Dashboard and select the project.
- Navigate to User & Authentication → Restrictions.
- Under Sign-up restrictions, enable Allowlist.
- Add the following domains to the allowlist:
osu.edubuckeyemail.osu.edu
- Ensure Block sign-ups from email addresses not on the allowlist is enabled.
- Save changes.
This prevents non-OSU users from creating accounts at the Clerk identity layer. The API middleware provides an additional server-side check as defense-in-depth (see S-AUTH-3b).
Test Cases
Section titled “Test Cases”See test-cases/auth/authentication.md for the full test case registry (TC-AUTH-001 through TC-AUTH-011), including automated API tests, E2E tests, and manual UI verification cases.