Skip to Content

Permissions

TL;DR

The PermissionManager in @cmdop/bot controls access to your bot with per-user, per-machine granularity. It uses the same five permission levels as the Python SDK: NONE, READ, EXECUTE, FILES, and ADMIN. Supports identity linking across Telegram, Discord, and Slack channels, wildcard machine grants, and custom persistent stores (JSON file or database). Integrates directly with IntegrationHub.

Control access to your CMDOP bot with the built-in permission system. Per-user, per-machine granularity with identity linking across channels.

What permission levels are available?

LevelValueAccess
NONE0No access
READ1List directories, read files
EXECUTE2Run shell commands
FILES3Write and delete files
ADMIN4Full access to all machines and commands

How do I use the PermissionManager?

// Import PermissionManager and PermissionLevel from @cmdop/bot import { PermissionManager, PermissionLevel } from '@cmdop/bot'; // Create a new permission manager instance (in-memory store by default) const permissions = new PermissionManager(); // Add admin β€” grants full access to everything across all machines permissions.addAdmin('telegram:123456789'); // Grant EXECUTE permission for a specific user on a specific machine permissions.grant({ identity: 'discord:987654321', machine: 'prod-server', level: PermissionLevel.EXECUTE, }); // Grant READ-only access to another user on a different machine permissions.grant({ identity: 'slack:U12345678', machine: 'logs-server', level: PermissionLevel.READ, });

How do I integrate permissions with IntegrationHub?

// Import everything needed for hub + permissions + channel import { IntegrationHub, PermissionManager, PermissionLevel } from '@cmdop/bot'; import { TelegramChannel } from '@cmdop/bot/telegram'; // Set up permissions before creating the hub const permissions = new PermissionManager(); permissions.addAdmin('telegram:123456789'); permissions.grant({ identity: 'telegram:987654321', machine: 'dev-server', level: PermissionLevel.EXECUTE, }); // Pass the permission manager to the hub via the permissions option const hub = new IntegrationHub({ apiKey: process.env.CMDOP_API_KEY!, permissions, }); // Add channel β€” hub will automatically check permissions before running commands hub.addChannel(new TelegramChannel({ token: process.env.TELEGRAM_BOT_TOKEN!, })); hub.start();

What is the identity format?

Format: {channel}:{userId}

ChannelFormatExample
Telegramtelegram:{userId}telegram:123456789
Discorddiscord:{userId}discord:987654321
Slackslack:{userId}slack:U12345678

Link identities across channels so users have the same permissions everywhere:

// First, grant admin to a Telegram user permissions.addAdmin('telegram:123456789'); // Link their Discord and Slack accounts to the same Telegram identity permissions.linkIdentity('telegram:123456789', 'discord:111222333'); permissions.linkIdentity('telegram:123456789', 'slack:U99887766'); // Now discord:111222333 and slack:U99887766 also have admin access

How do I check permissions programmatically?

// Check if a user has permission to run a command on a machine const canRun = permissions.check({ identity: 'telegram:123456789', machine: 'my-server', command: 'shell', }); console.log(canRun); // true (admin has access to everything) // Check a user with no permissions const canRun2 = permissions.check({ identity: 'telegram:555555555', machine: 'prod-server', command: 'shell', }); console.log(canRun2); // false (no permission granted)

How do I enforce permissions with require()?

Throws PermissionDeniedError if permission denied:

// Import the error class for catching permission failures import { PermissionDeniedError } from '@cmdop/bot'; try { // require() throws PermissionDeniedError if the user lacks access permissions.require({ identity: 'telegram:999999999', machine: 'prod-server', command: 'shell', }); } catch (error) { // Handle the denied case (e.g., reply with an error message) if (error instanceof PermissionDeniedError) { console.log('Access denied:', error.message); } }

How do I use wildcard permissions?

// Grant EXECUTE access to all machines using the '*' wildcard permissions.grant({ identity: 'telegram:123456789', machine: '*', level: PermissionLevel.EXECUTE, });

How do I revoke permissions?

// Revoke a specific user's permission on a specific machine permissions.revoke({ identity: 'discord:987654321', machine: 'dev-server', }); // Remove admin status from a user permissions.removeAdmin('telegram:123456789');

How do I persist permissions with a custom store?

By default, permissions are stored in memory. Use a custom store for persistence:

// Import JsonFileStore for file-based persistence import { PermissionManager, JsonFileStore } from '@cmdop/bot'; // Create permission manager with JSON file store const permissions = new PermissionManager({ store: new JsonFileStore('./permissions.json'), }); // Permissions are automatically saved to and loaded from permissions.json

How do I implement a custom store interface?

// The PermissionStore interface requires load() and save() methods interface PermissionStore { load(): Promise<PermissionData>; save(data: PermissionData): Promise<void>; } // Example: implement a database-backed store class MyDatabaseStore implements PermissionStore { async load(): Promise<PermissionData> { // Load permission data from your database } async save(data: PermissionData): Promise<void> { // Save permission data to your database } } // Use your custom store with the permission manager const permissions = new PermissionManager({ store: new MyDatabaseStore(), });
Last updated on