Skip to content

IAM Service - Domain Design

1. User sub-domain

Aggregate Root: User

a. Description

The User domain represents individual users in the system—people who can access the platform and be assigned to tenants with specific roles. Users have personal information (name, email) and can have multiple memberships across different tenants.

The User aggregate manages user identity, validates user data, and enforces business rules around user information updates.

Key Properties:

  • id: Unique identifier for the user
  • firstName: User's first name
  • lastName: User's last name
  • email: User's email address (unique)
  • memberships: Collection of memberships linking user to tenants with roles

Commands and Operations:

CommandTriggered ByPurposeBusiness Logic
create()Human (Admin) or System (Registration)Create new user accountValidates email format, creates user with required fields
update()Human (User/Admin)Update user informationValidates email format, ensures names are not empty, updates specified fields
checkCanDelete()Human (Admin)Check if user can be deletedCurrently no restrictions (placeholder for future business rules)

Validation Rules:

  1. Email Format: Must match standard email regex pattern (/^[^\s@]+@[^\s@]+\.[^\s@]+$/)
  2. Name Requirements: First name and last name cannot be empty strings
  3. Email Uniqueness: Email must be unique across all users (enforced at database level)

c. Domain Entry Points

The User aggregate provides a static factory method as its entry point:

Static MethodPurposeTriggered By
create()Initialize User aggregateUser registration or admin user creation

d. Domain Boundaries and Vision

The User domain manages user identity and personal information while remaining unaware of authorization details (roles, permissions) which are handled through the Membership domain.

Integration boundaries

  • ↔ Membership Domain: Users are linked to tenants and roles through Membership entities. User doesn't directly manage memberships, but memberships reference users.
  • ← External Systems: User creation can be triggered by external authentication systems (e.g., SuperTokens) during registration.
  • → External Systems: User information is consumed by other services for authorization and personalization.

Vision

  • User supports multi-tenant access through memberships
  • User maintains audit trail through createdAt/updatedAt timestamps
  • User supports soft-delete for data retention and compliance
  • User validation ensures data quality and prevents invalid user accounts

2. Tenant sub-domain

Aggregate Root: Tenant

a. Description

The Tenant domain represents organizations or tenants in a multi-tenant system—isolated workspaces where users collaborate. Each tenant has a unique name and can have multiple users as members with different roles.

The Tenant aggregate manages tenant identity, enforces tenant uniqueness, and supports tenant lifecycle management.

Key Properties:

  • id: Unique identifier for the tenant
  • name: Tenant name (unique across all tenants)
  • memberships: Collection of memberships linking users to this tenant with roles

Commands and Operations:

CommandTriggered ByPurposeBusiness Logic
create()Human (Admin)Create new tenantCreates tenant with unique name
rename()Human (Admin)Update tenant nameUpdates tenant name (uniqueness enforced at database level)

Business Rules:

  1. Name Uniqueness: Tenant name must be unique across all tenants (enforced at database level with unique constraint)
  2. Soft Delete: Tenants can be soft-deleted, preserving data for audit and compliance

c. Domain Entry Points

The Tenant aggregate provides a static factory method as its entry point:

Static MethodPurposeTriggered By
create()Initialize Tenant aggregateTenant creation by admin

d. Domain Boundaries and Vision

The Tenant domain manages tenant identity and isolation while remaining unaware of user details or authorization specifics, which are handled through the Membership domain.

Integration boundaries

  • ↔ Membership Domain: Tenants are linked to users and roles through Membership entities. Tenant doesn't directly manage memberships, but memberships reference tenants.
  • ← External Systems: Tenant creation can be triggered by external systems during onboarding.
  • → External Systems: Tenant information is consumed by other services for multi-tenant data isolation and authorization.

Vision

  • Tenant provides data isolation boundaries for multi-tenant architecture
  • Tenant maintains audit trail through createdAt/updatedAt timestamps
  • Tenant supports soft-delete for data retention and compliance
  • Tenant name uniqueness ensures clear tenant identification

3. Role sub-domain

Entity: Role (not an aggregate root)

a. Description

The Role domain represents roles that define sets of permissions—reusable authorization templates that can be assigned to users within tenants. Roles contain a collection of permission IDs that define what actions users with that role can perform.

Current Architecture Note: Role is an entity that can be referenced by multiple memberships. It doesn't have its own lifecycle persistence independent of the IAM service, but it's a first-class domain concept.

b. Structure and business rules

Role
├── Basic Properties
│   ├── id: string
│   ├── name: string
│   ├── description: string | null
│   └── permissionIds: string[]

└── Relationships
    ├── permissions: Permission[] (via permissionIds)
    └── memberships: Membership[] (referenced by memberships)

Business Rules:

  1. Permission Assignment: Roles contain an array of permission IDs that define allowed actions
  2. Reusability: Roles can be assigned to multiple users across different tenants through memberships
  3. Permission Validation: Permission IDs must reference existing Permission entities (enforced at application level)

Commands and Operations:

CommandTriggered ByPurposeBusiness Logic
create()Human (Admin)Create new roleCreates role with name, description, and permission IDs
rename()Human (Admin)Update role nameUpdates role name
updateDescription()Human (Admin)Update role descriptionUpdates role description
updatePermissions()Human (Admin)Update role permissionsReplaces permission IDs array

c. Domain Boundaries and Vision

The Role entity is a reusable authorization template that defines permission sets:

🔗 Role ↔ Permission Interface

  • Responsibility: Role encapsulates a named set of permissions
  • Direction: Role references Permission entities via permissionIds
  • Boundary Rule: Role doesn't own Permission entities; it references them

