Official Node.js SDK for Permissio.io - Authorization as a Service.
npm install permissio
# or
yarn add permissio
# or
pnpm add permissioimport { Permissio } from 'permissio';
// Initialize the SDK
const permissio = new Permissio({
token: 'permis_key_your_api_key_here',
projectId: 'your-project-id',
environmentId: 'your-environment-id',
});
// Check permissions
const allowed = await permissio.check({
user: 'user@example.com',
action: 'read',
resource: 'document',
});
if (allowed) {
console.log('Access granted!');
} else {
console.log('Access denied!');
}import { Permissio } from 'permissio';
const permissio = new Permissio({
// Required: Your API key
token: 'permis_key_your_api_key_here',
// Optional: API base URL (defaults to https://api.permissio.io)
apiUrl: 'https://api.permissio.io',
// Optional: Project and Environment IDs
projectId: 'your-project-id',
environmentId: 'your-environment-id',
// Optional: Enable debug logging
debug: false,
// Optional: Request timeout in ms (default: 30000)
timeout: 30000,
// Optional: Number of retry attempts (default: 3)
retryAttempts: 3,
// Optional: Throw errors or return false (default: true)
throwOnError: true,
// Optional: Custom headers
customHeaders: {
'X-Custom-Header': 'value',
},
});const allowed = await permissio.check({
user: 'user@example.com',
action: 'read',
resource: 'document',
});const allowed = await permissio.check({
user: 'user@example.com',
action: 'edit',
resource: {
type: 'document',
key: 'doc-123',
},
});const allowed = await permissio.check({
user: 'user@example.com',
action: 'delete',
resource: 'document',
tenant: 'acme-corp',
});const allowed = await permissio.check({
user: {
key: 'user@example.com',
attributes: {
department: 'engineering',
level: 'senior',
},
},
action: 'approve',
resource: 'expense_report',
});const response = await permissio.checkWithDetails({
user: 'user@example.com',
action: 'read',
resource: 'document',
});
console.log(response.allowed); // boolean
console.log(response.reason); // string (optional)
console.log(response.debug); // debug info (when debug enabled)const results = await permissio.bulkCheck({
checks: [
{ user: 'user1@example.com', action: 'read', resource: 'document' },
{ user: 'user1@example.com', action: 'write', resource: 'document' },
{ user: 'user2@example.com', action: 'read', resource: 'document' },
],
});
results.results.forEach(({ request, response }) => {
console.log(`${request.user} ${request.action} ${request.resource}: ${response.allowed}`);
});try {
await permissio.checkAndThrow({
user: 'user@example.com',
action: 'delete',
resource: 'document',
});
// Access granted, continue with operation
} catch (error) {
// Access denied
console.error(error.message);
}const user = await permissio.api.users.create({
key: 'user@example.com',
email: 'user@example.com',
firstName: 'John',
lastName: 'Doe',
attributes: {
department: 'engineering',
},
});const user = await permissio.api.users.sync({
key: 'user@example.com',
email: 'user@example.com',
firstName: 'John',
lastName: 'Doe',
});await permissio.syncUser({
key: 'user@example.com',
email: 'user@example.com',
firstName: 'John',
lastName: 'Doe',
roles: [
{ role: 'admin', tenant: 'acme-corp' },
{ role: 'viewer' },
],
});const users = await permissio.api.users.list({
page: 1,
perPage: 10,
search: 'john',
});const roles = await permissio.api.users.getRoles('user@example.com');await permissio.api.users.assignRole('user@example.com', 'admin', 'acme-corp');const tenant = await permissio.api.tenants.create({
key: 'acme-corp',
name: 'Acme Corporation',
description: 'Main organization',
attributes: {
plan: 'enterprise',
},
});const users = await permissio.api.tenants.getUsers('acme-corp');await permissio.api.tenants.addUser('acme-corp', 'user@example.com');const role = await permissio.api.roles.create({
key: 'editor',
name: 'Editor',
description: 'Can edit documents',
permissions: ['document:read', 'document:write'],
});await permissio.api.roles.addPermission('editor', 'document:delete');// Create a role that extends another
await permissio.api.roles.create({
key: 'admin',
name: 'Admin',
extends: ['editor'],
permissions: ['document:delete', 'user:manage'],
});const resource = await permissio.api.resources.create({
key: 'document',
name: 'Document',
actions: ['read', 'write', 'delete', 'share'],
});const instance = await permissio.api.resources.createInstance({
key: 'doc-123',
resourceType: 'document',
tenant: 'acme-corp',
attributes: {
title: 'My Document',
owner: 'user@example.com',
},
});await permissio.api.roleAssignments.assign({
user: 'user@example.com',
role: 'admin',
tenant: 'acme-corp',
});await permissio.api.roleAssignments.assign({
user: 'user@example.com',
role: 'editor',
resource: 'document',
resourceInstance: 'doc-123',
});const result = await permissio.api.roleAssignments.bulkAssign([
{ user: 'user1@example.com', role: 'viewer', tenant: 'acme-corp' },
{ user: 'user2@example.com', role: 'editor', tenant: 'acme-corp' },
{ user: 'user3@example.com', role: 'admin', tenant: 'acme-corp' },
]);
console.log(`Created: ${result.created}, Failed: ${result.failed}`);const hasRole = await permissio.api.roleAssignments.hasRole(
'user@example.com',
'admin',
{ tenant: 'acme-corp' }
);const permissions = await permissio.getPermissions({
user: 'user@example.com',
tenant: 'acme-corp',
});
console.log(permissions.roles); // ['admin', 'editor']
console.log(permissions.permissions); // ['document:read', 'document:write', ...]import { Permissio, PermissioApiError } from 'permissio';
const permissio = new Permissio({
token: 'permis_key_...',
throwOnError: true, // default
});
try {
await permissio.api.users.get('nonexistent-user');
} catch (error) {
if (error instanceof PermissioApiError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Error Code:', error.code);
console.error('Details:', error.details);
}
}const permissio = new Permissio({
token: 'permis_key_...',
throwOnError: false,
});
// Will return false instead of throwing
const allowed = await permissio.check({
user: 'user@example.com',
action: 'read',
resource: 'document',
});This SDK is written in TypeScript and provides full type definitions.
import {
Permis,
IPermisConfig,
ICheckRequest,
ICheckResponse,
IUserCreate,
IUserRead,
IRoleAssignmentCreate,
} from 'permissio';
const config: IPermisConfig = {
token: 'permis_key_...',
projectId: 'my-project',
environmentId: 'production',
};
const permissio = new Permissio(config);
const request: ICheckRequest = {
user: 'user@example.com',
action: 'read',
resource: 'document',
};
const response: ICheckResponse = await permissio.checkWithDetails(request);import { Permissio } from 'permissio';
import express from 'express';
const permissio = new Permissio({
token: process.env.PERMIS_API_KEY!,
projectId: process.env.PERMIS_PROJECT_ID!,
environmentId: process.env.PERMIS_ENVIRONMENT_ID!,
});
// Middleware factory
function requirePermission(action: string, getResource: (req: express.Request) => string) {
return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
const userId = req.user?.id; // Assuming user is attached to request
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
const allowed = await permissio.check({
user: userId,
action,
resource: getResource(req),
});
if (!allowed) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
}
// Usage
app.get(
'/documents/:id',
requirePermission('read', (req) => ({ type: 'document', key: req.params.id })),
async (req, res) => {
// Handle request
}
);import { Injectable, CanActivate, ExecutionContext, SetMetadata } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Permissio } from 'permissio';
export const PERMISSION_KEY = 'permission';
export const RequirePermission = (action: string, resource: string) =>
SetMetadata(PERMISSION_KEY, { action, resource });
@Injectable()
export class PermisGuard implements CanActivate {
constructor(
private reflector: Reflector,
private permis: Permis
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const permission = this.reflector.get(PERMISSION_KEY, context.getHandler());
if (!permission) return true;
const request = context.switchToHttp().getRequest();
const userId = request.user?.id;
if (!userId) return false;
return this.permissio.check({
user: userId,
action: permission.action,
resource: permission.resource,
});
}
}MIT
- Documentation: https://docs.permissio.io
- Issues: GitHub Issues
- Email: support@permissio.io