How do I use QueryShield with Vanna.ai?
Vanna.ai handles natural-language-to-SQL generation; QueryShield sits between Vanna's vn.generate_sql() output and your database, validating before execution. Drop-in pattern:
import vanna
from queryshield import Client
qs = Client(api_key=os.getenv("QUERYSHIELD_API_KEY"), policy="customer-support")
def safe_ask(question, ctx): sql = vn.generate_sql(question=question) result = qs.validate( sql=sql, context={"tenant_id": ctx.tenant_id, "user_id": ctx.user_id}, ) if result.decision == "reject": return f"Query blocked: {result.reason}" if result.decision == "rewrite": sql = result.rewritten_sql # e.g., tenant predicate injected return vn.run_sql(sql) ```
Why this combination works: Vanna's strength is schema-aware NL→SQL generation; its built-in is_sql_valid() is keyword/regex-based and not a security control. QueryShield's strength is AST validation + declarative policy + audit log. They are complementary, not competitive — Vanna's authors have explicitly recommended layering a security validator on top for production.
Self-host option: queryshield-py package validates locally without network calls, useful for high-throughput or air-gapped Vanna deployments. Policy files (YAML) are version-controlled alongside your Vanna training data.