potiuk opened a new pull request, #72655:
URL: https://github.com/apache/airflow/pull/72655
> **Draft — the core question is a product decision. See "Question for
> maintainers". Not ready to merge as-is; two known gaps are listed at the
end.**
Airflow authenticates the core API with a router-level `Depends(get_user)`
on the
public and ui routers. A plugin app is attached with `app.mount()`, and a
Starlette mount **has its own route table and inherits no dependencies from
its
parent**, so that dependency never reaches a plugin's routes.
`init_middlewares`
adds only JWT-refresh, gzip and access-log middlewares, none of which
authenticate.
A plugin that does not authenticate its own endpoints is therefore served to
anonymous callers. Verified end to end — against unmodified `main`:
```
UNAUTHENTICATED GET /demo/secret -> 200 {"data":"sensitive"}
```
**The documented example is exactly that shape.** The `fastapi_apps` sample
in
`plugins.rst` ships a plain route and never mentions authentication, so a
deployment following the docs exposes plugin endpoints pre-auth. The insecure
pattern is the one we teach.
### What this branch does
Mounts every plugin app behind a `PluginAuthenticationMiddleware` that
resolves
the requesting user the same way the core API does and returns the core
API's 401
shape when there is none. Same request now returns `401 {"detail":"Not
authenticated"}`.
A plugin that deliberately serves anonymous callers declares `"public":
True`.
Credential extraction is now shared with `TeamAuthorizationMiddleware` rather
than duplicated — duplicated credential selection is what let the logout
route
and `get_user` drift apart elsewhere. Team-scoped apps are now authenticated
*and* team-authorized: the team check answers whether a user may reach that
team,
which presumes there is a user.
## Question for maintainers
**Should plugin apps be authenticated by default?**
This is a behaviour change for any plugin relying on being reachable without
credentials, and it is why this is a draft. The options:
1. **Default-on, as here** — plugins opt out with `"public": True`. Safe
default,
breaks plugins that serve anonymous endpoints today, needs a newsfragment.
2. **Default-off, docs only** — leave the behaviour, fix `plugins.rst` to
teach
authentication and document the exposure. No break; the footgun stays
loaded.
3. **Default-on behind a config flag** for one release, defaulting to off,
then
flipped.
I did not want to pick this unilaterally.
## Two known gaps, both deliberate pending that answer
* **WebSocket routes bypass this.** `BaseHTTPMiddleware` only dispatches
`http`
scopes and passes `websocket` through, so a plugin's WebSocket routes are
still
unauthenticated. **This pre-dates the change** —
`TeamAuthorizationMiddleware`
is already `BaseHTTPMiddleware`, so team-scoped plugin WebSockets have
always
bypassed the team check too. Closing it means converting both middlewares
to
raw ASGI, which widens the blast radius; it is worth doing but only once
the
question above is settled.
* **`"public": True` is app-wide.** A plugin with one health check and
several
privileged endpoints must expose the whole sub-app to exempt the one route,
which pushes authors toward the insecure choice. A route allowlist or a
separate public mount would be better; the right shape depends on option 1
vs 3.
### Testing
29 tests pass across the middleware suite. New coverage: an unauthenticated
plugin route is refused and its payload never returned; `public: True` opts
out;
a team-scoped app carries both middlewares. The credential-extraction tests
moved
from the team middleware's suite to the shared resolver's, following the
code.
Two pre-existing failures in `test_hitl.py` reproduce identically on
unmodified
`main`.
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes (please specify the tool below)
Generated-by: Claude Code following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
--
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]