Fixes #24180: Domain isolation in UI, search and lineage for multi-tenant#28889
Fixes #24180: Domain isolation in UI, search and lineage for multi-tenant#28889harshach wants to merge 3 commits into
Conversation
Domain-restricted users (DomainOnlyAccessRole) now only see their own domains and sub-domains across lineage graphs, domain list/hierarchy/search, and the UI domain selector. Backend: - LineageDomainFilter prunes search-lineage results (reachability-from-root, severs traversal through foreign nodes); wired into SearchRepository lineage/export paths and the DB-graph get/getByName endpoints. - ListFilter.getDomainSelfCondition + EntityUtil.applyDomainSelfRestriction filter the Domain REST list and /domains/hierarchy. - RBACConditionEvaluator.hasDomain() matches a user's own domains by id and excludes domain documents from the domainless clause, so the domain search index hides foreign domains (gated on enableAccessControl). Frontend (defense-in-depth + UX): - Wire currentUser.domains into useDomainStore; hide "All Domains" and auto-select the single allowed domain; scope listing + lineage queries. Tests: LineageDomainFilterTest, ES/OS RBACConditionEvaluatorTest additions, DomainIsolationIT, frontend Jest specs, and DomainIsolation.spec.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /v1/lineage/getDataQualityLineage endpoint bypassed the domain prune, letting a DomainOnlyAccessRole user observe foreign-domain nodes/edges. Thread SubjectContext through searchDataQualityLineage (SearchManagementClient -> clients -> managers) and apply LineageDomainFilter.pruneDataQualityLineage (visibility-only over the node/edge sets) before assembling the response. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d shard (#24180) Add a dedicated Playwright project "DomainIsolation" (own shard, serial workers since the specs toggle the global enableAccessControl setting) and exclude the directory from the main chromium project. The suite verifies per-user, cross-tenant isolation across multiple users (userA/userB/admin): - DomainSearchIsolation: each user only finds their own domain's assets (+ domainless), not the other tenant's — proving per-user, not global, hiding. - DomainListingIsolation: domain listing page scoped per user. - DomainLineageIsolation: cross-tenant lineage node hidden per user; admin sees all. - DomainDropdownIsolation: navbar dropdown scoped per user (relocated here). Wired into the postgresql e2e workflow shard-1 group (alongside SearchRBAC); the mysql e2e --shard run picks it up automatically. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code Review ✅ Approved 3 resolved / 3 findingsImplements comprehensive domain isolation for multi-tenant setups across UI, search, and lineage, resolving all identified bypasses in data-quality and graph pruning. No issues found. ✅ 3 resolved✅ Performance: N+1 entity fetch per node in DB-graph lineage pruning
✅ Edge Case: Foreign root entity ref retained after DB-graph prune
✅ Security: Data Quality lineage endpoint bypasses domain isolation
OptionsDisplay: compact → Showing less information. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |
|
|
🟡 Playwright Results — all passed (14 flaky)✅ 4269 passed · ❌ 0 failed · 🟡 14 flaky · ⏭️ 88 skipped
🟡 14 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |



Describe your changes:
Fixes #24180
I worked on domain isolation for multi-tenant setups because users restricted to a Domain could still see other domains' names (dropdowns/lists/search) and foreign-domain lineage, which leaks metadata across tenants. This enforces isolation server-side for users carrying
DomainOnlyAccessRole: lineage results (search, DB-graph, exports, and the data-quality lineage endpoint) are pruned to the user's accessible domains (own + sub-domains + domainless, reachable-from-root so traversal through foreign nodes is severed), the Domain REST list//hierarchyare filtered, the domain search index is filtered through the search RBAC evaluator, and the UI mirrors this (hides "All Domains", auto-selects a single allowed domain, scopes listing/lineage queries). Activity-feed isolation already existed and is unchanged.Type of change:
High-level design:
LineageDomainFilterprunes the assembledSearchLineageResultinSearchRepository(single fail-closed chokepoint, reachability-from-root using the hierarchy-awareSubjectContext.hasDomains); the DB-graphget/getByNameand the data-quality lineage endpoint (searchDataQualityLineage, visibility-only prune over its node/edge sets) are filtered the same way. The graph builders are untouched.ListFilter.getDomainSelfCondition+EntityUtil.applyDomainSelfRestrictionfilter the Domain entity by its own id + sub-domain FQN-hash prefix (domains aren't themselves domain-tagged, so generic domain filters don't apply to them).RBACConditionEvaluator.hasDomain()matches the user's own domains byid.keywordand excludes domain documents from the "domainless" clause (gated onenableAccessControl, like all search RBAC).Tests:
Use cases covered
DomainOnlyAccessRoleuser querying lineage (search, DB-graph, or data-quality lineage) sees only own-domain + domainless nodes; foreign-domain nodes and the paths through them are hidden./v1/domains,/v1/domains/hierarchy, the domain search index, and the navbar dropdown.Unit tests
LineageDomainFilterTest(incl. data-quality prune),ElasticSearchRBACConditionEvaluatorTest,OpenSearchRBACConditionEvaluatorTest,SearchRepositoryBehaviorTest,DomainRestrictionUtils.test.ts,useApplicationStore.domain.test.ts,DomainSelectableTree.test.tsx.Backend integration tests
openmetadata-integration-tests/.../DomainIsolationIT.java(lineage + domain list/hierarchy/search isolation).Ingestion integration tests
Playwright (UI) tests
DomainIsolationPlaywright project/shard (runs serially because the specs toggle the globalenableAccessControlsetting; excluded from the mainchromiumproject).playwright/e2e/Features/DomainIsolation/):DomainSearchIsolation.spec.ts,DomainListingIsolation.spec.ts,DomainLineageIsolation.spec.ts,DomainDropdownIsolation.spec.ts,domainIsolationUtils.ts. Multi-user (admin / userA / userB) cross-tenant isolation.Manual testing performed
DomainIsolationshard compile/lint/type-check cleanly but were not executed against a live stack in this change.UI screen recording / screenshots:
Not applicable yet — happy to attach a recording of the restricted-user dropdown/search if required for review.
Checklist:
Fixes <issue-number>: <short explanation>Fixes #24180above.🤖 Generated with Claude Code