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 c42c74df92f [v3-2-test] UI: Block polling requests to endpoints that
returned 403 Forbidden (#64333) (#64492)
c42c74df92f is described below
commit c42c74df92f5c64261bcf31ef23894f59a767384
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Mar 31 00:09:37 2026 +0530
[v3-2-test] UI: Block polling requests to endpoints that returned 403
Forbidden (#64333) (#64492)
* UI: Block polling requests to endpoints that returned 403 Forbidden
Adds axios interceptors to track URLs that return 403 and abort
subsequent requests to those URLs. Permissions don't change mid-session,
so this prevents wasted polling traffic without requiring per-component
changes.
* UI: Only block polling for permission-based 403s, not auth-related ones
Narrow the 403 URL tracking to responses with detail "Forbidden"
(missing permissions). Auth-related 403s like "Invalid JWT token"
are left alone to trigger the login redirect.
---------
(cherry picked from commit 3e3b44cd4fefba2beef91c7468f5dc678ab21f59)
Co-authored-by: Pierre Jeambrun <[email protected]>
Co-authored-by: Rahul Vats <[email protected]>
---
airflow-core/src/airflow/ui/src/main.tsx | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/airflow-core/src/airflow/ui/src/main.tsx
b/airflow-core/src/airflow/ui/src/main.tsx
index 44d9934f75e..9fb55690e4c 100644
--- a/airflow-core/src/airflow/ui/src/main.tsx
+++ b/airflow-core/src/airflow/ui/src/main.tsx
@@ -48,6 +48,23 @@ Reflect.set(globalThis, "ReactRouterDOM", ReactRouterDOM);
Reflect.set(globalThis, "ChakraUI", ChakraUI);
Reflect.set(globalThis, "EmotionReact", EmotionReact);
+// URLs that returned 403 Forbidden. Permissions won't change mid-session,
+// so we block further requests to avoid spamming the server with polling.
+const forbidden403Urls = new Set<string>();
+
+// Block outgoing requests to URLs that previously returned 403.
+// The request is aborted immediately so no network traffic occurs.
+axios.interceptors.request.use((config) => {
+ if (config.url !== undefined && forbidden403Urls.has(config.url)) {
+ const controller = new AbortController();
+
+ controller.abort();
+ config.signal = controller.signal;
+ }
+
+ return config;
+});
+
// redirect to login page if the API responds with unauthorized or forbidden
errors
axios.interceptors.response.use(
(response) => response,
@@ -64,6 +81,16 @@ axios.interceptors.response.use(
globalThis.location.replace(`${loginPath}?${params.toString()}`);
}
+ // Track permission-based 403 URLs so future polling requests are blocked
at the request interceptor.
+ // Only block "Forbidden" (missing permissions), not other auth-related
403s.
+ if (
+ error.response?.status === 403 &&
+ error.response.data.detail === "Forbidden" &&
+ error.config?.url !== undefined
+ ) {
+ forbidden403Urls.add(error.config.url);
+ }
+
return Promise.reject(error);
},
);