Skip to main content

Organizations & teams

IdentSphere's identity model is org-shaped. Every user belongs to exactly one organization (v1 limitation; many-to-many lands in v2). Permissions are evaluated within an organization.

Data model

organizations

│ 1:many

organization_memberships ◄────── (user, organization, role)

│ many:1

users

A user's organization_id column is their "home" org. Their role in that org is read from organization_memberships, NOT from users.role — the membership row is authoritative.

Roles

The default RBAC matrix ships with these roles:

RoleIndicative permissions
ownerEverything (cannot be granted via invitation; only via ownership transfer)
adminOrg settings, member management, billing
billingBilling only
memberRead org, contribute to projects
viewerRead-only

These are configurable via RbacConfig::default_matrix() — fork the matrix and pass your own when constructing Authorizer.

Owners

Org-scoped routes

Every endpoint under /v1/orgs/:org_id/* is guarded by require_org_match: the path's :org_id must equal the caller's auth.organization_id. Cross-org access returns 403.

Authorization

The Authorizer evaluates a Permission against the caller's role:

state
.authorizer
.authorize(&auth, &Permission::MembersInvite)
.await
.map_err(RouteError::from)?;

The permission set is defined in identsphere_core::rbac::Permission. Map your own host permissions onto the same machinery by registering them in RbacConfig.

Slug

organizations.slug is a globally unique URL-safe identifier. Used in:

  • Email invite copy ("you've been invited to join Acme Co.")
  • Optionally, your own URL routing (/o/{slug}/projects)

The SDK enforces [a-z0-9-]{1,100} and global uniqueness. Slugs can be provided at registration time or auto-derived from the name.

Soft delete

organizations.deleted_at is for host-implemented soft-delete; the SDK itself never deletes orgs. Build your own teardown flow if you need one.

Settings

organizations.settings is a free-form JSONB column the SDK never reads. Use it for host-app settings (theme, default project, etc.).

Audit

  • auth.register creates an org as a side effect; the audit entry's resource is the new org id.
  • members.invited, members.role_changed, members.removed, members.invitation_accepted track membership lifecycle.