databrickslabs / databrickslabs/ontos
[Bug]: Data Consumer gets 403 on GET /assets/{id} even when asset is linked to an active Data Product
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 212
- Forks
- 71
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 43
Description
Summary
A Data Consumer navigating to an asset detail page (/assets/<id>) receives a 403 even when:
- The asset is explicitly linked to a Data Product (via a Deliverable / OutputPort)
- That Data Product has
activestatus
Steps to reproduce
- Create a Data Product with status
active - Add an asset as a Deliverable (OutputPort → linked asset via
portHasTable/portHasViewetc.) - Switch to the Data Consumer role
- Navigate directly to
/assets/<asset-id>(e.g. by clicking the asset link on the DP detail page)
Expected: Asset detail page loads — consumer has access because the asset is attached to a published DP.
Actual: 403 — "Asset is not linked to a Data Product accessible to this user."
Root cause
AssetsManager.resolve_accessible_asset_ids (called from GET /api/assets/{id} consumer path) delegates to DataProductsManager.list_products(is_admin=False) with no caller context (no caller_email, no caller_team_ids, no caller_project_ids).
DataProductsRepository.get_multi has a fail-closed guard: when is_admin=False and all three scope inputs are None, it returns [] immediately rather than applying any status filter. This was intentional for the DP listing endpoint, but resolve_accessible_asset_ids relies on the old assumption that list_products(is_admin=False) returns at least the published (active/deprecated) DPs.
The result: resolve_accessible_asset_ids always returns an empty set for any non-admin caller → every asset is denied → 403.
Affected file
src/backend/src/controller/assets_manager.py — resolve_accessible_asset_ids method.
Proposed fix
The purpose of resolve_accessible_asset_ids is "which assets can a consumer see via the marketplace?" — i.e. assets of published DPs, regardless of caller ownership. The fix is to fetch all products with is_admin=True and filter locally to consumer-visible statuses:
from src.common.version_visibility import is_visible_consumer
products = data_products_manager.list_products(
skip=0, limit=10_000, is_admin=True,
)
products = [p for p in products if is_visible_consumer(p)]
This matches the catalogue/marketplace contract: published (active/deprecated) DP assets are readable by any caller with data-products:READ_ONLY.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/backend/src/controller/assets_manager.py at resolve_accessible_asset_ids, then trace its GET /api/assets/{id} caller and the DataProductsManager.list_products fail-closed behavior. Check the is_visible_consumer rule against active and deprecated products. Done when a consumer can load an asset linked to a published Data Product while unrelated assets remain denied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, authorization, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100