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

kaxil 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 0bae39f4884 Document that `SQLToolset` does not check functions 
without `allowed_tables` (#74444)
0bae39f4884 is described below

commit 0bae39f4884bfd5b7434c0ece438860aa438999d
Author: Wei Lee <[email protected]>
AuthorDate: Sat Oct 10 21:18:49 2026 +0900

    Document that `SQLToolset` does not check functions without 
`allowed_tables` (#74444)
    
    * Document that SQLToolset does not check functions without allowed_tables
    
    Without allowed_tables, a SELECT can still call side-effecting functions 
such as nextval or pg_terminate_backend. Recommend a least-privilege role.
    
    * Clarify SQLToolset read-only guidance and allowed_tables function check
    
    - Recommend a least-privilege role together with a read-only role/session
      default, and note that a transaction cannot be set from the Dag.
    - State that the allowed_tables function check rejects only functions
      sqlglot cannot type, so typed syntax such as T-SQL NEXT VALUE FOR or
      Snowflake seq.nextval still passes.
---
 providers/common/ai/docs/agent_security.rst | 12 +++++++++++-
 providers/common/ai/docs/toolsets/sql.rst   | 16 ++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/providers/common/ai/docs/agent_security.rst 
b/providers/common/ai/docs/agent_security.rst
index 08a6fbd96a5..d5e1a07ae22 100644
--- a/providers/common/ai/docs/agent_security.rst
+++ b/providers/common/ai/docs/agent_security.rst
@@ -112,7 +112,17 @@ No single layer is sufficient on its own. They work 
together.
        (``DESCRIBE``/``SHOW``) statements pass; INSERT, UPDATE, DELETE, DROP,
        and writes hidden behind ``EXPLAIN`` are rejected.
      - Does not prevent the agent from reading sensitive data that the
-       database user has SELECT access to.
+       database user has SELECT access to. Without ``allowed_tables`` the 
check is
+       statement-level only: a side-effecting function inside a SELECT
+       (``nextval``, ``pg_terminate_backend``, ``dblink_exec``) is not blocked.
+       Setting ``allowed_tables`` adds a function check, but it rejects only 
functions
+       sqlglot cannot type; typed syntax such as T-SQL ``NEXT VALUE FOR`` or 
Snowflake
+       ``seq.nextval`` still passes. Use a least-privilege role and, where the 
database
+       supports it, a read-only default for that role or session (for example
+       ``ALTER ROLE <role> SET default_transaction_read_only = on`` on 
PostgreSQL).
+       The toolset opens its own connection per call, so you cannot set a 
transaction
+       from the Dag, and a read-only setting is defense in depth: it does not 
stop every
+       side-effecting function.
    * - **DataFusionToolset: read-only by default**
      - ``allow_writes=False`` (default) validates every SQL query through
        ``validate_sql()`` and rejects CREATE TABLE, CREATE VIEW, INSERT
diff --git a/providers/common/ai/docs/toolsets/sql.rst 
b/providers/common/ai/docs/toolsets/sql.rst
index 93b16520943..df0a4caca78 100644
--- a/providers/common/ai/docs/toolsets/sql.rst
+++ b/providers/common/ai/docs/toolsets/sql.rst
@@ -67,6 +67,22 @@ rejects by scanning the parsed statement for write 
operations. When
 table, so its target must be on the list, while ``SHOW`` enumerates objects 
beyond
 any single table and is rejected outright (see 
:ref:`allowed-tables-enforcement`).
 
+The read-only check inspects statement types, not what a function does. By 
default
+(no ``allowed_tables``) a function call inside a ``SELECT`` is not examined, so
+``SELECT nextval('seq')``, ``SELECT pg_terminate_backend(pid)`` or
+``SELECT dblink_exec(...)`` pass validation and run with the connection's
+privileges. Setting ``allowed_tables`` turns on the function check: every 
function
+sqlglot cannot type is rejected unless it is listed in ``allowed_functions``. 
The
+check rejects only functions sqlglot cannot type; typed syntax such as T-SQL
+``NEXT VALUE FOR seq`` or Snowflake ``seq.nextval`` still passes, so
+``allowed_tables`` is not a guarantee against side-effecting functions. Either 
way,
+point the connection at a least-privilege role and, where the database 
supports it,
+a read-only default for that role or session (for example
+``ALTER ROLE <role> SET default_transaction_read_only = on`` on PostgreSQL). 
The
+toolset opens its own connection per call, so you cannot set a transaction 
from the
+Dag, and a read-only setting is defense in depth: it does not stop every
+side-effecting function.
+
 .. _sql-toolset-restricted:
 
 Restricting the agent

Reply via email to