
This client makes it easy to interact with Permify from your Node.js application, providing type-safe access to Permify's authorization capabilities.
- Full TypeScript support
- Promise-based API
- Support for all Permify gRPC endpoints
- Built-in error handling
- Interceptor support for authentication and logging
- Streaming support for real-time updates
Use npm to install:
npm install @permify/permify-node
Use yarn to install (Please be aware that Yarn versions greater than v1.10.0 and less than v2 are not supported):
yarn add @permify/permify-node
- Node.js 14.x or later
- A running instance of Permify server (local or cloud)
- Basic understanding of Permify's authorization model
First, create a new client instance to connect to your Permify server:
import * as permify from "@permify/permify-node";
const client = permify.grpc.newClient({
endpoint: "localhost:3478", // Replace with your Permify server URL
cert: undefined, // Optional: SSL certificate
insecure: true, // Set to false in production
timeout: 5000, // Request timeout in milliseconds
});
import * as permify from "@permify/permify-node";
const client = permify.grpc.newClient({
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
});
client.tenancy
.create({
id: "t1",
name: "Tenant 1",
})
.then((response) => {
console.log(response);
// handle response
});
Define your authorization model using Permify's schema language. Here's a more comprehensive example:
import * as permify from "@permify/permify-node";
const client = permify.grpc.newClient({
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
});
let schema = `
entity user {}
entity document {
relation viewer @user
action view = viewer
}
`;
// Write the schema
client.tenancy
.create({
tenantId: "t1",
schema: schema,
})
.then((response) => {
// handle response
});
Create relationships between entities to define access rules. Here are some common patterns:
import * as permify from "@permify/permify-node";
const client = permify.grpc.newClient({
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
});
client.relationship
.write({
tenantId: "t1",
metadata: {
schemaVersion: "",
},
tuples: [
{
entity: {
type: "document",
id: "1",
},
relation: "viewer",
subject: {
type: "user",
id: "1",
},
},
],
})
.then((response) => {
// handle response
});
Verify if a user has a specific permission on a resource. Here are different ways to perform checks:
import * as permify from "@permify/permify-node";
const client = permify.grpc.newClient({
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
});
client.permission
.check({
tenantId: "t1",
metadata: {
snapToken: "",
schemaVersion: "",
depth: 20,
},
entity: {
type: "document",
id: "1",
},
permission: "view",
subject: {
type: "user",
id: "3",
},
})
.then((response) => {
if (response.can === permify.grpc.base.CheckResult.CHECK_RESULT_ALLOWED) {
console.log("RESULT_ALLOWED");
} else {
console.log("RESULT_DENIED");
}
});
Subscribe to permission changes in real-time:
import * as permify from "@permify/permify-node";
function main() {
const client = permify.grpc.newClient({
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
});
let res = client.permission.lookupEntityStream({
tenantId: "t1",
metadata: {
snapToken: "",
schemaVersion: "",
depth: 20,
},
entityType: "document",
permission: "view",
subject: {
type: "user",
id: "1",
},
});
handle(res);
}
async function handle(
res: AsyncIterable<permify.grpc.payload.PermissionLookupEntityStreamResponse>
) {
for await (const response of res) {
// response.entityId
}
}
import * as permify from "@permify/permify-node";
const client = new permify.grpc.newClient(
{
endpoint: "localhost:3478",
cert: undefined,
insecure: true,
},
permify.grpc.newAccessTokenInterceptor("YOUR_TOKEN")
);
import * as permify from "@permify/permify-node";
import fs from "fs";
const cert = fs.readFileSync("path/to/cert.pem");
const client = new permify.grpc.newClient(
{
endpoint: "localhost:3478",
cert: cert,
insecure: true,
},
permify.grpc.newAccessTokenInterceptor("YOUR_TOKEN")
);
All API calls return Promises that can be handled with try/catch:
try {
const response = await client.tenancy.create({
id: "t1",
name: "Production Tenant",
});
console.log("Tenant created:", response);
} catch (error) {
console.error("Error creating tenant:", error);
// Handle specific error types
if (error.code === grpc.status.ALREADY_EXISTS) {
console.log("Tenant already exists");
}
}
Contributions are welcome! Please read our contributing guidelines to get started.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Join our Discord channel for issues, feature requests, feedbacks or anything else. We love to talk about authorization and access control ❤️