Portal Community

Enforcement at IEntityClient

Every entity operation (read, create, update, query) includes the execution's TenantId. The IEntityClient implementation appends a WHERE tenantId = @tenantId clause to all queries and sets tenantId on all new records. This is not configurable in node config and not overridable by expressions.

// IEntityClient always uses ctx.TenantId:
var result = await _entityClient.ReadAsync(new ReadEntityRequest
{
    Schema = schema,
    EntityId = entityId,
    Fields = config.Fields,
    TenantId = ctx.TenantId    // from execution context — never from config
}, ct);

Isolation Guarantees

OperationIsolation
Read by IDReturns null if entity belongs to different tenant
CreateAlways creates with execution's tenantId — cannot specify another
Update by IDNo-op if entity belongs to different tenant (treated as not found)
QueryFilter always AND-ed with tenantId — cross-tenant results impossible
Silent failure by design: Cross-tenant entity access fails silently (entity not found) rather than with a permission error. This prevents cross-tenant entity ID enumeration — an attacker cannot determine whether an entity ID exists in another tenant by observing the error response.