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
| Rule | Reason |
|---|---|
Root goauth never imports providers/* | Avoid import cycles |
Providers import goauth | Constructors return goauth.Provider |
| Core uses stdlib only | Predictable deployments, no hidden deps |
Core types
| Type | Role |
|---|---|
Auth | http.Handler — routes all /auth/* actions |
Config | Top-level configuration |
Provider | Sign-in method (ID, Name, Type) |
Adapter | Users, accounts, sessions, verification tokens |
User, Account, Session | Domain models (JSON-serializable) |
JWT | Encrypted session payload map |
Optional adapter interfaces
Not every adapter must implement everything — goauth checks at runtime:
| Interface | Used for |
|---|---|
Adapter | Base CRUD |
Migrator | Auto-create tables in goauth.New() |
SessionLister | GET /auth/sessions |
AuthenticatorStore | Passkey provider |
Where logic lives
New behavior belongs in actions_*.go files, not inline in the router:
| File | Responsibility |
|---|---|
goauth.go | ServeHTTP route table |
actions_auth.go | Sign-in, callback, OAuth |
actions_mfa.go | MFA challenge + verify |
actions_passkey.go | WebAuthn options + callback |
actions_sessions.go | List/revoke sessions |
actions_simple.go | session, csrf, providers, signout |
tokens.go | Bearer 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.js | goauth |
|---|---|
experimental.enableWebAuthn | Add PasskeyProvider (+ AuthenticatorStore) |
Prisma Authenticator model | goauth.Authenticator + goauth_authenticators table |
signIn("passkey", { action: "register" }) | POST /auth/signin/passkey?action=register |
@simplewebauthn/server | goauth/webauthn (stdlib ES256) |