TenantUser

Junction entity representing the membership relationship between a user and a tenant workspace, enabling users to access and switch between multiple isolated tenant environments. This entity is the cornerstone of multi-tenant user management, tracking user membership status, invitation workflow, tenant-specific user attributes, and access periods. It enables scenarios where users work across multiple client tenants (consultants, agencies), collaborate with partner organizations, or manage multiple workspaces. The entity supports invitation-based onboarding, role designations per tenant (owner, member, guest), tenant switching in the UI, and complete membership lifecycle from invitation through active membership to removal. It serves as the authorization boundary for tenant-scoped data access and the foundation for tenant isolation in B2B SaaS platforms, enterprise systems, and collaborative applications.

18 properties
Schema

Properties

PropertyTypeModeDescriptionRequired
userUser
stored

Reference to the User who is a member of this tenant

Required
tenantTenant
stored

Reference to the Tenant that this user belongs to

Required
membershipStatusstring
stored

Current status of the user's membership in this tenant

Values: active, invited, pending, suspended, inactive, removed

Example: "active"

Required
joinedAtdatetime
stored

Date/time when the user joined or was added to this tenant

Example: "2024-01-15T10:30:00Z"

Required
invitedByUser
stored

Reference to the User who invited this user to the tenant

Optional
invitedAtdatetime
stored

Date/time when the invitation was sent

Example: "2024-01-10T14:00:00Z"

Optional
invitationAcceptedAtdatetime
stored

Date/time when the user accepted the invitation

Example: "2024-01-15T10:30:00Z"

Optional
isOwnerboolean
stored

Whether this user is an owner/administrator of the tenant with full administrative privileges

Example: true

Optional
isPrimaryboolean
stored

Whether this is the user's primary/default tenant workspace

Example: true

Optional
displayNamestring
stored

Tenant-specific display name for this user (may differ from Person name for privacy or branding)

Example: "John D. (Engineering Lead)"

Optional
positionstring
stored

User's position or job title within this tenant

Example: "Engineering Manager"

Optional
departmentstring
stored

Department or division within the tenant

Example: "Engineering"

Optional
metadatajson
stored

Tenant-specific metadata for this user (e.g., employee ID, cost center, custom fields)

Example: {"employeeId":"EMP-12345","costCenter":"CC-ENG-001","officeLocation":"New York"}

Optional
leftAtdatetime
stored

Date/time when the user left or was removed from the tenant

Optional
leftReasonstring
stored

Reason for leaving the tenant

Optional
isActiveboolean
calculated

Whether this membership is currently active (status is active and not left)

Optional
daysSinceJoinednumber
calculated

Number of days since the user joined this tenant

Optional
isInvitationPendingboolean
calculated

Whether the invitation is still pending acceptance

Optional

Examples

Example 1

{
  "@type": "TenantUser",
  "user": {
    "@type": "User",
    "username": "john.doe"
  },
  "tenant": {
    "@type": "Tenant",
    "slug": "acme-corp",
    "name": "ACME Corporation"
  },
  "membershipStatus": "active",
  "joinedAt": "2023-06-01T12:00:00Z",
  "isOwner": true,
  "isPrimary": true,
  "displayName": "John Doe",
  "position": "CEO",
  "department": "Executive"
}

Example 2

{
  "@type": "TenantUser",
  "user": {
    "@type": "User",
    "username": "jane.smith"
  },
  "tenant": {
    "@type": "Tenant",
    "slug": "acme-corp",
    "name": "ACME Corporation"
  },
  "membershipStatus": "active",
  "joinedAt": "2024-03-15T09:00:00Z",
  "invitedBy": {
    "@type": "User",
    "username": "john.doe"
  },
  "invitedAt": "2024-03-10T10:00:00Z",
  "invitationAcceptedAt": "2024-03-15T09:00:00Z",
  "isOwner": false,
  "isPrimary": true,
  "displayName": "Jane Smith",
  "position": "Sales Manager",
  "department": "Sales",
  "metadata": {
    "employeeId": "EMP-00234",
    "costCenter": "CC-SALES-001"
  }
}

Example 3

{
  "@type": "TenantUser",
  "user": {
    "@type": "User",
    "username": "bob.wilson"
  },
  "tenant": {
    "@type": "Tenant",
    "slug": "techstart",
    "name": "TechStart Inc"
  },
  "membershipStatus": "invited",
  "invitedBy": {
    "@type": "User",
    "username": "admin"
  },
  "invitedAt": "2024-11-20T10:00:00Z",
  "isOwner": false,
  "isPrimary": false,
  "position": "Consultant"
}

Example 4

{
  "@type": "TenantUser",
  "user": {
    "@type": "User",
    "username": "john.doe"
  },
  "tenant": {
    "@type": "Tenant",
    "slug": "consulting-partners",
    "name": "Consulting Partners LLC"
  },
  "membershipStatus": "active",
  "joinedAt": "2024-09-01T09:00:00Z",
  "isOwner": false,
  "isPrimary": false,
  "displayName": "John Doe (Advisor)",
  "position": "Strategic Advisor",
  "metadata": {
    "partTime": true,
    "hoursPerWeek": 10
  }
}