bmatticus opened a new issue, #70389:
URL: https://github.com/apache/airflow/issues/70389

   ### Apache Airflow version
   
   3.3.0
   
   ### If "Other Airflow 2 version" selected, which one?
   
   _No response_
   
   ### What happened?
   
   When Airflow is deployed behind a reverse proxy under a URL subpath (a 
documented/supported pattern using `[fab] enable_proxy_fix = True` + `[api] 
base_url` + the proxy sending `X-Forwarded-Prefix`), the FAB-rendered Security 
pages (`/auth/roles/list/`, `/auth/users/list/`) generate "Add" / "Edit" / 
"Show" action links that are **missing the `/auth` blueprint prefix**.
   
   For example, with subpath `/myns/myrelease`:
   - Expected: `/myns/myrelease/auth/roles/add`
   - Actual: `/myns/myrelease/roles/add`
   
   Since the FAB blueprint is mounted under `/auth`, the broken link (missing 
`/auth`) resolves instead to the new React SPA shell, which has no client-side 
route for `roles`/`users` paths and silently redirects/bounces the user back to 
the Dashboard — with no visible error. This makes it effectively impossible to 
add/edit/view Roles or Users from the UI when Airflow is served under a subpath.
   
   Notably, the List/Edit page URLs themselves (e.g. `/auth/roles/list/`) are 
correctly generated with the `/auth` prefix — it's specifically the row/page 
"Add", "Edit", and "Show" action links produced by FAB's ModelView machinery 
that drop the prefix, and only when `X-Forwarded-Prefix`/ProxyFix subpath 
handling is active.
   
   ### What you think should happen instead?
   
   The "Add"/"Edit"/"Show" action links on FAB Security views should include 
the `/auth` blueprint prefix (consistent with the page's own list/edit URLs), 
regardless of whether the app is served under a subpath via 
ProxyFix/`X-Forwarded-Prefix`.
   
   ### How to reproduce
   
   Minimal, clean-room repro with **no custom Helm chart / ingress / Istio** 
involved — plain `apache/airflow:3.3.0-python3.12` Docker image, FAB auth 
manager, default `webserver_config.py` with `AUTH_TYPE = AUTH_DB`.
   
   **Control (no subpath) — works correctly:**
   ```bash
   docker run -d --name airflow-repro -p 18080:8080 \
     -e 
AIRFLOW__CORE__AUTH_MANAGER=airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager
 \
     -e AIRFLOW__CORE__EXECUTOR=LocalExecutor \
     -e AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=sqlite:////opt/airflow/airflow.db \
     -v /path/to/webserver_config.py:/opt/airflow/webserver_config.py:ro \
     apache/airflow:3.3.0-python3.12 bash -c "airflow db migrate && (airflow 
scheduler &) && airflow api-server --port 8080"
   
   docker exec airflow-repro airflow users create --username admin --firstname 
A --lastname B \
     --email [email protected] --role Admin --password admin
   ```
   Log in at `http://localhost:18080/auth/login/`, navigate to 
`http://localhost:18080/auth/roles/list/`.
   The "Add" button's href is `/auth/roles/add` — correct.
   
   **Subpath repro (same image, add these two envs, and simulate a reverse 
proxy sending `X-Forwarded-Prefix`):**
   ```bash
   docker run -d --name airflow-repro -p 18080:8080 \
     -e 
AIRFLOW__CORE__AUTH_MANAGER=airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager
 \
     -e AIRFLOW__CORE__EXECUTOR=LocalExecutor \
     -e AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=sqlite:////opt/airflow/airflow.db \
     -e AIRFLOW__FAB__ENABLE_PROXY_FIX=True \
     -e AIRFLOW__API__BASE_URL=https://example.com/myns/myrelease \
     -v /path/to/webserver_config.py:/opt/airflow/webserver_config.py:ro \
     apache/airflow:3.3.0-python3.12 bash -c "airflow db migrate && (airflow 
scheduler &) && airflow api-server --port 8080"
   ```
   Then make requests with an added header `X-Forwarded-Prefix: 
/myns/myrelease` (e.g. via a browser extension, a small proxy, or Playwright 
request interception) while browsing 
`http://localhost:18080/myns/myrelease/auth/roles/list/`.
   
   The "Add" button's href is now `/myns/myrelease/roles/add` — **missing 
`/auth`**. Navigating to it loads the SPA shell instead of the FAB add-role 
form, and the SPA immediately redirects to the Dashboard since it has no 
client-side route matching `roles`/`users` paths.
   
   Same image, same FAB version — only the proxy-fix/subpath config differs 
between the working and broken case.
   
   ### Operating System
   
   Debian (apache/airflow official Docker image base), also reproduced on 
AKS/Kubernetes with Istio ingress
   
   ### Versions of Apache Airflow Providers
   
   apache-airflow-providers-fab (bundled with Airflow 3.3.0)
   
   ### Deployment
   
   Other Docker-based deployment
   
   ### Deployment details
   
   Also reproduced in a Kubernetes deployment behind an Istio Ingress 
Gateway/VirtualService, with `[fab] enable_proxy_fix = True` and `[api] 
base_url` set to the subpath, and `X-Forwarded-Prefix` set by the ingress. 
Confirmed the ingress/VirtualService routing itself is not the cause (verified 
byte-identical FAB static assets, correct base_url resolution, correct ProxyFix 
redirect behavior for unauthenticated pages) — isolated the bug down to just 
the two Airflow-side config values (`enable_proxy_fix` + 
`base_url`/`X-Forwarded-Prefix`) via the clean-room Docker repro above.
   
   ### Anything else?
   
   This will affect any Airflow 3.x deployment using the FAB auth manager 
behind a reverse proxy serving Airflow under a URL subpath — a pattern 
explicitly documented and supported via `[fab] enable_proxy_fix`. Since the 
failure mode is a silent redirect to the Dashboard with no error message, it 
may be underreported/hard to notice at first (it looks like the button "does 
nothing").
   
   ### Are you willing to submit a PR?
   
   - [ ] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's Code of Conduct
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to