Skip to content

Hide assets the caller may not read from the UI dependencies graph - #73008

Open
henry3260 wants to merge 2 commits into
apache:mainfrom
henry3260:fix-dependencies-graph-assets-authz
Open

henry3260 wants to merge 2 commits into
apache:mainfrom
henry3260:fix-dependencies-graph-assets-authz

Conversation

@henry3260

Copy link
Copy Markdown
Contributor

Why

GET /ui/dependencies scopes its graph by which Dags the caller may read, but never by which assets. Both modes leak asset identity to a caller who can read a Dag but not one of its assets:

  • dependency_type=scheduling expands each readable Dag's asset_expression into asset nodes whose label is the asset name.
  • dependency_type=data guards the root asset only by checking that some connected Dag is readable. Once that passes, the whole lineage graph is expanded with asset names, and the traversal keeps walking outward through assets the caller may not read.

The rest of the asset API already scopes responses with ReadableAssetsFilterDep (#72682), and #72864 applies the same per-asset readability to asset expressions. Asset names commonly encode bucket, table or dataset names, so this is the same class of gap.

What

  • airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dependencies.py: inject ReadableAssetsFilterDep and pass the readable asset ids to both service functions.
  • airflow-core/src/airflow/api_fastapi/core_api/services/ui/dependencies.py:
    • New hide_unreadable_assets post-processes the finished graph, dropping asset nodes the caller may not read and every edge touching them. Alias and ref nodes carry no asset id to authorize on and are left in place, matching Hide unreadable assets in the asset expression served by next_run_assets #72864.
    • get_data_dependencies returns the same empty result as an unrelated asset when the root asset is unreadable, so the route's existing 404 path serves it and the endpoint is not an oracle for asset ids. The BFS intersects each round with the readable set so it does not expand through an unreadable asset.

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Fable 5.1)

The dependencies graph scoped its nodes by which Dags the caller may read,
but never by which assets. A caller who can read a Dag saw every asset that
Dag produces or consumes, name included, even when the auth manager scopes
that asset away from them; the data graph would also expand outward through
such an asset. Asset names commonly encode bucket, table or dataset names,
so this is the same class of gap the rest of the asset API closed.
An asset_expression leaf whose id the Dag processor has not filled in yet
cannot be authorized, so it must be hidden like any other asset the caller
may not read. The data graph instead parsed the id out of the node, which
failed the request outright rather than dropping the node.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:API Airflow's REST/HTTP API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants