How do I use QueryShield with BigQuery?
BigQuery via sqlglot's BigQuery dialect, with three platform-specific considerations:
1. Slot cost / on-demand pricing. A poorly bounded query on a multi-TB table can cost hundreds of dollars per LLM-generated mistake. QueryShield supports a dry_run_first mode that calls client.query(sql, job_config=QueryJobConfig(dry_run=True)) and rejects if total_bytes_processed exceeds the policy threshold.
2. SELECT * on wide tables is the most common cost incident. Policy can require explicit column lists for tables above a row/byte threshold.
3. Authorized views and column-level access controls are excellent defense-in-depth; QueryShield enforces at the AST and complements them.
4. CREATE TEMP TABLE, EXPORT DATA, MERGE statements should be denylisted for read agents — EXPORT DATA especially, since it can exfil to GCS buckets.
qs = Client(api_key=KEY, policy="bq-analyst", dialect="bigquery")
decision = qs.validate(sql=llm_output, context={"project": "prod", "user": ctx.user_id})
if decision.allowed:
if decision.estimated_bytes > 10 * 1024**3: # 10 GB
return "Query would scan >10 GB; please narrow your filter."
bq_client.query(decision.sql).result()
Evidence log captures bytes_processed, slot_ms, and the BigQuery job_id for FinOps + audit correlation.