पाठ 15 / 32
Testing Tenant Isolation
यह पाठ अभी हिंदी में अनुवादित नहीं है, इसलिए अंग्रेज़ी में दिखाया जा रहा है।
Write automated tests that seed two tenants and prove that reads, writes, searches and exports never cross the tenant boundary.
लेखक: Rahul Agarwal · 15 साल से वेब डेवलपर
Prove the negative
Most tests check that a feature works. Isolation tests check that something does not happen: tenant A must never see, change or infer tenant B's data. The basic recipe is to seed at least two tenants with overlapping-looking data (same project names, consecutive ids), act as tenant A, and assert that B's records are invisible through every path: list endpoints, get-by-id, search, exports, file downloads, webhooks and admin screens. Also test writes: updating or deleting B's record id while signed in as A must fail, preferably with not found rather than forbidden, so you do not confirm that the id exists. Run these tests in CI against the real database engine with the application's restricted role, and add one whenever a new endpoint or data store appears. Some teams also run periodic production checks with synthetic canary tenants.
A minimal cross-tenant test
Plain asserts so it runs anywhere; in a real project this would be a pytest test using fixtures for both tenants.
import sqlite3
def make_db():
db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE notes (tenant_id TEXT, id INTEGER, body TEXT)")
db.executemany("INSERT INTO notes VALUES (?, ?, ?)",
[("acme", 1, "acme secret"), ("zen", 2, "zen secret")])
return db
def get_note(db, tenant_id, note_id):
row = db.execute("SELECT body FROM notes WHERE tenant_id = ? AND id = ?",
(tenant_id, note_id)).fetchone()
return row[0] if row else None
def test_cannot_read_other_tenant():
db = make_db()
assert get_note(db, "acme", 1) == "acme secret"
assert get_note(db, "acme", 2) is None # zen's note must be invisible
assert get_note(db, "zen", 1) is None
test_cannot_read_other_tenant()
print("cross-tenant isolation test passed")
Output:
cross-tenant isolation test passed
Return 404, not 403
If tenant A requests /invoices/981 and that invoice belongs to tenant B, answering forbidden tells A that invoice 981 exists. Answer not found, exactly as you would for an id that does not exist at all.
त्वरित जाँच: Which test best guards against cross-tenant leaks in a new search endpoint?
- Check that search returns results within 200 ms
- Search as tenant A for a term that exists only in tenant B's data and assert zero results
- Search as an admin superuser and assert all results appear
- Check that the search endpoint returns valid JSON
Answer
Search as tenant A for a term that exists only in tenant B's data and assert zero results — An isolation test seeds data in another tenant and proves it cannot be reached. Speed and JSON shape tests do not detect leaks, and superusers bypass the very rules you need to test.