This is an automated email from the ASF dual-hosted git repository.
vincbeck pushed a commit to branch v3-3-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-3-test by this push:
new 7b2737c5e75 [v3-3-test] Clarify when auth managers'
is_authorized_hitl_task hook runs (#72587) (#72807)
7b2737c5e75 is described below
commit 7b2737c5e75104ba5542392384d590aa9d49c38b
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Sep 9 10:58:04 2026 -0400
[v3-3-test] Clarify when auth managers' is_authorized_hitl_task hook runs
(#72587) (#72807)
(cherry picked from commit bc7068f292ee126e709e5185997279c956a0af0f)
Co-authored-by: PoAn Yang <[email protected]>
---
airflow-core/docs/core-concepts/auth-manager/index.rst | 5 ++++-
.../src/airflow/api_fastapi/auth/managers/base_auth_manager.py | 6 +++++-
.../airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py | 4 ----
.../api_fastapi/auth/managers/simple/test_simple_auth_manager.py | 2 --
4 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/airflow-core/docs/core-concepts/auth-manager/index.rst
b/airflow-core/docs/core-concepts/auth-manager/index.rst
index 49d761b174b..556473a5e90 100644
--- a/airflow-core/docs/core-concepts/auth-manager/index.rst
+++ b/airflow-core/docs/core-concepts/auth-manager/index.rst
@@ -143,6 +143,10 @@ These authorization methods are:
* ``is_authorized_view``: Return whether the user is authorized to access a
specific view in Airflow. The view is specified through ``access_view`` (e.g.
``AccessView.CLUSTER_ACTIVITY``).
* ``is_authorized_custom_view``: Return whether the user is authorized to
access a specific view not defined in Airflow. This view can be provided by the
auth manager itself or a plugin defined by the user.
* ``filter_authorized_menu_items``: Given the list of menu items in the UI,
return the list of menu items the user has access to.
+* ``is_authorized_hitl_task``: Return whether the user is authorized to
approve or reject a Human-in-the-loop (HITL) task.
+ This is an optional method: the default implementation returns whether the
user's ID is in ``assigned_users``, the IDs of the users assigned to the task.
+ Airflow only calls this method for tasks that have assigned users. When a
task has none, Airflow skips this method and any user allowed to
+ update the task's HITL detail (``is_authorized_dag`` with
``access_entity=DagAccessEntity.HITL_DETAIL``) can respond.
It should be noted that the ``method`` parameter listed above may only have
relevance for a specific subset of the auth manager's authorization methods.
For example, the ``configuration`` resource is by definition read-only, so
only the ``GET`` parameter is relevant in the context of
``is_authorized_configuration``.
@@ -204,7 +208,6 @@ The following methods aren't required to override to have a
functional Airflow a
* ``filter_authorized_dag_ids``: Given a list of Dag IDs, return the list of
Dag IDs the user has access to. If not overridden, it calls
``is_authorized_dag`` for every single Dag passes as parameter.
* ``filter_authorized_pools``: Given a list of pool names, return the list of
pool names the user has access to. If not overridden, it calls
``is_authorized_pool`` for every single pool passed as parameter.
* ``filter_authorized_variables``: Given a list of variable keys, return the
list of variable keys the user has access to. If not overridden, it calls
``is_authorized_variable`` for every single variable passed as parameter.
-* ``is_authorized_hitl_task``: Return whether the user is authorized to
approve or reject a Human-in-the-loop (HITL) task. Override this method to
implement custom authorization logic for HITL tasks. If not overridden, it
checks if the user's ID is in the assigned users list.
CLI
^^^
diff --git
a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
index 4ba08e5b447..e8993df420a 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
@@ -387,10 +387,14 @@ class BaseAuthManager(Generic[T], LoggingMixin,
metaclass=ABCMeta):
"""
Check if a user is allowed to approve/reject a HITL task.
+ Airflow only calls this method for tasks that have assigned users.
When a task has none, Airflow
+ skips this method and any user allowed to update the task's HITL
detail (``is_authorized_dag``
+ with ``DagAccessEntity.HITL_DETAIL``) can respond.
+
By default, checks if the user's ID is in the assigned_users set.
Auth managers can override this method to implement custom logic.
- :param assigned_users: set of user IDs assigned to the task
+ :param assigned_users: set of user IDs assigned to the task, never
empty
:param user: the user to check authorization for
"""
return user.get_id() in assigned_users
diff --git
a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
index 0559a388156..d209397d34e 100644
---
a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
+++
b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
@@ -378,10 +378,6 @@ class
SimpleAuthManager(BaseAuthManager[SimpleAuthManagerUser]):
# In all-admin mode, everyone is allowed
return True
- # If no assigned_users specified, allow access
- if not assigned_users:
- return True
-
# Delegate to parent class for the actual authorization check
return super().is_authorized_hitl_task(assigned_users=assigned_users,
user=user)
diff --git
a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
index c10e1273d16..956ece124bd 100644
---
a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
+++
b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
@@ -458,8 +458,6 @@ class TestSimpleAuthManager:
(False, "user1", {"user1"}, True),
(False, "user2", {"user1"}, False),
(False, "admin", {"test_user"}, False),
- # When no assigned_users, allow access
- (False, "user1", set(), True),
],
)
def test_is_authorized_hitl_task(self, auth_manager, all_admins, user_id,
assigned_users, expected):