You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ra...@apache.org on 2026/04/15 05:28:01 UTC

(airflow) branch v3-2-test updated: [v3-2-test] Fix: add RUN, HITL_DETAIL, TASK_INSTANCE entities to /dags endpoint as it returns nested entities in response (#64822) (#65225)

This is an automated email from the ASF dual-hosted git repository.

rahulvats pushed a commit to branch v3-2-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-2-test by this push:
     new b45201274bc [v3-2-test] Fix: add RUN, HITL_DETAIL, TASK_INSTANCE entities to /dags endpoint as it returns nested entities in response (#64822) (#65225)
b45201274bc is described below

commit b45201274bc9a8c08dbb08f6a580b950c497b017
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Wed Apr 15 10:57:53 2026 +0530

    [v3-2-test] Fix: add RUN, HITL_DETAIL, TASK_INSTANCE entities to /dags endpoint as it returns nested entities in response (#64822) (#65225)
    
    [v3-2-test] Fix: add RUN, HITL_DETAIL, TASK_INSTANCE entities to /dags endpoint as it returns nested entities in response (#64822) (#65225)
    Co-authored-by: Kevin Yang <85...@users.noreply.github.com>
---
 airflow-core/newsfragments/64822.significant.rst   |  1 +
 .../airflow/api_fastapi/core_api/routes/ui/dags.py |  3 +++
 .../api_fastapi/core_api/routes/ui/test_dags.py    | 25 ++++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/airflow-core/newsfragments/64822.significant.rst b/airflow-core/newsfragments/64822.significant.rst
new file mode 100644
index 00000000000..348700d4d1f
--- /dev/null
+++ b/airflow-core/newsfragments/64822.significant.rst
@@ -0,0 +1 @@
+Users who only have read access to DAGs will no longer be able to fetch data from the ``/dags`` endpoint, as it now requires additional permissions (``DagAccessEntity.RUN``, ``DagAccessEntity.HITL_DETAIL``, and ``DagAccessEntity.TASK_INSTANCE``). This change was made because the endpoint returns aggregated data from these multiple entities. Please update your custom user roles to include read access for DAG Runs, Task Instances, and HITL Details if those users should still have access to [...]
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
index 41da300e5d8..e00fb085a9d 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py
@@ -78,6 +78,9 @@ dags_router = AirflowRouter(prefix="/dags", tags=["DAG"])
     response_model_exclude_none=True,
     dependencies=[
         Depends(requires_access_dag(method="GET")),
+        Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.RUN)),
+        Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.HITL_DETAIL)),
+        Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.TASK_INSTANCE)),
     ],
     operation_id="get_dags_ui",
 )
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
index 801f8754ed1..717a2cecb95 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
@@ -24,6 +24,8 @@ import pytest
 from fastapi.testclient import TestClient
 from sqlalchemy.orm import Session
 
+from airflow.api_fastapi.auth.managers.models.resource_details import DagAccessEntity
+from airflow.api_fastapi.auth.managers.simple.simple_auth_manager import SimpleAuthManager
 from airflow.models import DagRun
 from airflow.models.dag import DagModel, DagTag
 from airflow.models.dag_favorite import DagFavorite
@@ -235,6 +237,29 @@ class TestGetDagRuns(TestPublicDagEndpoint):
         response = unauthorized_test_client.get("/dags", params={})
         assert response.status_code == 403
 
+    @pytest.mark.parametrize(
+        "denied_entity",
+        [
+            DagAccessEntity.RUN,
+            DagAccessEntity.HITL_DETAIL,
+            DagAccessEntity.TASK_INSTANCE,
+        ],
+    )
+    def test_should_response_403_on_missing_entity_permission(self, test_client, denied_entity):
+        """Users lacking any sub-entity permission should receive 403 on the DAG list."""
+        original_is_authorized = SimpleAuthManager.is_authorized_dag
+
+        def restricted_is_authorized_dag(self, *, method, user, access_entity=None, details=None):
+            if access_entity == denied_entity:
+                return False
+            return original_is_authorized(
+                self, method=method, user=user, access_entity=access_entity, details=details
+            )
+
+        with mock.patch.object(SimpleAuthManager, "is_authorized_dag", restricted_is_authorized_dag):
+            response = test_client.get("/dags")
+        assert response.status_code == 403
+
     def test_get_dags_no_n_plus_one_queries(self, session, test_client):
         """Test that fetching DAGs with tags doesn't trigger n+1 queries."""
         num_dags = 5