#4956 — lock down ForTenant() conjoined-document tenant isolation#4958
Merged
Conversation
#4956 reports a "regression": a ForTenant() view of an identity session that Store()s a conjoined (MultiTenanted) document under one tenant, then reads it back through the BASE session (a different tenant), no longer sees it. This is the intended behavior of #4801/#4947 — a conjoined id is a different document per tenant, so a session bound to tenant X must not resolve tenant Y's document. Pre-9.13 the shared tenant-blind identity map leaked one tenant's uncommitted write into another's view; #4801 tenant-scoped the map and #4947 restored sharing only for tenancy-neutral documents. No code change — this adds a regression suite that pins the ForTenant() matrix so the isolation and legitimate sharing cases can't silently drift again. Covers: base-session cross-tenant read returns null (pending + committed/DB parity), same-tenant view sees its own pending write, multiple ForTenant stores all commit through one base SaveChanges with no cross-tenant bleed, and same-tenant ForTenant sharing in both directions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 16, 2026
Open
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a regression suite (
Bug_4956_for_tenant_conjoined_isolation, 5 tests) that pins theForTenant()behavior matrix for conjoined (.MultiTenanted()) documents. No production code change.Why
#4956 reports a regression from 9.12.0 → 9.15.x: a
ForTenant()view of an identity sessionStore()s a conjoined document under one tenant, then reads it back through the base session (a different tenant) and no longer sees it.This is the intended behavior established by #4801 / #4947:
ForTenantsession shared the parent's tenant-blind identity map, so at1store appeared in a*DEFAULT*read — an in-memory answer a real per-tenant query would never give (and, since the repro never callsSaveChanges, it lived only in that shared map).ForTenantsessions; IdentitySessions - ForTenant issue with tenantless entities #4947 restored sharing only for tenancy-neutral documents and deliberately keepsConjoineddocs isolated.The correct pattern for the reporter's code is to read through the same-tenant view:
session.ForTenant(tenantId).LoadAsync(id), or open the session for the intended tenant.Tests
base_session_cannot_see_other_tenants_pending_conjoined_write— the reporter's exact scenario returns null.same_tenant_view_sees_its_own_pending_conjoined_write— correct pattern works.committed_conjoined_write_is_only_visible_to_its_own_tenant— afterSaveChanges, a fresh default-tenant session still can't load it, butForTenant("t1")can (DB parity — not an identity-map artifact).multiple_for_tenant_stores_all_commit_through_base_save_changes— several tenants' writes in one unit of work all commit, no cross-tenant bleed.for_tenant_matching_base_tenant_shares_pending_writes_both_directions— the legitimate sharing case.All green alongside the existing
Bug_4801andBug_4947suites (17/17).Closes #4956.
🤖 Generated with Claude Code