Every product needs sign-in; almost none is defined by it. @spfn/auth
ships the whole surface — client-signed JWT, OTP, OAuth with pluggable providers, Next.js
sessions and guards, runtime RBAC — as one package, wired into the SPFN slice.
Sign-in is the first thing every product builds and the last thing that
makes it different. So this package doesn't hand you primitives to assemble — it ships the
complete flow, already shaped to the SPFN pattern: routes under /_auth/*, a
typed authApi client, and exactly four wiring points in your app. The same
setup every time, for humans and agents alike.
Most auth stacks sign tokens with a server-held secret — whoever holds
that secret can mint any user's token, and one leak compromises every session.
@spfn/auth inverts the direction: each client generates its own ES256/RS256
keypair, registers the public key at login, and signs its request JWTs locally. The server
only verifies, against the stored public key the JWT's keyId points to. There
is no signing secret on the server to steal, logout is just revoking a key, and keys expire
after 90 days with rotation built in. Native social sign-in follows the same rule — the
server verifies the provider's id_token, binds it to the client's public key,
and still never issues a token itself.
Asymmetric ES256/RS256 — devices hold keys, the server verifies.
Pluggable provider registry — Google, Kakao, Naver built in.
Cookie sessions for Next.js — RequireAuth, RequireRole, getSession.
Runtime roles and permissions, seeded at boot, checked per route.
Email verification codes and single-use tokens.
beforeRegister hook — invite-only, allowlists, custom checks.
Declarative admin accounts, created at lifecycle boot.
Grace-period account deletion with a recovery window.