Skip to content

Fixes #35078: authorize VIEW_BASIC on lineage edge-details read endpoints - #35140

Closed
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fixes-35078-authorize-view-basic-on-lineage-edge-d-740586
Closed

detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fixes-35078-authorize-view-basic-on-lineage-edge-d-740586

Conversation

@detail-app

@detail-app detail-app Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Describe your changes:

Fixes #35078

The getLineageEdge (by-id) and getLineageEdgeByName (by-FQN) read endpoints in LineageResource called the DAO directly with no authorizer.authorize(...) and no getSubjectContext(...), so any authenticated caller could read the raw LineageDetails (including sqlQuery, columnsLineage, pipeline) for arbitrary entity pairs. This bypassed both the per-entity VIEW_BASIC authorization and the DomainOnlyAccessRole domain isolation that get/getByName enforce via pruneLineageByDomain. Every sibling PUT/PATCH/DELETE endpoint in the same resource already authorizes both endpoints; the two GETs were the only read endpoints that performed zero authorization.

I worked on closing this authorization gap because the edge-details endpoints are the sole read path through which a DomainOnlyAccessRole user can exfiltrate cross-domain lineage (the graph reads prune foreign-domain nodes, but the edge reads returned the raw edge data with no check).

Type of change:

  • Bug fix

High level design:

The by-id path (/{fromId}/{toId}) has no entity-type segments in the URL, so the fix resolves fromEntity/toEntity from the stored entity_relationship row via a new LineageRepository.getLineageEdgeRecord(UUID, UUID) (using the existing relationshipDAO().getRecord(...) already called in 5+ places). If the record is absent the endpoint returns 404 before any authz check, preserving the prior behavior. Both endpoints then call the existing three-argument authorizeLineageReference(securityContext, entityReference, MetadataOperation.VIEW_BASIC) helper on both endpoints before the DAO read.

VIEW_BASIC is used (not EDIT_LINEAGE) to match the scene API's focus-entity read (authorizeLineageSceneFocus, line 144) — EDIT_LINEAGE would 403 the view-only DataConsumer users who legitimately click a visible edge in the Lineage Map. The by-FQN variant resolves references with Include.NON_DELETED, matching the DAO's own lookup so authz succeeds/fails on exactly the entity the DAO queries.

Tests:

Use cases covered

  • A DomainOnlyAccessRole user confined to domain A is denied (403) when reading edge details for an edge where either endpoint lies in a foreign domain B — both by-id and by-FQN.
  • A DomainOnlyAccessRole user can still read edge details for edges within their own domain (no over-restriction).
  • A user holding a DENY policy on VIEW_BASIC for foreign-domain tables is denied edge details touching a denied table — both by-id and by-FQN.
  • An admin can still read any edge (admin bypass unaffected).
  • A non-existent edge still returns 404 (not 403), with no authz check.
  • The authorizer receives VIEW_BASIC (not EDIT_LINEAGE) for both endpoints.
  • Existing admin happy-path edge reads (PUT via FQN + getLineageEdgeByName; PATCH + getLineageEdgeByName; by-id GET in TableResourceIT) continue to pass.

Unit tests

  • I added unit tests for the new/changed logic.
  • openmetadata-service/src/test/java/org/openmetadata/service/resources/lineage/LineageResourceGetLineageEdgeAuthorizationTest.java — 10 cases covering the by-id and by-FQN endpoints: deny-on-from, deny-on-to, allow-both, 404-before-authz, and VIEW_BASIC-not-EDIT_LINEAGE capture; plus Include.NON_DELETED scope verification.
  • LineageRepositoryTest.java — 3 new cases for getLineageEdgeRecord: delegates to getRecord with Relationship.UPSTREAM, null passthrough, and entity-type carriage.

