Omnibase

Objects & Namespaces

Object types, built-in defaults, and defining custom objects

Objects & Namespaces

In the Omnibase permission system, every namespace is an object type — a distinct kind of thing that can own, be acted upon, or be the subject of a permission check.

Built-in Objects

Omnibase ships with these object types by default. They are defined in your project's omnibase/permissions/ directory.

User

Users who authenticate via sessions. User is the primary subject type — the "who" in a permission check. It has no relations defined on it; it exists only to be the target of relations on other objects.

// omnibase/permissions/tenants.ts
export class User implements Namespace {}

Tenant

The organizational container. Each tenant has its own members, roles, and data isolation. Tenant permissions are auto-scoped from the user's active session.

export class Tenant implements Namespace {
  related: {
    /** @group Tenant Administration */
    can_delete_tenant: User[];

    /** @group User Management */
    can_invite_user: User[];

    /** @group User Management */
    can_update_user_role: User[];

    /** @group User Management */
    can_remove_user: User[];

    /** @group User Management */
    can_view_users: User[];

    /** @group Roles & Permissions */
    can_create_roles: User[];

    /** @group Roles & Permissions */
    can_update_roles: User[];

    /** @group Roles & Permissions */
    can_delete_roles: User[];
  };

  permits = {
    invite_user: (ctx): boolean =>
      this.related.can_invite_user.includes(ctx.subject),
    delete_tenant: (ctx): boolean =>
      this.related.can_delete_tenant.includes(ctx.subject),
    // ... etc
  };
}

StorageObject

A file uploaded to object storage. Has its own owner-based permissions with read, delete, and make_public relations.

// omnibase/permissions/storage.ts
export class StorageObject implements Namespace {
  related: {
    /** @hidden */
    owner: User[];
    can_read: User[];
    can_delete: User[];
    can_make_public: User[];
    /** @hidden */
    tenant: Tenant[];
  };

  permits = {
    read: (ctx): boolean =>
      this.related.owner.includes(ctx.subject) ||
      this.related.can_read.includes(ctx.subject),
    delete: (ctx): boolean =>
      this.related.owner.includes(ctx.subject) ||
      this.related.can_delete.includes(ctx.subject),
    make_public: (ctx): boolean =>
      this.related.owner.includes(ctx.subject) ||
      this.related.can_make_public.includes(ctx.subject),
  };
}

Defining Custom Objects

Create a new namespace class to define a custom object type. The class must implement Namespace and can define related relations and a permits block.

// omnibase/permissions/agents.ts
import { Context, Namespace } from "./types";

export class Agent implements Namespace {}

// omnibase/permissions/codebases.ts
import { Agent, Context, Namespace, Tenant, User } from "./types";

export class Codebase implements Namespace {
  related: {
    /** @hidden */
    tenant: Tenant[];

    /** @group Codebase Access */
    can_edit: (User | Agent)[];

    /** @group Codebase Access */
    can_push: (User | Agent)[];

    /** @group Codebase Access */
    can_view: (User | Agent)[];
  };

  permits = {
    edit: (ctx): boolean =>
      this.related.can_edit.includes(ctx.subject),
    push: (ctx): boolean =>
      this.related.can_push.includes(ctx.subject),
    view: (ctx): boolean =>
      this.related.can_view.includes(ctx.subject),
  };
}

See the full OmniGit Example for a complete walkthrough with two agent scoping patterns.

JSDoc Annotations

Every relation in a related block can carry JSDoc annotations. These provide metadata for the UI and role system — they are parsed by the API and consumed by frontend components.

AnnotationPurposeExample
@groupPrimary UI grouping@group User Management
@subGroupSecondary grouping within a group@subGroup Role Assignment
@displayNameHuman-readable label@displayName Invite Users
@roleSuggested default role(s)@role owner
@hiddenHide from UI (internal relations)@hidden
/**
 * @group User Management
 * @subGroup Role Assignment
 * @displayName Update User Roles
 * @role owner
 * @role admin
 */
can_update_user_role: User[];

The @role annotation serves as a suggestion when creating roles in the UI. The @hidden annotation is essential for relations used only for permission traversal (like tenant: Tenant[] or owner: User[]) — they should never appear in a role-editing UI.

Next

Relations are how objects connect — Relations & Traversal explains how to chain permissions through intermediate objects.

On this page