← Back to all posts

Architecture

Provider-agnostic core: contracts before code

11 min

Why the Auth Fly stack splits into core, authkit and authkit-hanko — and how that split lets us swap Hanko for Supabase or a custom Postgres backend without touching the UI or the IdP.

The first thing we built was not a feature — it was a contract package. core defines what an IdP flow needs to know, with zero imports of UI, Hanko or storage.

What lives in core

  • FlowConfig — API URL, session cookie name, logout path, browser SDK script URL.
  • FeatureFlags — registration toggles (public, OIDC, SAML).
  • AuthCode / AuthCodeStore — OAuth2-style authorization codes for the OIDC layer.
  • CredentialVerifier — verify bearer or session tokens, expose FlowConfig() for the UI layer.
  • IdentityClaims, session helpers, shared errors.

Why this order

If the core depends on a specific provider, every new provider becomes a fork. If the UI depends on a specific provider, every new provider becomes a UI rewrite. By writing the contracts first, we made the rest of the stack honest.

How the split pays off

  • authkit renders pages from a ViewConfig that includes a generic FlowConfig — no provider name appears.
  • authkit-hanko implements CredentialVerifier for Hanko: JWT + JWKS verification, cookie extraction, the right SDKScript pointer.
  • The IdP composes both at startup. Replacing Hanko with another provider means writing a new package next to authkit-hanko.

Future modules

  • github.com/authfly/core — the contracts.
  • github.com/authfly/authkit — the hosted UI.
  • github.com/authfly/authkit-hanko — the first provider adapter.

Auth Fly logo

Auth Fly

Open auth construction kit

About Auth Fly