Overview
Gopherium’s authentication is five bricks with one dependency direction. Each layer consumes the one below it and none of them knows your application exists.
@gopherium/react-auth React client: gate, hooks, screens, test harness │ speaks JSON toauthkit HTTP transport: handlers, middleware, cookie │ persists throughauthkit/postgres gouncer.Store in a schema of its own │ implementsgouncer pure primitives: users, passwords, sessions
authkit/ratelimit wraps the login route, independent of all of themThe division of labor
Section titled “The division of labor”gouncer is
the pure core: validated user construction, argon2id password hashing
and verification, session issuance, token hashing, and the Store
interface with its sentinel errors. Its dependencies are the standard
library, google/uuid, and golang.org/x/crypto, enforced by a lint
rule. It owns none of your HTTP layer.
authkit
is that HTTP layer, shared instead of re-typed: login, logout, and
session handlers, the RequireSession middleware, the __Host-
cookie, the user administration surface,
a session garbage collector, and a bootstrap helper. It exports
handlers and middleware, never a router.
authkit/postgres
implements the store in PostgreSQL, inside a schema it owns
outright, so it composes into your
database without touching your migrations.
authkit/ratelimit
budgets failed logins per client IP, with the
reverse-proxy trust model that makes
per-IP meaningful behind a proxy.
@gopherium/react-auth
is the browser side: a session-aware gate, hooks, typed errors, a
WordPress-Design-System skin, an admin UI, and an msw-based
test harness.
Adopt what you need
Section titled “Adopt what you need”The layering exists so you can stop at any line:
- Bring your own transport and take only
gouncer. Its README documents the integrator obligations the higher bricks otherwise absorb. - Take
authkitwith your own database by implementing the five-methodgouncer.Storeagainst anything that persists. - Take everything, and your integration is the Quickstart.
The contract in one paragraph
Section titled “The contract in one paragraph”A login exchanges credentials for an opaque token, delivered once in a
__Host- cookie and stored only as a digest. Every protected request
resolves the cookie to a user through the store, and everything
downstream of RequireSession sees an Identity carrying no
credential material. Disabling a user revokes their sessions in the
same transaction. Expired sessions are swept on an interval. Failed
logins are rate limited per client IP and cost the same for known and
unknown emails. The security model
page walks each of those claims.