This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 04e7d6c2a0e Clarify auth and add an authorization example for plugin
FastAPI apps (#72935)
04e7d6c2a0e is described below
commit 04e7d6c2a0ec3baaccccb66269245d7cb14dcc51
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Fri Sep 11 12:52:27 2026 +0200
Clarify auth and add an authorization example for plugin FastAPI apps
(#72935)
Follow-up to #72655. The core API applies its authentication dependencies
at the router level and, for some endpoints, per route, so the docs should
not imply router-level only. And because authentication is not
authorization, show how a plugin enforces a permission check with the same
access helpers the core API uses (requires_access_dag).
---
.../docs/administration-and-deployment/plugins.rst | 26 ++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/airflow-core/docs/administration-and-deployment/plugins.rst
b/airflow-core/docs/administration-and-deployment/plugins.rst
index 7784df244a6..d215940c054 100644
--- a/airflow-core/docs/administration-and-deployment/plugins.rst
+++ b/airflow-core/docs/administration-and-deployment/plugins.rst
@@ -234,10 +234,11 @@ definitions in Airflow.
**Airflow does not authenticate plugin FastAPI apps. Authenticating them
is the
plugin author's responsibility.**
- Airflow authenticates the core API with a router-level dependency. A
plugin app is
- attached with ``app.mount()``, and a Starlette mount has its own route
table and
- inherits none of the parent's dependencies, so that dependency never
reaches a
- plugin's routes. No middleware in the API server authenticates them either.
+ Airflow authenticates the core API with authentication dependencies,
declared at the
+ router level and, for some endpoints, per route. A plugin app is attached
with
+ ``app.mount()``, and a Starlette mount has its own route table and
inherits none of the
+ parent's dependencies, so those dependencies never reach a plugin's
routes. No
+ middleware in the API server authenticates them either.
Every route a plugin exposes is therefore reachable by **anonymous
callers** unless
the plugin authenticates it itself. The minimal ``app`` above is a
structural
@@ -274,6 +275,23 @@ definitions in Airflow.
applies to team scoping too — in a multi-team deployment, a plugin that
does not check
the caller's team serves every team's users the same data.
+ The core API's access helpers can enforce that decision for you. For
example,
+ ``requires_access_dag`` restricts a route to callers allowed the requested
action on a
+ Dag; it authenticates the caller and reads the ``dag_id`` from the request:
+
+ .. code-block:: python
+
+ from fastapi import Depends, FastAPI
+
+ from airflow.api_fastapi.core_api.security import requires_access_dag
+
+ app = FastAPI()
+
+
+ @app.get("/dags/{dag_id}",
dependencies=[Depends(requires_access_dag(method="GET"))])
+ def dag_detail(dag_id: str):
+ return {"dag_id": dag_id}
+
.. code-block:: python
# Creating a FastAPI middleware that will operates on all the server api
requests.