cauthy-auth
v0.15.0
Published
Sign in with Cauthy: one route to mount, getSession on the server, useSession in the browser. No database, no screens to build.
Maintainers
Readme
cauthy-auth
Sign your people in with Cauthy: one route to mount, getSession on the server, useSession in the browser.
- Nothing to build. Sign-in, sign-up, second factors, passkeys, sign-in links, password recovery and the account page are Cauthy's own pages.
- No database, no migration. The session lives in an encrypted, httpOnly cookie.
- No token in the browser. The browser asks your server who is signed in.
- Central control. An account disabled in Cauthy is out of your application within minutes.
npm install cauthy-auth// auth.ts — reads CAUTHY_ISSUER, CAUTHY_CLIENT_ID, CAUTHY_SECRET (and CAUTHY_SYSTEM)
import { createCauthy } from 'cauthy-auth'
export const auth = createCauthy()// a route that catches /api/auth/* — any runtime with Request and Response
export const GET = (request: Request) => auth.handler(request)
export const POST = (request: Request) => auth.handler(request)// on the server
const session = await auth.getSession(request, responseHeaders)
session?.user // { id, email, name, emailVerified, restricted }
await auth.organizations(session) // [{ id, name, role, … }]// in the browser
import { CauthyProvider, useSession } from 'cauthy-auth/react'
const { session, signIn, signOut } = useSession()Prefer your own sign-in page to Cauthy's? Set CAUTHY_TENANT and draw it, with the ready-made forms or the functions under them. The browser still holds no token:
import { SignIn, useAuth } from 'cauthy-auth/react'
<SignIn locale="es" links={{ signUp: '/registro', forgotPassword: '/olvide' }} />
const { signIn } = useAuth()
const r = await signIn.email({ email, password }) // r.ok, r.status, r.error.fieldWhat Cauthy mails opens your pages too: a new password, a confirmed address, a sign-in link.
export const auth = createCauthy({ pages: { signIn: '/sign-in', resetPassword: '/new-password', verifyEmail: '/confirm' } })import { ResetPassword, VerifyEmail } from 'cauthy-auth/react'And the person's account, in your application: name, password, second step, sessions.
import { Account } from 'cauthy-auth/react'
<Account /> // or: const { account } = useAuth()Roles and permissions with their names, from the catalog Cauthy has:
npx cauthy-auth policy --pull --out src/policy.tsimport { can, hasRole } from './policy'
can(organization, 'ledger:write') // only what the catalog names compilesEach framework has its own few lines:
| | |
| --- | --- |
| Next.js | cauthyNext(auth) from cauthy-auth/next: { GET, POST }, session(), middleware() |
| Express | app.use(cauthyExpress(auth)) from cauthy-auth/express: req.cauthy(), requireSession |
| Hono | app.use(cauthyHono(auth)) from cauthy-auth/hono: c.get('session'), requireSession |
| Fastify | app.register(cauthyFastify, { auth }) from cauthy-auth/fastify: req.cauthy(), app.requireSession |
| Anything else | auth.handler(request) takes a Request and answers a Response |
In the browser, beside React:
| | |
| --- | --- |
| Vue | app.use(createCauthyVue()), then useSession() and useAuth() from cauthy-auth/vue |
| Svelte | createCauthySession() from cauthy-auth/svelte: $session, $status, auth |
| Anything else | createSessionStore() from cauthy-auth/client |
The ready-made forms wear the look set for your application in Cauthy's dashboard (colours, corners, typeface), the same as Cauthy's own sign-in page, with one import:
import 'cauthy-auth/styles.css'Or draw them with your own components and classNames, and pass unstyled. The dashboard can start the look from your stylesheet (shadcn/ui and Tailwind, Stackmyth, or variables of your own); npx cauthy-auth theme --css src/app/globals.css reads it the same way from a terminal.
Connect your application to Cauthy in one step, from Cauthy's dashboard ("Connect a System") or from a terminal. In the application's folder, init reads its framework (Next.js, TanStack Start, SvelteKit, Express, Hono, Fastify), makes the client, writes every variable to its env file, CAUTHY_SECRET included, and lays down the route and a sign-in page, never over a file that is there:
npx cauthy-auth init
npx cauthy-auth init --system ledger --app-url https://app.example.com # productionThe same client is your application's own identity: it manages its organizations with no person's token.
const org = await auth.system.organizations.create({ name: 'Acme' })
await auth.system.members.add(org.id, { role: 'owner', email: '[email protected]' })A backend that is handed a Cauthy access token checks it with Cauthy's published keys: no secret, no call per request.
import { verifyToken } from 'cauthy-auth'
const who = await verifyToken(request) // throws CauthyTokenError: answer 401
who.userId, who.tenantId, who.rolesAn MCP server (or an API) that AI agents use as one of your people: Claude, Cursor and others find Cauthy from it, the person signs in and allows the agent, and the token works on that server alone.
import { mcpAuth } from 'cauthy-auth/mcp'
const auth = mcpAuth({ resource: 'https://mcp.example.com/mcp', scopes: ['books:read'] })
app.use(auth.middleware()) // or auth.protect(handler) for Request/ResponseThe full guide is in Cauthy's documentation, under "Auth SDK".
License
Apache-2.0
