LogoLogo
GitHub
  • Elsa Workflows 3
  • Getting Started
    • Concepts
      • Outcomes
      • Correlation ID
    • Hello World
    • Prerequisites
    • Packages
    • Containers
      • Docker
      • Docker Compose
        • Elsa Server + Studio
        • Elsa Server + Studio - Single Image
        • Persistent Database
        • Traefik
  • Application Types
    • Elsa Server
    • Elsa Studio
    • Elsa Server + Studio (WASM)
  • Guides
    • HTTP Workflows
      • Programmatic
      • Designer
    • External Application Interaction
    • Loading Workflows from JSON
    • Running Workflows
      • Using Elsa Studio
      • Using a Trigger
      • Dispatch Workflow Activity
  • Activities
    • Control Flow
      • Decision
    • MassTransit
      • Tutorial
  • Expressions
    • C#
    • JavaScript
    • Python
    • Liquid
  • Extensibility
    • Custom Activities
  • Reusable Triggers (3.5-preview)
  • Multitenancy
    • Introduction
    • Setup
  • Operate
    • Variables
    • Activation Strategies
    • Incidents
      • Strategies
      • Configuration
    • Alterations
      • Alteration Plans
        • REST API
      • Applying Alterations
        • REST API
        • Extensibility
  • Optimize
    • Log Persistence
    • Retention
  • Hosting
    • Distributed Hosting
Powered by GitBook
On this page
Edit on GitHub
  1. Multitenancy

Setup

Here are the general steps to enable a multi-tenant setup:

  1. Add a reference to the Elsa.Tenants package.

  2. Install and configure the TenantsFeature.

    1. Configure the tenant resolution pipeline

    2. Configure the tenant provider

Configuration

The following is an example of setting up multitenancy using configuration as the tenants provider and a claims tenant resolver that determines the current tenant from the user's tenant ID claim:

Program.cs
services.AddElsa(elsa =>
{
    elsa.UseTenants(tenants =>
    {
        tenants.ConfigureMultitenancy(options =>
        {
            // Configure the tenant resolution pipeline.
            options.TenantResolverPipelineBuilder.Append<ClaimsTenantResolver>();
        });

        // Install the configuration-based tenanta provider.
        tenants.UseConfigurationBasedTenantsProvider(options => configuration.GetSection("Multitenancy").Bind(options));
});

The appsettings.json file would look like this:

appsettings.json
{
  "Multitenancy": {
      "Tenants": [
        {
          "Id": "tenant-1,
          "Name": "Tenant 1"
        },
        {
          "Id": "tenant-2",
          "Name": "Tenant 2"
        }
      ]
    }
}

When using the default Identity module (Elsa.Identity), and the signed in user is linked to a tenant, the ID of that tenant is added as a claim.

The ClaimsTenantResolver uses that claim to resolve the current tenant.

The following appsettings.json section demonstrates an example of defining users, applications and roles that are linked to a given tenant:

appsettings.json
{
  "Identity": {
    "Tokens": {
      "SigningKey": "sufficiently-large-secret-signing-key",
      "AccessTokenLifetime": "1:00:00:00",
      "RefreshTokenLifetime": "7:00:00:00"
    },
    "Roles": [
      {
        "Id": "admin-1",
        "Name": "Administrator",
        "Permissions": [
          "*"
        ],
        "TenantId": "tenant-1"
      },
      {
        "Id": "admin-2",
        "Name": "Administrator",
        "Permissions": [
          "*"
        ],
        "TenantId": "tenant-2"
      }
    ],
    "Users": [
      {
        "Id": "a2323f46-42db-4e15-af8b-94238717d817",
        "Name": "admin",
        "HashedPassword": "TfKzh9RLix6FPcCNeHLkGrysFu3bYxqzGqduNdi8v1U=",
        "HashedPasswordSalt": "JEy9kBlhHCNsencitRHlGxmErmSgY+FVyMJulCH27Ds=",
        "Roles": [
          "admin-1"
        ],
        "TenantId": "tenant-1"
      },
      {
        "Id": "b0cd0e506e713a9d",
        "Name": "alice",
        "Roles": [
          "admin-2"
        ],
        "HashedPassword": "8B0fFK/f/kk9GkVtzXfRJ2Y6cNyYVvLTfKouWcAcuPg=",
        "HashedPasswordSalt": "xlNWvEng8fRvo0McyJopbRJ2MJ9NIYV/4IY5dOZeiiw=",
        "TenantId": "tenant-2"
      }
    ],
    "Applications": [
      {
        "Id": "d57030226341448daff5a2935aba2d3f",
        "Name": "Postman",
        "Roles": [
          "admin"
        ],
        "ClientId": "HXr0Vzdm9KCZbwsJ",
        "HashedApiKey": "Z5ClHs3mbzx8Pnw3+PxbMq8A/Y+VKMCCDTGYtax8JFM=",
        "HashedApiKeySalt": "kBisa1X8FwBfN2zmyGMFRgIVVBleghhQAJ4WGyTkaD0=",
        "HashedClientSecret": "jEv58d0SVbGQ3nBZM0lkzHghG4Y+lMKW80wipz+9vHk=",
        "HashedClientSecretSalt": "xRKy14Ok1/tU3kLf/8V1fcbLIegy9vcM90Peu2tzohU=",
        "TenantId": "tenant-1"
      }
    ]
  }
}

Primary keys (Id) must be unique across tenants since there's no constraint with tenant IDs. This might change in a future version.

PreviousIntroductionNextVariables

Last updated 4 months ago