cauthy-auth
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.field
What 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.ts
import { can, hasRole } from './policy'
can(organization, 'ledger:write') // only what the catalog names compiles
Each 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, React Router or Remix, SvelteKit, Vite + React, 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 # production
The 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: 'ana@acme.com' })
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.roles
An 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/Response
When that server calls another of your servers for the person, it trades the agent's token for one for that server (token exchange, RFC 8693). Delegate the call and create the server's credentials in the dashboard first:
const auth = mcpAuth({ resource, clientId: process.env.CAUTHY_MCP_CLIENT_ID, clientSecret: process.env.CAUTHY_MCP_CLIENT_SECRET })
const { accessToken } = await auth.exchange(req.agent, 'https://api.example.com', ['orders:read'])
The full guide is in Cauthy's documentation, under "Auth SDK".
License
Apache-2.0
Related Packages
AuthAction server-side SDK — session-based auth for Next.js, Nuxt, Remix, and Sv...
Nuxt 4 module for OIDC/SSO authentication with Laravel Passport or any OIDC prov...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.22.0 | >=3.3 | Apache-2.0 | |
| 0.20.0 | >=3.3 | Apache-2.0 | |
| 0.19.0 | >=3.3 | Apache-2.0 | |
| 0.18.0 | >=3.3 | Apache-2.0 | |
| 0.17.0 | >=3.3 | Apache-2.0 | |
| 0.16.0 | >=3.3 | Apache-2.0 | |
| 0.15.0 | >=3.3 | Apache-2.0 | |
| 0.14.0 | >=3.3 | Apache-2.0 | |
| 0.13.0 | >=3.3 | Apache-2.0 | |
| 0.12.0 | >=3.3 | Apache-2.0 | |
| 0.11.0 | >=3.3 | Apache-2.0 | |
| 0.10.0 | >=3.3 | Apache-2.0 | |
| 0.9.0 | >=3.3 | Apache-2.0 | |
| 0.8.0 | >=3.3 | Apache-2.0 | |
| 0.5.2 | Apache-2.0 | ||
| 0.5.1 | Apache-2.0 | ||
| 0.5.0 | Apache-2.0 | ||
| 0.4.0 | Apache-2.0 | ||
| 0.3.0 | Apache-2.0 | ||
| 0.2.0 | Apache-2.0 | ||
| 0.1.0 | Apache-2.0 |
Pre-releases (1)
| Version | Released | License |
|---|---|---|
| 0.0.0-stage |