Live
fusheriff_head.png
FuscAuth

Centralized authentication service for the fuscripts ecosystem. Google OAuth, JWT tokens, shared commons packages, and the beginning of it all.

Node.js AWS Serverless DynamoDB Svelte

How it works

Here's what happens when you click "Sign in with Google" on a fuscripts app.

The journey starts before you even see the login page. When the fuscripts app you're trying to access realizes you're not authenticated, it redirects you to FuscAuth with a return address tucked into the URL:

?returnFuscapp=https://fusclock.fuscripts.com

FuscAuth's SvelteKit frontend grabs that parameter and stashes it in localStorage. This is important — the OAuth flow is about to bounce you through Google's servers, and we need to remember where you came from.

You click the button. The frontend calls the backend's /auth endpoint, which constructs a Google OAuth URL with the right client ID, callback URL, and scopes (openid email profile), then sends you off with an HTTP 302 redirect. You're on Google's turf now.

Google does its thing. Credentials, consent screen, the works. When you approve, Google redirects back to FuscAuth's /auth/callback endpoint with an authorization code.

The four-check identity resolution

The backend exchanges that code for a Google access token, then fetches your profile. Now it needs to figure out: who are you in our system? This isn't as straightforward as it sounds, because FuscAuth supports multiple identity scenarios. The handleOAuthLogin function runs four checks in sequence:

Check 1: Provider lookup. Query DynamoDB for AUTHPROVIDER#google#{googleId}. If you've logged in with Google before, we find your internal UUID instantly. Done.

Check 2: Legacy migration. If the system is in dual-write mode, check the old schema where Google IDs were the primary key. This handles users from before the UUID migration -- more on that in the next post.

Check 3: Email-based auto-linking. This is the clever one. Your email gets hashed with HMAC-SHA256 using a secret pepper, then we look up EMAILHASH#{hash}. If found, it means you already have an account through a different provider (say, GitHub) with the same email. FuscAuth links Google to your existing account automatically. One person, one identity, regardless of how they sign in.

Check 4: New user. None of the above matched. Generate a UUID with crypto.randomUUID(), create four DynamoDB records (profile, provider link, email hash lookup, and reverse provider lookup), and welcome them in.

What's in the token

Once we know who you are, the backend signs two JWTs: an access token (7 days) and a refresh token (30 days). The payload is deliberately minimal:

json
{
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "iat": 1730000000,
  "exp": 1730604800
}

No email. No name. No Google ID. Just an internal UUID. If a token leaks, none of our personal information goes with it.

The homecoming

The tokens land in the SvelteKit callback page, which stores them in localStorage and shows a success screen.

Then it reads back that returnFuscapp URL from earlier and redirects you home. You're back in fusclock with a valid token, and the whole thing felt like one click.

Under the hood: DynamoDB Monotable

All of this runs on one DynamoDB table with four access patterns:

KeyPurpose
USER#{uuid} + PROFILEUser profile and metadata
USER#{uuid} + AUTH#google#{id}Provider linkage
EMAILHASH#{hash} + USERCross-provider account linking
AUTHPROVIDER#google#{id} + USERFast login lookup

Four records per user. Every query is a direct key lookup. The single-table design means one DynamoDB table serves the entire fuscripts ecosystem, and FuscAuth's access patterns don't step on anyone else's.

The whole backend runs on AWS Lambda behind API Gateway, deployed with Serverless Framework. No servers to manage, no idle costs. The sheriff works on demand.