EF Core Tenant Isolation: Global Query Filters for Secure Multi-Tenant SaaS
In one of our enterprise SaaS projects last year, we discovered a critical bug during a routine audit. Customer A could see order data belonging to Customer B when filtering by a specific date range. The root cause? A missing WHERE TenantId = @tenantId clause in a complex reporting query.
This wasn’t just embarrassing. It was a potential GDPR violation that could have resulted in significant penalties. That incident taught us that manual tenant filtering is prone to human error, especially in large codebases with multiple developers.
EF Core’s global query filters solved this problem by automatically applying tenant isolation at the ORM level. Here’s how we implemented bulletproof tenant isolation that passes SOC2 and HIPAA compliance requirements.
The Multi-Tenant Entity Foundation
Every entity in our system includes a TenantId property. This isn’t optional, it’s the foundation of data isolation.
public class Order
{
public int Id { get; set; }
public Guid TenantId { get; set; }
public string CustomerName { get; set; }
public decimal Amount { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Product
{
public int Id { get; set; }
public Guid TenantId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
The TenantId is resolved through dependency injection using a tenant provider service:
public interface ITenantProvider
{
Guid TenantId { get; }
}
public …