Alok Auth

Alok Auth

I built this project to understand how an auth server actually works under the hood. Instead of only reading about OAuth 2.0 and OpenID Connect, I wanted to implement the moving parts myself: login, consent, authorization codes, ID tokens, access tokens, refresh tokens, sessions, and the redirects that hold the whole flow together.

This is a working OpenID Connect-first server. The flow requires the openid scope, as it is designed around OIDC's identity layer on top of OAuth 2.0. It follows standard OIDC behavior closely, so a client can switch between this server and providers like Google just by changing configuration (issuer, client ID, client secret), without modifying application logic.

I wanted to learn the system by building the system.

I've always found OAuth and OpenID Connect interesting, and at some point I wanted to go beyond just reading about them and actually build one myself.

So this server became my way of learning the protocol by implementing it end to end covering login, consent, tokens, and the full flow behind the scenes.

The flow

  1. A client app registers and gets credentials.
  2. It sends the user to /authorization.
  3. If the user is not logged in, I send them to login.
  4. If they are logged in, I skip login.
  5. If consent is missing, I show consent.
  6. If consent already exists, I skip that too.
  7. The server issues an authorization code.
  8. The client exchanges that code at /token.
  9. The response includes an ID token, an access token, and a refresh token when offline access is requested.
  10. The client can call /userinfo for user claims.

How it behaves in practice

  • Sessions are server-side and stored in Postgres.
  • Each /authorization request creates a separate flow object in session.
  • A single user can have multiple client flows active in parallel.
  • Consent is persisted and reused.
  • Revoking access removes stored consent and invalidates issued tokens.

What a user can do after signing in

When signed in to this server:

  • View all apps that have been granted access
  • Review scopes and permissions
  • Revoke access for any app
  • Manage basic profile details

Revoking access removes both stored consent and issued tokens for that app.

Current constraints of the implementation

  • Sessions are stored in Postgres instead of Redis or a faster dedicated session store.
  • Client registration does not require authentication, to keep the setup simple.
  • Signing keys are static and there is no JWKS rotation.
  • The server's public and private signing keys are currently stored in .env instead of a proper secret manager.
  • There is no rate limiting or abuse protection.

I had already gone through the theory things like scopes, PKCE (code challenge), and the backend-to-backend token exchange, and I found the whole flow genuinely cool.

That was enough reason for me to try building it myself and see how it actually works when everything is wired together.

  • How does state survive across multiple redirects?
  • Where do nonce and PKCE actually fit in the flow?
  • What happens when multiple auth flows run in parallel for the same user?

This project is my way of learning those answers by implementing them, seeing the edge cases in code, and making the system behave the way I expect a real OIDC server to behave.