Built-in Roles in Kaneo: Viewer, Member, Admin, and Owner Permissions Explained

Kaneo defines four built-in workspace roles—Viewer, Member, Admin, and Owner—in packages/permissions/src/index.ts, with permissions ranging from read-only project access to full workspace management and deletion capabilities.

Kaneo implements a hierarchical role-based access control (RBAC) system using four distinct permission levels. These roles extend the base organization statements from better-auth and are instantiated using the createAccessControl factory to govern access across projects, tasks, labels, and workspace settings.

The Four Built-in Kaneo Roles and Their Capabilities

Kaneo’s permission model is defined in packages/permissions/src/index.ts, where each role is created using ac.newRole method calls at specific line numbers. The following sections detail the granular permissions assigned to each built-in role.

Viewer (Line 19)

The Viewer role provides minimal read-only access suitable for stakeholders who need visibility without modification rights.

  • Projects: read
  • Tasks: read
  • Labels: read
  • Workspace: read

Defined at line 19 via ac.newRole, this role cannot create, update, or delete any resources within the workspace.

Member (Line 27)

The Member role serves as the standard contributor level, enabling active participation in project work while restricting destructive actions and administrative settings.

  • Projects: create, read
  • Tasks: create, read, update
  • Labels: create, read, update, delete
  • Workspace: read

As implemented in packages/permissions/src/index.ts at line 27, Member can create and modify most objects but cannot delete projects or manage workspace-level configurations.

Admin (Line 35)

The Admin role grants comprehensive management capabilities over content and users while restricting the most destructive workspace actions.

  • Projects: create, read, update, delete, share
  • Tasks: create, read, update, delete, assign
  • Labels: create, read, update, delete
  • Workspace: read, update, manage_settings

Defined at line 35, Admin has full control over projects, tasks, and labels, including the ability to assign tasks to users and share projects. Admins can modify workspace settings but cannot delete the workspace itself.

Owner (Line 43)

The Owner role possesses unrestricted access, including the unique ability to delete the entire workspace.

  • Projects: create, read, update, delete, share
  • Tasks: create, read, update, delete, assign
  • Labels: create, read, update, delete
  • Workspace: read, update, delete, manage_settings

This role is instantiated at line 43 with identical permissions to Admin plus the critical delete action on the workspace resource, making it the only role capable of permanent workspace removal.

How Roles Are Defined in the Source Code

According to the Kaneo source code, all built-in roles share base statements imported from better-auth/plugins/organization/access (lines 3-7 of packages/permissions/src/index.ts). The system uses the createAccessControl(statement) factory to generate the access control object, then extends these base permissions through sequential ac.newRole calls.

Each role definition aggregates specific actions across four resource types: project, task, label, and workspace. The builtInRoles object exports these definitions for consumption throughout the application.

Checking Role Permissions Programmatically

The @kaneo/permissions package provides utilities to verify capabilities at runtime and enforce authorization in API handlers.

Verify Specific Capabilities

Use the can method on any built-in role to check specific permissions:

import { builtInRoles } from "@kaneo/permissions";

// Check if a member can delete a task
const canDeleteTask = builtInRoles.member.can("task", "delete"); // returns false

// Check if an admin can assign a task
const canAssignTask = builtInRoles.admin.can("task", "assign"); // returns true

Enforce Permissions in API Middleware

The requireWorkspacePermission middleware integrates with Kaneo’s routing system to protect endpoints:

import { requireWorkspacePermission } from "@kaneo/permissions";

export const deleteProject = createRoute({
  method: "delete",
  path: "/projects/:id",
  middleware: [requireWorkspacePermission("project", "delete")],
})(async (c) => {
  // Handler logic executes only for Admin or Owner roles
});

This middleware rejects requests from Viewer and Member roles, allowing only Admin and Owner to execute project deletions.

Audit All Role Capabilities

To programmatically inspect the permission matrix:

import { builtInRoles } from "@kaneo/permissions";

for (const [name, role] of Object.entries(builtInRoles)) {
  console.log(`${name} can:`)
  for (const [resource, actions] of Object.entries(role.statements)) {
    console.log(`  ${resource}: ${actions.join(", ")}`);
  }
}

Summary

  • Viewer: Read-only access defined at line 19; cannot modify any resources.
  • Member: Content creation and editing rights defined at line 27; cannot delete projects or manage workspace settings.
  • Admin: Full content management including task assignment and project sharing defined at line 35; can modify workspace settings but not delete the workspace.
  • Owner: Unrestricted access defined at line 43; the only role capable of deleting the workspace.

The permission system is tested in packages/permissions/src/index.test.ts and validated through integration tests in tests/api-integration/workspace-rbac.test.ts.

Frequently Asked Questions

What is the difference between Admin and Owner roles in Kaneo?

The Owner role includes the delete action on the workspace resource, while the Admin role does not. Both roles share identical permissions for projects, tasks, and labels—including sharing projects and assigning tasks—but only Owner can permanently delete the workspace itself.

Can I create custom roles beyond the four built-in roles?

The current implementation in packages/permissions/src/index.ts exports a fixed builtInRoles object containing only Viewer, Member, Admin, and Owner. While the underlying createAccessControl system supports additional roles via ac.newRole, extending beyond these four would require modifying the permissions package source code.

How do I check if a user has permission to perform a specific action?

Import builtInRoles from @kaneo/permissions and use the can(resource, action) method. For example, builtInRoles.admin.can("project", "share") returns a boolean indicating whether that role permits project sharing.

Where are the permission tests located in the Kaneo repository?

Unit tests for role definitions reside in packages/permissions/src/index.test.ts, while end-to-end validation of RBAC behavior is implemented in tests/api-integration/workspace-rbac.test.ts. The package configuration for these tests is found in packages/permissions/vitest.config.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →