NewWacht Bench is live — AI-assisted development for Wacht

useActiveTenancy() hook

useActiveTenancy() resolves the current active organization membership and workspace membership from the active sign-in in the session. It is the broadest “where am I scoped right now?” hook in the multi-tenancy layer.

Usage

The following example shows a basic usage of useActiveTenancy().

export default function ActiveTenancySummary() {  const { loading, orgMembership, workspaceMembership } = useActiveTenancy();  if (loading) {    return <p>Loading tenancy…</p>;  }  return (    <div>      <p>Organization: {orgMembership?.organization.name ?? 'None'}</p>      <p>Workspace: {workspaceMembership?.workspace.name ?? 'None'}</p>    </div>  );}

Return value

The hook returns the following fields and methods.

loading: boolean;
Whether the session, organization memberships, or workspace memberships are still loading.
orgMembership: OrganizationMembership | null;
Organization membership whose identifier matches the active sign-in in the session.
id?: string | undefined;
Organization-membership identifier.
organization?: Organization | undefined;
Organization attached to the active membership.
id?: string | undefined;
Organization identifier.
name?: string | undefined;
Organization name.
image_url?: string | undefined;
Organization image URL.
description?: string | undefined;
Organization description.
member_count?: number | undefined;
Organization member count.
enforce_mfa?: boolean | undefined;
Whether the organization enforces MFA.
enable_ip_restriction?: boolean | undefined;
Whether the organization uses IP restrictions.
user?: PublicUserData | undefined;
Public user data for the membership owner.
id?: string | undefined;
User identifier.
first_name?: string | undefined;
User first name.
last_name?: string | undefined;
User last name.
username?: string | undefined;
Username when one is set.
roles?: OrganizationRole[] | undefined;
Roles attached to the membership.
[].id?: string | undefined;
Role identifier.
[].name?: string | undefined;
Role name.
[].permissions?: string[] | undefined;
Permissions granted by the role.
public_metadata?: Record<string, unknown> | undefined;
Public metadata stored on the membership.
created_at?: string | undefined;
Creation timestamp for the membership.
updated_at?: string | undefined;
Last update timestamp for the membership.
workspaceMembership: WorkspaceMembership | null;
Workspace membership whose identifier matches the active sign-in in the session.
id?: string | undefined;
Workspace-membership identifier.
workspace?: Workspace | undefined;
Workspace attached to the active membership.
id?: string | undefined;
Workspace identifier.
name?: string | undefined;
Workspace name.
image_url?: string | undefined;
Workspace image URL.
description?: string | undefined;
Workspace description.
member_count?: number | undefined;
Workspace member count.
enforce_2fa?: boolean | undefined;
Whether the workspace enforces 2FA.
enable_ip_restriction?: boolean | undefined;
Whether the workspace uses IP restrictions.
organization?: Organization | undefined;
Parent organization for the workspace membership.
id?: string | undefined;
Organization identifier.
name?: string | undefined;
Organization name.
roles?: WorkspaceRole[] | undefined;
Roles attached to the workspace membership.
[].id?: string | undefined;
Role identifier.
[].name?: string | undefined;
Role name.
[].permissions?: string[] | undefined;
Permissions granted by the role.
eligibility_restriction?: { type: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required"; message: string } | undefined | undefined;
Eligibility restriction attached to the membership when one exists.
type?: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required" | undefined;
Restriction type.
message?: string | undefined;
Restriction message.

How it works

The hook does not fetch a separate “active tenancy” resource. It derives the active organization and workspace memberships by matching the active sign-in in the session against the full membership lists.
That means the hook only becomes useful once both the session and the relevant membership collections have loaded.
If the current session has no sign-ins, or if the active membership identifiers do not match any loaded membership rows, the hook returns null for that side of the scope.
This hook is the right fit for UI that needs to work across both tenancy models at once. If a page only cares about one model, useActiveOrganization() or useActiveWorkspace() is usually a tighter fit.

When to use it

    Examples

    Render the current organization and workspace scope

    export default function TenancyHeader() {  const { loading, orgMembership, workspaceMembership } = useActiveTenancy();  if (loading) {    return <p>Loading tenancy…</p>;  }  return (    <div>      <p>Organization: {orgMembership?.organization.name ?? 'None'}</p>      <p>Workspace: {workspaceMembership?.workspace.name ?? 'None'}</p>    </div>  );}

    Gate UI that needs any active tenancy scope

    export default function TenancyGate() {  const { loading, orgMembership, workspaceMembership } = useActiveTenancy();  if (loading) {    return null;  }  if (!orgMembership && !workspaceMembership) {    return <p>Select a workspace or organization first.</p>;  }  return <p>Tenancy ready.</p>;}

    On this page