Backend integration tests

  • I added integration tests in openmetadata-integration-tests/ for the changed API endpoints.
  • LineageResourceIT.testGetLineageEdgeEnforcesDomainIsolationForEdgeReads — cross-domain DomainOnlyAccessRole denial (by-id and by-FQN), with graph-pruning positive control, same-domain readability, and admin regression check.
  • LineageResourceIT.testGetLineageEdgeEnforcesViewBasicPolicyDenyForEdgeReads — policy-denied VIEW_BASIC denial (by-id and by-FQN), with admin control.

Ran locally (Testcontainers MySQL + Elasticsearch):

  • LineageResourceIT — 62 tests, 0 failures, 3 pre-existing skips.
  • ServiceLineageRefcountIT — 4 tests, 0 failures (404 regression).
  • TableResourceIT — 346 tests, 0 failures (admin by-id edge read regression).
  • DomainIsolationIT — 9 tests, 0 failures (domain isolation regression).
  • LineageResourceGetLineageEdgeAuthorizationTest + LineageRepositoryTest — 39 tests, 0 failures.
  • Lineage unit regression suite (LineagePermissionFilterTest, LineageDomainFilterTest, LineageSceneResolverTest, LineageGraphPrunerTest, LineageScene*Test) — 127 tests total, 0 failures.
  • mvn spotless:check on openmetadata-service and openmetadata-integration-tests — clean.

Manual testing performed

N/A — coverage is via the unit and integration tests above.

UI screen recording / screenshots:

Not applicable.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.
  • For UI changes: I attached a screen recording and/or screenshots above.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

Automatic Fixes PRs can be configured here.

@detail-app
detail-app Bot requested a review from ulixius9 October 10, 2026 02:15
@detail-app
detail-app Bot requested a review from a team as a code owner October 10, 2026 02:15
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@detail-app detail-app Bot added the safe to test Add this label to run secure Github workflows on PRs label Oct 10, 2026
@sonarqubecloud

Copy link
Copy Markdown

@mohityadav766 mohityadav766 self-assigned this Oct 12, 2026
@ulixius9
ulixius9 removed their request for review October 13, 2026 08:58
@shah-harshit

Copy link
Copy Markdown
Contributor

Superseded by #35537, which combines this change with other queued fixes.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a manual request Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚦 Removed from the merge queue — manual (2026-10-15T12:27:00Z)

The entry left the queue before it was built, so no checks ran against it.

mohityadav766 added a commit that referenced this pull request Oct 16, 2026
…dav-prs-combine

#34838 on main already authorizes VIEW_BASIC on both lineage edge-details
reads through LineageRepository.getLineageEdgeEnds, and removed
getLineageEdgeByFQN. LineageResource and LineageRepository take main's
version, which drops #35140's duplicate check and its now-unused
getLineageEdgeRecord. The #35140 unit tests now target getLineageEdgeEnds
and getLineageEdge; its LineageResourceIT cases are unchanged.
timothybrush pushed a commit to timothybrush/OpenMetadata that referenced this pull request Oct 16, 2026
…, SAML tenant GUIDs, dead-code removals (open-metadata#35537)

* Fixes open-metadata#35106: gate certification tag strip on supportsCertification in BundleWarmupBatcher (open-metadata#35167)

* chore(searchIndex): remove unused ReindexingMetrics methods (open-metadata#35392)

* chore: remove unused TeamsMessage Fact/Action model classes (open-metadata#35386)

* chore: remove unused awaitVectorCompletionWithDetails and VectorCompletionResult (open-metadata#35389)

* Fixes open-metadata#35078: authorize VIEW_BASIC on lineage edge-details read endpoints (open-metadata#35140)

* Fixes open-metadata#34464: Accept upper/mixed-case Azure AD tenant GUIDs in SAML validation (open-metadata#34522)

---------

Co-authored-by: mohitdeuex <mohit.y@deuexsolutions.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] Lineage API: edge-details endpoints bypass authorization and domain isolation (IDOR/authorization flaw)

3 participants