Knara.MultiTenant.IsolationEnforcer 1.0.4

dotnet add package Knara.MultiTenant.IsolationEnforcer --version 1.0.4
                    
NuGet\Install-Package Knara.MultiTenant.IsolationEnforcer -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Knara.MultiTenant.IsolationEnforcer" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Knara.MultiTenant.IsolationEnforcer" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Knara.MultiTenant.IsolationEnforcer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Knara.MultiTenant.IsolationEnforcer --version 1.0.4
                    
#r "nuget: Knara.MultiTenant.IsolationEnforcer, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Knara.MultiTenant.IsolationEnforcer@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Knara.MultiTenant.IsolationEnforcer&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Knara.MultiTenant.IsolationEnforcer&version=1.0.4
                    
Install as a Cake Tool

Multi-Tenant Data Isolation Enforcer

Build and Test NuGet .NET License: MIT

Multi-tenant data isolation for .NET applications with compile-time enforcement.

Problem and Solution

Problem: Tenant data leaks are among the most common and costly mistakes in multi-tenant applications.

Solution: This library prevents tenant isolation errors through compile-time analysis via Roslyn analyzers and runtime safeguards.

Before (Unsafe)

public async Task<List<Order>> GetOrders()
{
    return await _context.Orders.ToListAsync(); // Returns ALL tenants' data
}

After (Protected)

public async Task<List<Order>> GetOrders()
{
    return await _orderRepository.GetAllAsync(); // Automatically tenant-filtered
}

// Attempting direct DbSet access produces:
// Error MTI001: Use ITenantIsolatedRepository<Order> instead of direct DbSet access

Requirements

  • .NET 8.0 or later

Installation

NuGet Packages

dotnet add package Knara.MultiTenant.IsolationEnforcer
dotnet add package Knara.MultiTenant.IsolationEnforcer.Analyzers
<ItemGroup>
  <PackageReference Include="Knara.MultiTenant.IsolationEnforcer" Version="1.0.0" />
  <PackageReference Include="Knara.MultiTenant.IsolationEnforcer.Analyzers" Version="1.0.0" 
                    OutputItemType="Analyzer" 
                    ReferenceOutputAssembly="false">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
  </PackageReference>
</ItemGroup>

Clone and Build

git clone https://github.com/tasriyan/Knara.MultiTenant.IsolationEnforcer
cd Knara.MultiTenant.IsolationEnforcer
dotnet build

Quick Start

1. Configure Services

services.AddMultiTenantIsolation()
    .WithInMemoryTenantCache()
    .WithTenantsStore<YourTenantStore>()
    .WithSubdomainResolutionStrategy(options =>
    {
        options.ExcludedSubdomains = new[] { "www", "api", "admin" };
    });

app.UseAuthentication();
app.UseMultiTenantIsolation();

2. Choose Isolation Approach

Option A: TenantIsolatedDbContext (Automatic Filtering)

public class YourDbContext : TenantIsolatedDbContext
{
    public YourDbContext(DbContextOptions<YourDbContext> options, 
        ITenantContextAccessor tenantAccessor, 
        ILogger<YourDbContext> logger) 
        : base(options, tenantAccessor, logger) { }
}

// Use DbContext directly
public async Task<List<Order>> GetOrders()
{
    return await _context.Orders.ToListAsync(); // Automatically filtered
}

Option B: TenantIsolatedRepository (Manual Filtering)

public class OrderService
{
    private readonly TenantIsolatedRepository<Order, YourDbContext> _orderRepo;
    
    public async Task<List<Order>> GetOrders()
    {
        return await _orderRepo.GetAllAsync(); // Manually filtered
    }
}

3. Mark Entities

public class Order : ITenantIsolated
{
    public Guid Id { get; set; }
    public Guid TenantId { get; set; } // Auto-assigned
    public string CustomerName { get; set; }
}

Documentation

Key Features

Compile-Time Enforcement

  • MTI001: Direct DbSet access prohibited
  • MTI002: Cross-tenant authorization required
  • MTI003: Filter bypass warnings
  • MTI005: System context authorization required

Runtime Protection

  • Global query filters: WHERE TenantId = @currentTenant
  • SaveChanges validation prevents cross-tenant modifications
  • Automatic TenantId assignment
  • Exception throwing on violations

Mandatory Monitoring

  • Query performance tracking
  • Violation logging
  • Cross-tenant operation auditing

Cross-Tenant Operations

For legitimate administrative operations:

[AllowCrossTenantAccess("Admin reporting", "SystemAdmin")]
public async Task<AdminReport> GetGlobalReport()
{
    return await _crossTenantManager.ExecuteCrossTenantOperationAsync(
        async () => await GenerateReport(), 
        "Global admin reporting"
    );
}

Tenant Resolution

Built-in strategies:

.WithSubdomainResolutionStrategy()  // tenant1.yourapp.com
.WithJwtResolutionStrategy()         // JWT claims
.WithHeaderResolutionStrategy()      // X-Tenant-ID header
.WithPathResolutionStrategy()        // /tenant1/api/users

Comparison to Other Libraries

Compared to libraries like Finbuckle.MultiTenant, this library is more restrictive:

  • Compile-time enforcement via Roslyn analyzers
  • Mandatory performance monitoring
  • Opinionated design with fewer configuration options

This library assumes developers will make mistakes and attempts to prevent them at compile time.

Migration from Existing Applications

  1. Install package and configure services
  2. Choose TenantIsolatedDbContext or TenantIsolatedRepository
  3. Add ITenantIsolated interface to entities
  4. Replace direct DbContext usage with repositories (Option B only)
  5. Fix compilation errors guided by analyzers
  6. Add database migration for TenantId columns

When to Use

Good fit:

  • Teams frequently making tenant isolation mistakes
  • Preference for compile-time safety over flexibility
  • New multi-tenant applications
  • Opinionated tools with fewer configuration options

Not suitable:

  • Need for maximum flexibility
  • Complex tenant resolution requirements beyond built-in resolvers
  • Large existing codebases resistant to repository pattern adoption

License

MIT License. Copyright 2025 Tatyana Asriyan

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.4 262 10/23/2025
1.0.3 180 9/26/2025
1.0.2 234 9/25/2025
1.0.1 232 9/24/2025
1.0.0 219 9/24/2025