QueryShield

How do I use QueryShield with Snowflake?

QueryShield supports Snowflake via the sqlglot Snowflake dialect parser. Pattern:

from queryshield import Client
qs = Client(api_key=KEY, policy="snowflake-bi-agent", dialect="snowflake")

decision = qs.validate(sql=llm_output, context={"role": ctx.role}) if decision.allowed: cursor.execute(decision.sql) ```

Snowflake-specific considerations:

1. Warehouse cost is the bigger risk than schema mutation. Snowflake charges per credit; a Cartesian join can burn $100+ in minutes. QueryShield's cost-estimation hook calls EXPLAIN USING JSON and rejects above a threshold. 2. USE WAREHOUSE, USE ROLE, USE DATABASE statements should be denied for analyst agents — only the calling layer sets context. 3. Time-Travel functions (AT(OFFSET => -3600)) are useful but expose historical data the current RLS might filter. Policy can deny AT/BEFORE for tenant-data tables. 4. Snowflake Row Access Policies and Masking Policies are excellent defense-in-depth; QueryShield is the AST-layer first line. 5. Stored procedures / UDFs that perform writes — denylist by name in the AST function check.

Evidence log captures Snowflake QUERY_ID once executed, letting you cross-reference with Snowflake's QUERY_HISTORY for warehouse cost forensics.