This is an automated email from the ASF dual-hosted git repository.

jscheffl 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 c2e5bde10ea Treat non-sensitive-only as true and always mask sensitive 
values in public api's (#59880)
c2e5bde10ea is described below

commit c2e5bde10ea84262c06910d511c93261ff1b85da
Author: Pratyush Gupta <[email protected]>
AuthorDate: Sat Jan 3 19:19:17 2026 +0530

    Treat non-sensitive-only as true and always mask sensitive values in public 
api's (#59880)
    
    * Treat non-sensitive-only as true and always mask sensitive values in 
public APIs.
    
    * Add newsfragment and update docs and client references for config masking
    
    * newline error fixed - config.yml
    
    * Update clients/python/README.md
    
    Co-authored-by: Bas Harenslak <[email protected]>
    
    * CI image check resolved
    
    * newline error in config.py fixed
    
    ---------
    
    Co-authored-by: Jarek Potiuk <[email protected]>
    Co-authored-by: Bas Harenslak <[email protected]>
---
 airflow-core/newsfragments/59880.bugfix.rst                    |  1 +
 .../src/airflow/api_fastapi/core_api/services/public/config.py | 10 +++++++++-
 airflow-core/src/airflow/config_templates/config.yml           |  6 +++---
 .../unit/api_fastapi/core_api/routes/public/test_config.py     |  8 ++++----
 clients/python/README.md                                       |  1 +
 clients/python/test_python_client.py                           |  1 +
 6 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/airflow-core/newsfragments/59880.bugfix.rst 
b/airflow-core/newsfragments/59880.bugfix.rst
new file mode 100644
index 00000000000..e1c35a9d640
--- /dev/null
+++ b/airflow-core/newsfragments/59880.bugfix.rst
@@ -0,0 +1 @@
+Always mask sensitive configuration values in public config APIs and treat the 
deprecated ``non-sensitive-only`` value as ``True``.
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py 
b/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py
index a23c957074b..0b51a6c33ae 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py
@@ -16,6 +16,8 @@
 # under the License.
 from __future__ import annotations
 
+import warnings
+
 from fastapi import HTTPException, status
 from fastapi.responses import Response
 
@@ -29,9 +31,15 @@ def _check_expose_config() -> bool:
     if conf.get("api", "expose_config").lower() == "non-sensitive-only":
         expose_config = True
         display_sensitive = False
+        warnings.warn(
+            "The value 'non-sensitive-only' for [api] expose_config is 
deprecated. "
+            "Use 'true' instead; sensitive configuration values are always 
masked.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
     else:
         expose_config = conf.getboolean("api", "expose_config")
-        display_sensitive = True
+        display_sensitive = False
 
     if not expose_config:
         raise HTTPException(
diff --git a/airflow-core/src/airflow/config_templates/config.yml 
b/airflow-core/src/airflow/config_templates/config.yml
index bc00638ae1e..a4ed088865a 100644
--- a/airflow-core/src/airflow/config_templates/config.yml
+++ b/airflow-core/src/airflow/config_templates/config.yml
@@ -1443,9 +1443,9 @@ api:
       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.
+        Expose the configuration file in the web server. Set to ``True`` to 
expose configuration with
+        sensitive values always masked. The deprecated value 
``non-sensitive-only`` is treated the same as
+        ``True`` for backward compatibility. ``False`` hides the configuration 
completely.
       version_added: ~
       type: string
       example: ~
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 9ceacd48ea4..aa1a74890f7 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
@@ -56,7 +56,7 @@ MOCK_CONFIG_DICT = {
         OPTION_KEY_SMTP_MAIL_FROM: OPTION_VALUE_SMTP_MAIL_FROM,
     },
     SECTION_DATABASE: {
-        OPTION_KEY_SQL_ALCHEMY_CONN: OPTION_VALUE_SQL_ALCHEMY_CONN,
+        OPTION_KEY_SQL_ALCHEMY_CONN: OPTION_VALUE_SENSITIVE_HIDDEN,
     },
 }
 MOCK_CONFIG_DICT_SENSITIVE_HIDDEN = {
@@ -102,7 +102,7 @@ GET_CONFIG_ALL_JSON_RESPONSE = {
         {
             "name": SECTION_DATABASE,
             "options": [
-                {"key": OPTION_KEY_SQL_ALCHEMY_CONN, "value": 
OPTION_VALUE_SQL_ALCHEMY_CONN},
+                {"key": OPTION_KEY_SQL_ALCHEMY_CONN, "value": 
OPTION_VALUE_SENSITIVE_HIDDEN},
             ],
         },
     ],
@@ -206,7 +206,7 @@ class TestGetConfig(TestConfigEndpoint):
                     {OPTION_KEY_SMTP_MAIL_FROM} = {OPTION_VALUE_SMTP_MAIL_FROM}
 
                     [{SECTION_DATABASE}]
-                    {OPTION_KEY_SQL_ALCHEMY_CONN} = 
{OPTION_VALUE_SQL_ALCHEMY_CONN}
+                    {OPTION_KEY_SQL_ALCHEMY_CONN} = 
{OPTION_VALUE_SENSITIVE_HIDDEN}
                     """
                 ),
             ),
@@ -252,7 +252,7 @@ class TestGetConfig(TestConfigEndpoint):
                         {
                             "name": SECTION_DATABASE,
                             "options": [
-                                {"key": OPTION_KEY_SQL_ALCHEMY_CONN, "value": 
OPTION_VALUE_SQL_ALCHEMY_CONN},
+                                {"key": OPTION_KEY_SQL_ALCHEMY_CONN, "value": 
OPTION_VALUE_SENSITIVE_HIDDEN},
                             ],
                         },
                     ],
diff --git a/clients/python/README.md b/clients/python/README.md
index e164f4b5ca8..6f04629a3a5 100644
--- a/clients/python/README.md
+++ b/clients/python/README.md
@@ -630,6 +630,7 @@ You can also set it by env variable: `export 
AIRFLOW__CORE__LOAD_EXAMPLES=True`
 
 * optionally expose configuration (NOTE! that this is dangerous setting). The 
script will happily run with
   the default setting, but if you want to see the configuration, you need to 
expose it.
+  Note that sensitive configuration values are always masked.
   In the `[api]` section of your `airflow.cfg` set:
 
 ```ini
diff --git a/clients/python/test_python_client.py 
b/clients/python/test_python_client.py
index 9d771428f87..30cdfb2afaa 100644
--- a/clients/python/test_python_client.py
+++ b/clients/python/test_python_client.py
@@ -121,6 +121,7 @@ def test_python_client():
 
         # Get current configuration. Note, this is disabled by default with 
most installation.
         # You need to set `expose_config = True` in Airflow configuration in 
order to retrieve configuration.
+        # Sensitive configuration values are always masked in the response.
         conf_api_instance = config_api.ConfigApi(api_client)
         try:
             api_response = conf_api_instance.get_config()

Reply via email to