@zxkit/authz
Typed authorization for roles, permissions, and routes.
Your app already knows who the user is. This decides what they can see and run — once, with the same types on the server, the client, and the Next.js proxy.
Define once
permissions.ts
One catalog of resources and actions. Everything else is typed from it.
import { definePermissions } from '@zxkit/authz'
export const permissions = definePermissions({
order: ['read', 'create', 'update', 'delete'],
invoice: ['read', 'export'],
settings: ['manage'],
})Server
authz.ts
Session, adapter, and cache in one helper. protect wraps any server action.
import { createAuthz, redisCache } from '@zxkit/authz'
import { prismaAuthzAdapter } from '@zxkit/authz/prisma'
export const authz = createAuthz({
permissions,
getSession,
adapter: prismaAuthzAdapter(db),
cache: redisCache(redis, { ttl: 60 * 30 }),
})
export const deleteOrder = authz.protect(
{ order: ['delete'] },
async ({ user }, orderId: string) => {
return orders.delete({ orderId, deletedBy: user.id })
}
)Client
authz-client.ts
Typed guards and hooks. No fetching — they read the snapshot you already loaded.
'use client'
import { createAuthzClient } from '@zxkit/authz/client'
import { permissions } from './permissions'
export const { AuthzProvider, Can, Guard, useCan } =
createAuthzClient(permissions)Routes
proxy.ts
The same route definitions protect the whole app before anything renders.
import { createAuthzProxy } from '@zxkit/authz/next'
export const proxy = createAuthzProxy({
authz,
auth: { signIn: '/login', afterSignIn: '/hub', forbidden: '/hub' },
public: ['/'],
guestOnly: ['/login'],
protected: [{ matcher: '/hub/:path*', routes }],
})- Typed permissions
- Resources and actions autocomplete. Invalid ones fail to compile.
- Roles in your database
- The catalog lives in code; roles and assignments live in Prisma.
- Guards everywhere
- Can, Guard, and hooks on the client. require and protect on the server.
- Next.js proxy
- Protected zones, guest-only and public routes from the same definitions.
- Cached snapshots
- Memory or Redis, invalidated on role mutations, resilient to outages.