🔗 Role ↔ Membership Interface

  • Responsibility: Role is assigned to users within tenants through Membership
  • Direction: Membership references Role via roleId
  • Boundary Rule: Role doesn't manage memberships; memberships reference roles

Key Encapsulation Rules:

  1. External actors CANNOT directly manipulate Role permission sets without going through role commands
  2. All Role operations MUST go through role commands (create, rename, updatePermissions)
  3. Role entities contain business logic but are referenced by memberships

Vision

  • Role provides reusable authorization templates
  • Role supports permission composition through permission IDs
  • Role enables consistent authorization across tenants
  • Role maintains clear separation between role definition and role assignment

4. Permission sub-domain

Entity: Permission (not an aggregate root)

a. Description

The Permission domain represents permissions—granular authorization capabilities that define what actions can be performed in the system. Permissions are the atomic units of authorization that are composed into roles.

Current Architecture Note: Permission is an entity that can be referenced by multiple roles. It doesn't have its own lifecycle persistence independent of the IAM service, but it's a first-class domain concept.

b. Structure and business rules

Permission
├── Basic Properties
│   ├── id: string
│   ├── name: string
│   ├── description: string | null
│   └── deletedAt: Date | null

└── Relationships
    └── roles: Role[] (referenced by roles via permissionIds)

Business Rules:

  1. Atomic Authorization: Permissions represent single, atomic authorization capabilities
  2. Reusability: Permissions can be referenced by multiple roles
  3. Soft Delete: Permissions can be soft-deleted, preserving references but marking as inactive

Commands and Operations:

CommandTriggered ByPurposeBusiness Logic
create()Human (Admin)Create new permissionCreates permission with name and optional description
rename()Human (Admin)Update permission nameUpdates permission name
updateDescription()Human (Admin)Update permission descriptionUpdates permission description

c. Domain Boundaries and Vision

The Permission entity is an atomic authorization unit that defines individual capabilities:

🔗 Permission ↔ Role Interface

  • Responsibility: Permission defines atomic authorization capabilities
  • Direction: Role references Permission entities via permissionIds
  • Boundary Rule: Permission doesn't own Role entities; roles reference permissions

Key Encapsulation Rules:

  1. External actors CANNOT directly manipulate Permission definitions without going through permission commands
  2. All Permission operations MUST go through permission commands (create, rename, updateDescription)
  3. Permission entities contain business logic but are referenced by roles

Vision

  • Permission provides atomic authorization units
  • Permission enables fine-grained access control
  • Permission supports composition into roles for flexible authorization
  • Permission maintains clear separation between permission definition and permission usage

5. Membership sub-domain

Entity: Membership (not an aggregate root)

a. Description

The Membership domain represents the relationship between users, tenants, and roles—the assignment of a user to a tenant with a specific role. Memberships enable multi-tenant access control by linking users to tenants and defining their authorization level through roles.

Current Architecture Note: Membership is an entity that links User, Tenant, and Role aggregates. It doesn't have its own lifecycle persistence independent of these aggregates, but it's a first-class domain concept that enables the authorization model.

b. Structure and business rules

Membership
├── Basic Properties
│   ├── id: string
│   ├── userId: string (references User)
│   ├── tenantId: string (references Tenant)
│   ├── roleId: string (references Role)
│   ├── createdAt: Date
│   ├── updatedAt: Date
│   └── deletedAt: Date | null

└── Relationships
    ├── user: User (via userId)
    ├── tenant: Tenant (via tenantId)
    └── role: Role (via roleId)

Business Rules:

  1. Unique User-Tenant Pair: A user can have at most one membership per tenant (enforced at database level with unique constraint on [userId, tenantId])
  2. Role Assignment: Each membership assigns exactly one role to the user within the tenant
  3. Multi-Tenant Support: Users can have multiple memberships across different tenants with different roles
  4. Soft Delete: Memberships can be soft-deleted, preserving audit trail while revoking access

Commands and Operations:

CommandTriggered ByPurposeBusiness Logic
create()Human (Admin)Create new membershipCreates membership linking user, tenant, and role. If membership already exists, returns existing membership ID

Key Aggregate Invariants:

  1. User-Tenant Uniqueness: Each user can have only one active membership per tenant
  2. Role Requirement: Membership must reference an existing role
  3. User Requirement: Membership must reference an existing user
  4. Tenant Requirement: Membership must reference an existing tenant

c. Domain Boundaries and Vision

The Membership entity is a relationship entity that links User, Tenant, and Role aggregates:

🔗 Membership ↔ User Interface

  • Responsibility: Membership links users to tenants and roles
  • Direction: Membership references User via userId
  • Boundary Rule: Membership doesn't own User; it references users

🔗 Membership ↔ Tenant Interface

  • Responsibility: Membership defines user's access within a tenant
  • Direction: Membership references Tenant via tenantId
  • Boundary Rule: Membership doesn't own Tenant; it references tenants

🔗 Membership ↔ Role Interface

  • Responsibility: Membership assigns role to user within tenant
  • Direction: Membership references Role via roleId
  • Boundary Rule: Membership doesn't own Role; it references roles

Key Encapsulation Rules:

  1. External actors CANNOT directly manipulate Membership relationships without going through membership commands
  2. All Membership operations MUST go through membership commands (create)
  3. Membership entities enforce business rules around user-tenant-role relationships

Vision

  • Membership enables multi-tenant access control
  • Membership provides clear user-tenant-role relationships
  • Membership supports role-based access control (RBAC) model
  • Membership maintains audit trail through timestamps and soft-delete
  • Membership ensures data integrity through unique constraints