diff --git a/Dockerfile.ci b/Dockerfile.ci index 343a65d355dc4..86bb4738785dc 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1145,7 +1145,7 @@ function start_api_server_with_examples(){ return fi export AIRFLOW__CORE__LOAD_EXAMPLES=True - export AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True + export AIRFLOW__API__EXPOSE_CONFIG=True airflow dags reserialize echo "Example dags parsing finished" if airflow config get-value core auth_manager | grep -q "FabAuthManager"; then diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py index 1df1582591581..1509dd25e6fc9 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py @@ -70,11 +70,11 @@ def _check_expose_config() -> bool: display_sensitive: bool | None = None - if conf.get("webserver", "expose_config").lower() == "non-sensitive-only": + if conf.get("api", "expose_config").lower() == "non-sensitive-only": expose_config = True display_sensitive = False else: - expose_config = conf.getboolean("webserver", "expose_config") + expose_config = conf.getboolean("api", "expose_config") display_sensitive = True if not expose_config: diff --git a/airflow-core/src/airflow/cli/commands/config_command.py b/airflow-core/src/airflow/cli/commands/config_command.py index b953e61d09c0a..0f5c5df5ba157 100644 --- a/airflow-core/src/airflow/cli/commands/config_command.py +++ b/airflow-core/src/airflow/cli/commands/config_command.py @@ -495,6 +495,10 @@ def message(self) -> str | None: renamed_to=ConfigParameter("fab", "proxy_fix_x_prefix"), breaking=True, ), + ConfigChange( + config=ConfigParameter("webserver", "expose_config"), + renamed_to=ConfigParameter("api", "expose_config"), + ), ConfigChange( config=ConfigParameter("webserver", "cookie_secure"), was_deprecated=False, diff --git a/airflow-core/src/airflow/config_templates/config.yml b/airflow-core/src/airflow/config_templates/config.yml index a14efca725514..5cb51a56ebdd3 100644 --- a/airflow-core/src/airflow/config_templates/config.yml +++ b/airflow-core/src/airflow/config_templates/config.yml @@ -1284,6 +1284,15 @@ secrets: api: description: ~ options: + expose_config: + description: | + Expose the configuration file in the web server. Set to ``non-sensitive-only`` to show all values + except those that have security implications. ``True`` shows all values. ``False`` hides the + configuration completely. + version_added: ~ + type: string + example: ~ + default: "False" base_url: description: | The base url of the API server. Airflow cannot guess what domain or CNAME you are using. @@ -1705,15 +1714,6 @@ webserver: sensitive: true example: ~ default: "{SECRET_KEY}" - expose_config: - description: | - Expose the configuration file in the web server. Set to ``non-sensitive-only`` to show all values - except those that have security implications. ``True`` shows all values. ``False`` hides the - configuration completely. - version_added: ~ - type: string - example: ~ - default: "False" expose_hostname: description: | Expose hostname in the web server diff --git a/airflow-core/src/airflow/configuration.py b/airflow-core/src/airflow/configuration.py index c48377c333ccb..ff214b3138ad7 100644 --- a/airflow-core/src/airflow/configuration.py +++ b/airflow-core/src/airflow/configuration.py @@ -355,6 +355,7 @@ def sensitive_config_values(self) -> set[tuple[str, str]]: ("api", "ssl_key"): ("webserver", "web_server_ssl_key", "3.0"), ("api", "access_logfile"): ("webserver", "access_logfile", "3.0"), ("triggerer", "capacity"): ("triggerer", "default_capacity", "3.0"), + ("api", "expose_config"): ("webserver", "expose_config", "3.0.1"), } # A mapping of new section -> (old section, since_version). @@ -1294,7 +1295,7 @@ def gettimedelta( def read( self, - filenames: (str | bytes | os.PathLike | Iterable[str | bytes | os.PathLike]), + filenames: str | bytes | os.PathLike | Iterable[str | bytes | os.PathLike], encoding=None, ): super().read(filenames=filenames, encoding=encoding) diff --git a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py index dcd39ef19ed62..fa4bd5566b7ed 100644 --- a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py +++ b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_middleware.py @@ -32,7 +32,7 @@ def all_access_test_client(): with conf_vars( { ("core", "simple_auth_manager_all_admins"): "true", - ("webserver", "expose_config"): "true", + ("api", "expose_config"): "true", } ): app = create_app() @@ -56,6 +56,7 @@ def all_access_test_client(): ) def test_all_endpoints_without_auth_header(all_access_test_client, method, path): response = all_access_test_client.request(method, path) - assert response.status_code not in {401, 403}, ( - f"Unexpected status code {response.status_code} for {method} {path}" - ) + assert response.status_code not in { + 401, + 403, + }, f"Unexpected status code {response.status_code} for {method} {path}" diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_config.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_config.py index 1fec270f34fcc..c057d2d32a78a 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_config.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_config.py @@ -77,9 +77,9 @@ (SECTION_SMTP, OPTION_KEY_SMTP_MAIL_FROM): OPTION_VALUE_SMTP_MAIL_FROM, } -AIRFLOW_CONFIG_ENABLE_EXPOSE_CONFIG = {("webserver", "expose_config"): "True"} -AIRFLOW_CONFIG_DISABLE_EXPOSE_CONFIG = {("webserver", "expose_config"): "False"} -AIRFLOW_CONFIG_NON_SENSITIVE_ONLY_CONFIG = {("webserver", "expose_config"): "non-sensitive-only"} +AIRFLOW_CONFIG_ENABLE_EXPOSE_CONFIG = {("api", "expose_config"): "True"} +AIRFLOW_CONFIG_DISABLE_EXPOSE_CONFIG = {("api", "expose_config"): "False"} +AIRFLOW_CONFIG_NON_SENSITIVE_ONLY_CONFIG = {("api", "expose_config"): "non-sensitive-only"} FORBIDDEN_RESPONSE = { "detail": "Your Airflow administrator chose not to expose the configuration, most likely for security reasons." } diff --git a/chart/docs/airflow-configuration.rst b/chart/docs/airflow-configuration.rst index 39a541fb505dd..65c7cb83e3f97 100644 --- a/chart/docs/airflow-configuration.rst +++ b/chart/docs/airflow-configuration.rst @@ -28,7 +28,7 @@ allow webserver users to view the config from within the UI: .. code-block:: yaml config: - webserver: + api: expose_config: 'True' # by default this is 'False' Generally speaking, it is useful to familiarize oneself with the Airflow diff --git a/clients/python/README.md b/clients/python/README.md index 07ae5c81b3aa3..0fa289542a581 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -555,11 +555,11 @@ You can also set it by env variable: `export AIRFLOW__CORE__LOAD_EXAMPLES=True` In the `[webserver]` section of your `airflow.cfg` set: ```ini -[webserver] +[api] expose_config = True ``` -You can also set it by env variable: `export AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True` +You can also set it by env variable: `export AIRFLOW__API__EXPOSE_CONFIG=True` * Configure your host/ip/user/password in the `test_python_client.py` file diff --git a/dev/README_RELEASE_PYTHON_CLIENT.md b/dev/README_RELEASE_PYTHON_CLIENT.md index dab9bf9e41e6e..be46acce909f4 100644 --- a/dev/README_RELEASE_PYTHON_CLIENT.md +++ b/dev/README_RELEASE_PYTHON_CLIENT.md @@ -478,7 +478,7 @@ and allows you to test the client in a real environment. ```shell export AIRFLOW__API__AUTH_BACKENDS=airflow.providers.fab.auth_manager.api.auth.backend.session,airflow.providers.fab.auth_manager.api.auth.backend.basic_auth -export AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True +export AIRFLOW__API__EXPOSE_CONFIG=True ``` @@ -487,7 +487,7 @@ or `http://localhost:28080` from the host) and you should be able to access the with `admin`/`admin` credentials. The `http://localhost:8080` and `admin`/`admin` credentials are default in the `clients/python/test_python_client.py` test. -The ``AIRFLOW__WEBSERVER__EXPOSE_CONFIG`` is optional - the script will also succeed when +The ``AIRFLOW__API__EXPOSE_CONFIG`` is optional - the script will also succeed when (default setting) exposing configuration is disabled. 2. Start Airflow in Breeze with example dags enabled: diff --git a/scripts/docker/entrypoint_ci.sh b/scripts/docker/entrypoint_ci.sh index a8adf1d9e8d49..e89c40d3f2952 100755 --- a/scripts/docker/entrypoint_ci.sh +++ b/scripts/docker/entrypoint_ci.sh @@ -379,7 +379,7 @@ function start_api_server_with_examples(){ return fi export AIRFLOW__CORE__LOAD_EXAMPLES=True - export AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True + export AIRFLOW__API__EXPOSE_CONFIG=True airflow dags reserialize echo "Example dags parsing finished" if airflow config get-value core auth_manager | grep -q "FabAuthManager"; then