Omnibase

Permissions Overview

Understanding the object-relationship permission model

Permissions Overview

Omnibase uses a relationship-based access control (ReBAC) system. Instead of rigid roles or complex policies, permissions are modeled as relations between objects in a graph.

The Core Idea

Every namespace is an object type. Objects relate to each other through named relations. A permission check asks one question:

Does subject S have relation R on object O?

(User, user_abc, can_invite_user, Tenant, tenant_xyz)

These relations form a graph that you can traverse. A user can act on a tenant directly, or on all projects within a tenant through chained relations.

Built-in Defaults

Omnibase ships with these object types out of the box:

ObjectPurpose
UserEnd user — acts as a subject in permission checks
TenantOrganizational container — members, owners, permissions
StorageObjectA file in object storage

Why Relations, Not Roles

Traditional RBAC gives users flat roles with fixed permission sets. ReBAC gives you:

  • Fine-grained control — grant a permission on a specific resource, not "all resources"
  • Inheritance through traversal — grant at the tenant level and cascade to all resources
  • Multiple subject types — both Users and API keys can hold permissions
  • Per-resource ownership — each object has its own access rules

Permissions Sub-Pages

Quick Example

// Check if a user can invite others to a tenant
const { data } = await permissionsApi.checkPermission({
  checkPermissionRequest: {
    namespace: 'Tenant',
    object: tenantId,
    relation: 'can_invite_user',
    subjectId: userId,
    subjectNamespace: 'User',
  },
});
result, _, err := client.CheckPermission(ctx).CheckPermissionRequest(omnibase.CheckPermissionRequest{
    Namespace: "Tenant",
    Object:    tenantId,
    Relation:  "can_invite_user",
    SubjectSet: omnibase.SubjectSetRequest{
        Namespace: "User",
        Object:    userId,
    },
}).Execute()

On this page