Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion airflow-core/docs/redirects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ administration-and-deployment/security/access-control/index.rst ../apache-airflo
administration-and-deployment/security/api.rst security/api.rst
administration-and-deployment/security/audit_logs.rst security/audit_logs.rst
administration-and-deployment/security/flower.rst security/flower.rst
administration-and-deployment/security/webserver.rst security/webserver.rst
administration-and-deployment/security/webserver.rst ../apache-airflow-providers-fab/stable/auth-manager/security.rst
administration-and-deployment/security/workload.rst security/workload.rst
administration-and-deployment/security/secrets/secrets-backends/index.rst security/secrets/secrets-backends/index.rst
administration-and-deployment/security/secrets/secrets-backends/local-filesystem-secrets-backend.rst security/secrets/secrets-backends/local-filesystem-secrets-backend.rst
Expand Down
59 changes: 40 additions & 19 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@
if PACKAGE_NAME != "apache-airflow":
global_substitutions["experimental"] = "This is an :external:ref:`experimental feature <experimental>`."


# == Sphinx configuration ======================================================

# -- Project information -------------------------------------------------------
Expand Down Expand Up @@ -168,6 +167,21 @@
"substitution_extensions",
"sphinx_design",
]


packages_with_redoc = ["apache-airflow", "apache-airflow-providers-fab"]
if PACKAGE_NAME in packages_with_redoc:
extensions.extend(
[
"autoapi.extension",
# First, generate redoc
"sphinxcontrib.redoc",
# Second, update redoc script
"sphinx_script_update",
]
)


if PACKAGE_NAME == "apache-airflow":
extensions.extend(
[
Expand All @@ -176,14 +190,9 @@
"sphinxcontrib.httpdomain",
"sphinxcontrib.httpdomain",
"extra_files_with_substitutions",
# First, generate redoc
"sphinxcontrib.redoc",
# Second, update redoc script
"sphinx_script_update",
]
)

if PACKAGE_NAME == "apache-airflow-providers":
elif PACKAGE_NAME == "apache-airflow-providers":
extensions.extend(
[
"sphinx_jinja",
Expand All @@ -203,8 +212,9 @@
"providers_extensions",
]
)
else:
elif PACKAGE_NAME not in packages_with_redoc:
extensions.append("autoapi.extension")

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns: list[str]
Expand Down Expand Up @@ -888,6 +898,10 @@ def filter_ignore(record: logging.LogRecord) -> bool:

# -- Options for sphinxcontrib.redoc -------------------------------------------
# See: https://sphinxcontrib-redoc.readthedocs.io/en/stable/
if PACKAGE_NAME in packages_with_redoc:
# Options for script updater
redoc_script_url = "https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.48/bundles/redoc.standalone.js"

if PACKAGE_NAME == "apache-airflow":
OPENAPI_FILE = (
Path(__file__).parents[1]
Expand All @@ -910,27 +924,34 @@ def filter_ignore(record: logging.LogRecord) -> bool:
},
},
]

# Options for script updater
redoc_script_url = "https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.48/bundles/redoc.standalone.js"

elif PACKAGE_NAME == "apache-airflow-providers-fab":
OPENAPI_FILE = Path(__file__).parents[1] / "providers" / "fab" / "auth_manager" / "openapi" / "v1.yaml"
from airflow.providers.fab.auth_manager import __file__ as auth_manager_path

fab_flask_openapi_file = Path(auth_manager_path).parent.joinpath("openapi", "v1.yaml")
fab_fastapi_openapi_file = Path(auth_manager_path).parent.joinpath(
"api_fastapi", "openapi", "v1-generated.yaml"
)
redoc = [
{
"name": "Fab provider REST API",
"page": "stable-rest-api-ref",
"spec": OPENAPI_FILE.as_posix(),
"name": "Fab auth manager API",
"page": "api-ref/fab-public-api-ref",
"spec": fab_flask_openapi_file.as_posix(),
"opts": {
"hide-hostname": True,
"no-auto-auth": True,
},
},
{
"name": "Fab auth manager token API",
"page": "api-ref/fab-token-api-ref",
"spec": fab_fastapi_openapi_file.as_posix(),
"opts": {
"hide-hostname": True,
"no-auto-auth": True,
},
},
]

# Options for script updater
redoc_script_url = "https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.48/bundles/redoc.standalone.js"


def skip_util_classes(app, what, name, obj, skip, options):
if what == "data" and "STATICA_HACK" in name:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
specific language governing permissions and limitations
under the License.

REST API Reference
==================
FAB auth manager API
====================

It's a stub file. It will be converted automatically during the build process
to the valid documentation by the Sphinx plugin. See: /docs/conf.py
22 changes: 22 additions & 0 deletions providers/fab/docs/api-ref/fab-token-api-ref.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

.. Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

.. http://www.apache.org/licenses/LICENSE-2.0

.. Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

FAB auth manager token API
==========================

It's a stub file. It will be automatically converted during the build process into valid documentation by the Sphinx plugin. See: /docs/conf.py
17 changes: 10 additions & 7 deletions providers/fab/docs/auth-manager/access-control.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
specific language governing permissions and limitations
under the License.

Access Control
==============
Access Control with FAB auth manager
====================================

Access Control of Airflow Webserver UI is handled by Flask AppBuilder (FAB).
FAB auth manager access control is handled by Flask AppBuilder (FAB).
Please read its related `security document <http://flask-appbuilder.readthedocs.io/en/latest/security.html>`_
regarding its security model.

Expand All @@ -33,7 +33,7 @@ regarding its security model.

Default Roles
'''''''''''''
Airflow ships with a set of roles by default: Admin, User, Op, Viewer, and Public.
FAB auth manager ships with a set of roles by default: Admin, User, Op, Viewer, and Public.
By default, only ``Admin`` users can configure/alter permissions for roles. However,
it is recommended that these default roles remain unaltered, and instead ``Admin`` users
create new roles with the desired permissions if changes are necessary.
Expand Down Expand Up @@ -110,7 +110,7 @@ Permissions

.. warning::

Airflow allows you to define custom Roles with fine-grained RBAC permissions for users. However, not all
FAB auth manager allows you to define custom Roles with fine-grained RBAC permissions for users. However, not all
combinations of permissions are fully consistent, and there is no mechanism to make sure that the set of
permissions assigned is fully consistent. There are a number of cases where permissions for
particular resources are overlapping. A good example is menu access permissions - a lack of menu access
Expand All @@ -125,7 +125,7 @@ Permissions
Resource-Based permissions
^^^^^^^^^^^^^^^^^^^^^^^^^^

Starting with version 2.0, permissions are based on individual resources and a small subset of actions on those
Permissions are based on individual resources and a small subset of actions on those
resources. Resources match standard Airflow concepts, such as ``Dag``, ``DagRun``, ``Task``, and
``Connection``. Actions include ``can_create``, ``can_read``, ``can_edit``, and ``can_delete``.

Expand All @@ -138,7 +138,10 @@ There are five default roles: Public, Viewer, User, Op, and Admin. Each one has
DAG-level permissions
^^^^^^^^^^^^^^^^^^^^^

For DAG-level permissions exclusively, access can be controlled at the level of all DAGs or individual DAG objects. This includes ``DAGs.can_read``, ``DAGs.can_edit``, ``DAGs.can_delete``, ``DAG Runs.can_read``, ``DAG Runs.can_create``, ``DAG Runs.can_delete``, and ``DAG Runs.menu_access``. When these permissions are listed, access is granted to users who either have the listed permission or the same permission for the specific DAG being acted upon. For individual DAGs, the resource name is ``DAG:`` + the DAG ID, or for the DAG Runs resource the resource name is ``DAG Run:``.
For DAG-level permissions exclusively, access can be controlled at the level of all DAGs or individual DAG objects.
This includes ``DAGs.can_read``, ``DAGs.can_edit``, ``DAGs.can_delete``, ``DAG Runs.can_read``, ``DAG Runs.can_create``, ``DAG Runs.can_delete``, and ``DAG Runs.menu_access``.
When these permissions are listed, access is granted to users who either have the listed permission or the same permission for the specific DAG being acted upon.
For individual DAGs, the resource name is ``DAG:`` + the DAG ID, or for the DAG Runs resource the resource name is ``DAG Run:``.

For example, if a user is trying to view DAG information for the ``example_dag_id``, and the endpoint requires ``DAGs.can_read`` access, access will be granted if the user has either ``DAGs.can_read`` or ``DAG:example_dag_id.can_read`` access.

Expand Down
59 changes: 13 additions & 46 deletions providers/fab/docs/auth-manager/api-authentication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,25 @@
specific language governing permissions and limitations
under the License.

API Authentication
==================
FAB auth manager API authentication
===================================

Authentication for the API is handled separately to the Web Authentication. The default is to
check the user session:
.. note::
This guide only applies to :doc:`FAB auth manager API </api-ref/fab-public-api-ref>`.

Authentication for the APIs is handled by what is called an authentication backend. The default is to check the user session:

.. code-block:: ini

[api]
[fab]
auth_backends = airflow.providers.fab.auth_manager.api.auth.backend.session

.. versionchanged:: 1.10.11

In Airflow <1.10.11, the default setting was to allow all API requests without authentication, but this
posed security risks for if the Webserver is publicly accessible.

.. versionchanged:: 2.3.0

In Airflow <2.3.0 this setting was ``auth_backend`` and allowed only one
value. In 2.3.0 it was changed to support multiple backends that are tried
in turn.

