Banata

Organizations & RBAC

Roles & Permissions

Define custom roles, create permissions, and control what users can do within organizations.

Banata uses a super_admin-first RBAC model. Every project starts with one default role (super_admin) and a set of built-in permissions. From there, you create custom roles and permissions that match your application's needs.


The Default Role: super_admin

When your project is created, Banata seeds a single role called super_admin. This role has full access to every built-in permission and serves as the starting point for your authorization model.

Key facts about super_admin:

  • It is automatically assigned to the creator of each new organization.
  • It cannot be deleted or edited.
  • The slug super_admin is reserved — you cannot reuse it for a custom role.

Think of super_admin as the root account for each organization. You should keep its assignment limited to trusted org owners.


Permission Model

Permissions in Banata are project-scoped. That means the permission catalog you define is shared across all organizations in your project. Individual organizations do not maintain separate permission lists.

Permissions fall into two categories:

Built-in Permissions

These are seeded automatically when your project is created. They cover core platform operations and cannot be deleted or edited. Examples include:

  • organization.read
  • member.invite
  • role.create
  • api_key.create

The super_admin role is linked to every built-in permission by default.

Custom Permissions

These are the permissions you create for your own application logic. Use the resource.action naming convention to keep things consistent. Examples:

  • document.publish
  • workspace.archive
  • invoice.approve
  • report.export

You can create, update, and delete custom permissions at any time from the dashboard or the SDK.


Creating Roles and Permissions from the Dashboard

The dashboard gives you a visual way to manage your entire authorization model. Follow these steps:

Step 1: Create Your Permissions

  1. Open your project in the dashboard.
  2. Navigate to Authorization > Permissions.
  3. Click Create Permission.
  4. Enter a slug using the resource.action format (for example, employee.read).
  5. Give it a human-readable name and optional description.
  6. Repeat for each permission your app needs.

For example, an HR application might create:

  • employee.read
  • employee.manage
  • leave.approve
  • payroll.read

Step 2: Create Your Roles

  1. Navigate to Authorization > Roles.
  2. Click Create Role.
  3. Enter a slug (for example, hr_manager), a display name, and an optional description.

Step 3: Assign Permissions to Roles

  1. From the roles list, find the role you just created and click Manage Permissions.
  2. You will see the full list of available permissions (both built-in and custom).
  3. Toggle on the permissions that this role should grant.
  4. Save your changes.

Step 4: Assign Roles to Members

  1. Open the organization member screen.
  2. Select a member and assign them the appropriate role slug.

Creating Roles and Permissions via the SDK

You can also manage roles and permissions programmatically using the Banata SDK.

Initialize the Client

typescript
import { BanataAuth } from "@banata-auth/sdk";
 
const banata = new BanataAuth({
  apiKey: "sk_live_...",
  baseUrl: "https://auth.banata.dev",
});

Manage Roles

typescript
// List all roles in your project
const roles = await banata.rbac.listRoles();
 
// Create a new role
const role = await banata.rbac.createRole({
  name: "HR Manager",
  slug: "hr_manager",
  description: "Can manage employees and approve leave requests",
  permissions: ["employee.manage", "leave.approve", "employee.read"],
});
 
// Update a role (e.g., add more permissions)
const updatedRole = await banata.rbac.updateRole({
  id: role.id,
  permissions: ["employee.manage", "leave.approve", "employee.read", "payroll.read"],
});
 
// Delete a custom role
await banata.rbac.deleteRole(role.id);

Manage Permissions

typescript
// List all permissions in your project
const permissions = await banata.rbac.listPermissions();
 
// Create a new permission
const permission = await banata.rbac.createPermission({
  name: "Publish Document",
  slug: "document.publish",
  description: "Allows publishing draft documents",
});
 
// Update a permission
const updatedPermission = await banata.rbac.updatePermission({
  id: permission.id,
  name: "Publish Document",
  slug: "document.publish",
  description: "Allows publishing draft documents to the public site",
});
 
// Delete a custom permission
await banata.rbac.deletePermission(permission.id);

Assigning and Revoking Roles

Roles are assigned at the organization level. A user can hold a role within a specific organization.

typescript
// Assign a role to a user within an organization
await banata.rbac.assignRole({
  organizationId: "org_01...",
  userId: "usr_01...",
  role: "hr_manager",
});
 
// Revoke a user's role within an organization
await banata.rbac.revokeRole({
  organizationId: "org_01...",
  userId: "usr_01...",
  role: "hr_manager",
});

Permission Checks

Use permission checks to determine whether a user is allowed to perform a specific action. You can pass the permission as a { resource, action } object.

Check a Single Permission

typescript
const canPublish = await banata.rbac.checkPermission({
  userId: "usr_01...",
  permission: { resource: "document", action: "publish" },
  organizationId: "org_01...",
});
 
if (canPublish.allowed) {
  // proceed with the action
}

Check Multiple Permissions

Use the operator field to require that the user has all of the listed permissions:

typescript
const canManageHR = await banata.rbac.checkPermissions({
  userId: "usr_01...",
  permissions: [
    { resource: "employee", action: "manage" },
    { resource: "leave", action: "approve" },
  ],
  operator: "all",
  organizationId: "org_01...",
});

Best Practices

  1. Keep super_admin limited. Only assign it to trusted organization owners. Create purpose-built roles for everyone else.

  2. Use capability-based role names. Names like hr_manager, billing_viewer, or content_editor communicate intent better than generic titles like admin or user.

  3. Keep permissions granular. Stick to the resource.action slug format. Fine-grained permissions like invoice.approve and invoice.read give you more flexibility than a broad invoice.manage.

  4. Always enforce checks server-side. Client-side checks are useful for hiding UI elements, but your server (or serverless functions) should be the final authority on whether an action is allowed.

  5. Create permissions before roles. Permissions are the building blocks. Define your permission catalog first, then compose roles from those permissions.


Next Steps

  • Organizations Overview — Learn how organizations work and how members are managed.
  • API Keys — Set up API key authentication for your project.
  • Getting Started — Return to the setup guide if you haven't integrated Banata yet.