The TypeScript toolkit for Permify with type-safe schema DSL, NestJS integration, and CLI for fine-grained authorization.
If permify-toolkit saves you time, please ⭐ star this repo, it helps others discover it!
Working with Permify's gRPC API directly is verbose. Permify Toolkit wraps it in a clean, type-safe TypeScript API so you can focus on your authorization model, not the plumbing:
- Zero gRPC boilerplate — connect with a single function call or environment variables
- Type-safe schema DSL — define entities, relations, and permissions in TypeScript with full autocompletion
- One config file —
permify.config.tsis shared between your NestJS app and CLI; no duplication - NestJS-first — drop-in module,
@CheckPermission()decorator, and guard with multi-permission AND/OR logic - CLI included — push schemas and seed relationships without writing scripts
This monorepo publishes three focused packages:
| Package | Install | Purpose |
|---|---|---|
@permify-toolkit/core |
pnpm add @permify-toolkit/core |
Schema DSL, client factory, shared config |
@permify-toolkit/nestjs |
pnpm add @permify-toolkit/nestjs |
NestJS module, guard, decorators |
@permify-toolkit/cli |
pnpm add -D @permify-toolkit/cli |
Schema push, relationship seeding |
# Core client + schema DSL
pnpm add @permify-toolkit/core
# NestJS integration
pnpm add @permify-toolkit/nestjs
# CLI (dev dependency)
pnpm add -D @permify-toolkit/cliimport {
defineConfig,
schema,
entity,
relation,
permission
} from "@permify-toolkit/core";
export default defineConfig({
tenant: "t1",
client: { endpoint: "localhost:3478", insecure: true },
schema: schema({
user: entity({}),
document: entity({
relations: { owner: relation("user") },
permissions: { edit: permission("owner"), view: permission("owner") }
})
})
});permify-toolkit schema push
permify-toolkit relationships seed --file-path ./data/relationships.json// app.module.ts
PermifyModule.forRoot({
configFile: true,
resolvers: {
subject: (ctx) => ctx.switchToHttp().getRequest().user?.id
}
});
// documents.controller.ts
@Get(':id')
@CheckPermission({ resource: 'document', action: 'view', resourceId: (req) => req.params.id })
findOne(@Param('id') id: string) {
return this.documentsService.findOne(id);
}The toolkit offers flexible ways to connect to your Permify instance.
import {
createPermifyClient,
clientOptionsFromEnv
} from "@permify-toolkit/core";
// Reads from PERMIFY_ENDPOINT, PERMIFY_INSECURE, PERMIFY_TLS_CERT, etc.
const client = createPermifyClient(clientOptionsFromEnv());Supported environment variables:
PERMIFY_ENDPOINT- Permify server endpoint (e.g.,localhost:3478)PERMIFY_INSECURE- Use insecure connection (true/false)PERMIFY_TLS_CERT- Path to TLS certificate filePERMIFY_TLS_KEY- Path to TLS key filePERMIFY_TLS_CA- Path to CA certificate filePERMIFY_AUTH_TOKEN- Permify access token (when using interceptor)
You can also use a custom prefix:
// Reads from MY_APP_ENDPOINT, MY_APP_INSECURE, etc.
const client = createPermifyClient(clientOptionsFromEnv("MY_APP_"));import * as fs from "fs";
import { createPermifyClient } from "@permify-toolkit/core";
const client = createPermifyClient({
endpoint: "permify.internal:3478",
insecure: false,
tls: {
cert: fs.readFileSync("cert.pem"),
key: fs.readFileSync("key.pem"),
ca: fs.readFileSync("ca.pem")
},
interceptor: { authToken: "YOUR_TOKEN" },
timeoutMs: 60000
});Define your connection, schema, and tenant once in permify.config.ts and share it across CLI and NestJS:
// permify.config.ts
import {
defineConfig,
schema,
entity,
relation,
permission
} from "@permify-toolkit/core";
export default defineConfig({
tenant: "t1",
client: { endpoint: "localhost:3478", insecure: true },
schema: schema({
user: entity({}),
document: entity({
relations: { owner: relation("user") },
permissions: { edit: permission("owner") }
})
})
});Then use it in your NestJS app — no client duplication, no env redefinition:
PermifyModule.forRoot({
configFile: true,
resolvers: {
subject: (ctx) => ctx.switchToHttp().getRequest().user?.id
}
});And with the CLI (tenant from config, no flag needed):
permify-toolkit schema push
permify-toolkit relationships seed --file-path ./data/relationships.jsonSee the individual package READMEs for full documentation.
pnpm testTo run specific tests, you can use the helper scripts in packages/core (currently tests are only in core, PRs are welcome adding more tests for rest packages):
# Run a specific file
pnpm test:file client.spec.ts
# Run a specific test group
pnpm test:group "Client Creation"
# Run tests matching a title
pnpm test:grep "should create a client"Alternatively, you can pass arguments directly to pnpm test:
pnpm test -- --files client.spec.tsWe're actively working on expanding the toolkit. Here's what's coming:
- Authorization guards for NestJS package
- Full-stack example app (frontend + NestJS backend)
- Release v1.0.0 and publish to npm
- Multi permission checks (AND + OR logic)
- Docs
- Testing utilities — mock Permify client and test helpers for unit testing authorization logic
- Permission result caching — in-memory (and optionally Redis-backed) cache to reduce gRPC round-trips
- Schema validation CLI command — lint and validate schema syntax before pushing to Permify
- Relationship query CLI commands — list, inspect, and export existing relationships from a tenant
- Express.js / Fastify middleware — permission-check middleware for non-NestJS backends
- GraphQL support —
@CheckPermissiondirective and guards for NestJS GraphQL resolvers - ABAC helpers — high-level utilities for attribute-based access control rules
- OpenTelemetry tracing — structured spans and metrics for permission checks and schema operations
- Schema diff CLI command — preview what will change before pushing a schema update
- Multi-tenant CLI management — create, list, and delete tenants directly from the CLI
Have ideas? Open an issue or start a discussion!
We love contributions from the community! Whether you're fixing bugs, adding features, or improving documentation, your help is welcome.
Please see our Contributing Guidelines for:
- Code of conduct
- Development workflow
- How to submit PRs
- Testing requirements
This project is licensed under the MIT License. See the LICENSE file for details.
Built with ❤️ by Nikhil Kumar Choudhary aka thisisnkc for the Permify community.
If you find this toolkit helpful, please consider:
- ⭐ Starring the repo, it helps others discover permify-toolkit
- Reporting bugs
- Suggesting features
- Improving documentation
- Adding more tests
Questions? Open an issue or reach out to the maintainers. We're here to help!
