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]