If you want to check which authentication backends are currently set, you can use ``airflow config get-value api auth_backends``
If you want to check which authentication backends are currently set, you can use ``airflow config get-value fab auth_backends``
command as in the example below.

.. code-block:: console

$ airflow config get-value api auth_backends
$ airflow config get-value fab auth_backends
airflow.providers.fab.auth_manager.api.auth.backend.basic_auth

.. versionchanged:: 3.0.0
Expand All @@ -51,30 +42,6 @@ command as in the example below.
This approach is independent from which ``auth_backend`` is used.
The default setting is using Airflow public API to create a token (JWT) first and use this token in the requests to access the API.


JWT Token based authentication
''''''''''''''''''''''''''''''
The JWT token based authentication is the default setting for the API.
To be able to use the Airflow Public API, you need to create a token first and use this token in the requests to access the API.

Endpoints are populated under ``/auth`` path. These endpoints are mounted to the Airflow API.
You should use your username and password, as seen in the example below.
The token is valid for seconds defined in ``auth_jwt_expiration_time`` which can be set from ``airflow.cfg``.

Example of creating a token:
.. code-block:: bash

curl -X 'POST' \
'http://localhost:32784/auth/token' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"username": "username",
"password": "password"
}'

This process will return a token that you can use in the requests to access the API.

Kerberos authentication
'''''''''''''''''''''''

Expand All @@ -84,7 +51,7 @@ To enable Kerberos authentication, set the following in the configuration:

.. code-block:: ini

[api]
[fab]
auth_backends = airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth

[kerberos]
Expand All @@ -109,7 +76,7 @@ work. This means that your user name should be ``user_name@REALM``.

.. note::

Remember that the stable API is secured by both authentication and `access control <./access-control.html>`_.
Remember that the APIs are secured by both authentication and `access control <./access-control.html>`_.
This means that your user needs to have a Role with necessary associated permissions, otherwise you'll receive
a 403 response.

Expand All @@ -125,7 +92,7 @@ To enable basic authentication, set the following in the configuration:

.. code-block:: ini

[api]
[fab]
auth_backends = airflow.providers.fab.auth_manager.api.auth.backend.basic_auth

Username and password needs to be base64 encoded and send through the
Expand Down Expand Up @@ -162,7 +129,7 @@ and may have one of the following to support API client authorizations used by :
* function ``create_client_session() -> requests.Session``
* attribute ``CLIENT_AUTH: tuple[str, str] | requests.auth.AuthBase | None``

After writing your backend module, provide the fully qualified module name in the ``auth_backends`` key in the ``[api]``
After writing your backend module, provide the fully qualified module name in the ``auth_backends`` key in the ``[fab]``
section of ``airflow.cfg``.

Additional options to your auth backend can be configured in ``airflow.cfg``, as a new option.
9 changes: 8 additions & 1 deletion providers/fab/docs/auth-manager/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@
Flask AppBuilder (FAB) auth manager
===================================

FAB auth (for authentication/authorization) manager is the auth manager that comes by default with Airflow. This auth manager defines the user authentication and user authorization by default in Airflow.
FAB auth (for authentication/authorization) manager defines the user authentication and user authorization in Airflow.
The backend used to store all entities used by the FAB auth manager is the Airflow database: :doc:`apache-airflow:database-erd-ref`.

.. image:: ../img/diagram_fab_auth_manager_airflow_architecture.png

Follow the below topics as well to understand other aspects of FAB auth manager:

* :doc:`token`. Use FAB auth manager to generate a JWT token in order to call Airflow public API
* :doc:`api-authentication`. How to authenticate the API provided by FAB auth manager
* :doc:`access-control`. How FAB auth manager manage users and permissions
* :doc:`webserver-authentication`. To learn the different options available in FAB auth manager to authenticate users
* :doc:`security`. To learn the different options available in FAB auth manager to secure the UI provided by FAB auth manager

.. toctree::
:hidden:
:maxdepth: 1
:glob:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
specific language governing permissions and limitations
under the License.

Webserver
=========
FAB auth manager UI security options
====================================

This topic describes how to configure Airflow to secure your webserver.
.. note::
This guide only applies to FAB auth manager UI pages. These pages are accessible under category "Security" in the
menu.

Rendering Airflow UI in a Web Frame from another site
------------------------------------------------------
Expand Down Expand Up @@ -48,14 +50,6 @@ Sensitive Variable fields
Variable values that are deemed "sensitive" based on the variable name will be masked in the UI automatically.
See :ref:`security:mask-sensitive-values` for more details.

.. _web-authentication:

Web Authentication
------------------

The webserver authentication is handled by the auth manager. For more information about webserver authentication, please refer to the auth manager documentation used by your environment.
By default Airflow uses the FAB auth manager, if you did not specify any other auth manager, please look at :doc:`apache-airflow-providers-fab:auth-manager/webserver-authentication`.

SSL
---

Expand Down
Loading