Skip to content

ATLAS-5380 : Authorize bulk entity headers before returning classifica… - #734

Merged
nixonrodrigues merged 1 commit into
apache:masterfrom
VinayakMarraiya230920:ATLAS-5380
Sep 8, 2026
Merged

ATLAS-5380 : Authorize bulk entity headers before returning classifica…#734
nixonrodrigues merged 1 commit into
apache:masterfrom
VinayakMarraiya230920:ATLAS-5380

Conversation

@VinayakMarraiya230920

@VinayakMarraiya230920 VinayakMarraiya230920 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

tions

The bulk entity headers API (GET /api/atlas/v2/entity/bulk/headers?tagUpdateStartTime=...) returned entity headers including classifications without checking ENTITY_READ per entity.

The single-header API (GET /api/atlas/v2/entity/guid/{guid}/header) already enforces ENTITY_READ and returns 403 when access is denied.

So a user blocked from reading an entity via the single API could still see that entity's metadata (and classifications) through the bulk API — an authorization bypass / information disclosure.

Fix

Per review feedback (@mneethiraj), the per-entity read check is centralized in EntityGraphRetriever instead of holding AtlasTypeRegistry in the retriever:

  1. Added EntityGraphRetriever.isEntityReadAllowed(AtlasEntityHeader), which performs:
    AtlasAuthorizationUtils.isAccessAllowed(
    new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, entityHeader))
  2. Updated ClassificationAssociator.Retriever to call entityRetriever.isEntityReadAllowed(entityHeader) after loading each header, and skip unauthorized entities (omit from the result map).
  3. Removed the AtlasTypeRegistry member and the local isEntityReadAllowed(...) helper (with its typeRegistry == null bypass) from Retriever; cleaned up the now-unused constructor and imports.

Behavior after fix

API | Unauthorized user -- | -- GET .../guid/{guid}/header | 403 (unchanged) GET .../bulk/headers?... | Entity omitted from response (no leak)

Authorized users are unaffected — they still get full bulk results.

Scope: 2 main files changed (ClassificationAssociator.java, EntityGraphRetriever.java) + test; no REST contract change, no UI changes.

How was this patch tested?

Unit tests  ClassificationAssociatorTest (7/7 pass), including a new case asserting the fix:

  • auditScanYieldsOneEntity_ButNotAuthorized_EntityFilteredOut → entity is omitted when isEntityReadAllowed returns false.
  • auditScanYieldsOneEntity_EntityHeadersHasOneElementWithClassification → entity still returned when authorized (no regression).
mvn -pl repository -Dtest=ClassificationAssociatorTest test

Reporter's PoC re-run against the patched build (atlas-repository-3.0.0-SNAPSHOT):

  • The behavioral test that previously returned both tag-changed entities with their classifications to an unauthorized principal now returns an empty header set — the disclosure is no longer reproducible.

Manual, with authorization enabled (User A with access, User B without ENTITY_READ on a target entity):

  • User A creates an entity and adds a classification.
  • User B calls GET .../guid/{guid}/header → 403 ✓
  • User B calls GET .../bulk/headers?tagUpdateStartTime={beforeChange} → GUID not in response ✓
  • User A calls same bulk API → entity returned with classifications ✓ (no regression)

Build

mvn -pl repository -am compile -DskipTests

Compiles successfully.


@VinayakMarraiya230920
VinayakMarraiya230920 marked this pull request as ready for review August 20, 2026 12:08
…tions

Apply per-entity ENTITY_READ checks in ClassificationAssociator.Retriever
when building bulk headers response, matching getHeaderById behavior.
@nixonrodrigues
nixonrodrigues merged commit 1ba819c into apache:master Sep 8, 2026
2 checks passed
asf-gitbox-commits pushed a commit that referenced this pull request Sep 8, 2026
…tions (#734)

Apply per-entity ENTITY_READ checks in ClassificationAssociator.Retriever
when building bulk headers response, matching getHeaderById behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants