Skip to main content

Architecture

goauth is structured like Auth.js: a small core package, optional providers, adapters, and a jwt subpackage.

Package layout

goauth/ # Core: Config, Auth handler, types, actions
├── jwt/ # JWE session tokens (Auth.js-compatible)
├── webauthn/ # Stdlib WebAuthn verification (passkeys)
├── providers/ # Provider constructors (import only what you need)
│ ├── github/
│ ├── passkey/
│ └── ...
├── adapters/ # Adapter implementations
│ ├── postgres/
│ ├── mysql/
│ └── memory/
└── client/ # Browser helper (goauth.js)

Import rules

RuleReason
Root goauth never imports providers/*Avoid import cycles
Providers import goauthConstructors return goauth.Provider
Core uses stdlib onlyPredictable deployments, no hidden deps

Core types

TypeRole
Authhttp.Handler — routes all /auth/* actions
ConfigTop-level configuration
ProviderSign-in method (ID, Name, Type)
AdapterUsers, accounts, sessions, verification tokens
User, Account, SessionDomain models (JSON-serializable)
JWTEncrypted session payload map

Optional adapter interfaces

Not every adapter must implement everything — goauth checks at runtime:

InterfaceUsed for
AdapterBase CRUD
MigratorAuto-create tables in goauth.New()
SessionListerGET /auth/sessions
AuthenticatorStorePasskey provider

Where logic lives

New behavior belongs in actions_*.go files, not inline in the router:

FileResponsibility
goauth.goServeHTTP route table
actions_auth.goSign-in, callback, OAuth
actions_mfa.goMFA challenge + verify
actions_passkey.goWebAuthn options + callback
actions_sessions.goList/revoke sessions
actions_simple.gosession, csrf, providers, signout
tokens.goBearer token refresh

Session strategies (summary)

flowchart TD
A[Sign-in succeeds] --> B{Strategy?}
B -->|JWT| C[Encrypt JWE cookie]
B -->|Database| D[Insert session row + cookie token]
C --> E[GetSession decodes cookie or Bearer]
D --> E

Details: Session strategies.

Comparison with Auth.js

Auth.jsgoauth
experimental.enableWebAuthnAdd PasskeyProvider (+ AuthenticatorStore)
Prisma Authenticator modelgoauth.Authenticator + goauth_authenticators table
signIn("passkey", { action: "register" })POST /auth/signin/passkey?action=register
@simplewebauthn/servergoauth/webauthn (stdlib ES256)