Inspiration

LLMs are commonly being used to translate natural language into SQL queries, giving non-technical users direct access to databases through plain English. However, this causes a massive security risk. What happens when the AI generates a query that touches data it shouldn't? Trusting an LLM's own judgment about whether its output is safe isn't good enough for production systems and requires thorough analysis.

I wanted to explore whether Midnight's zero-knowledge tooling could act as a cryptographic guardrail between an untrusted AI and a real database to prove a query is safe before it executes, rather than hoping the AI got it right.

What it does

Our system takes a natural language request (e.g. "show me all active users"), and:

  1. An LLM (via Groq) translates it into a PostgreSQL query and classifies whether it's a safe, read-only SELECT statement
  2. The query is hashed locally
  3. A Compact smart contract, compiled to a real zero-knowledge circuit, verifies the safety classification before the query is allowed to proceed
  4. Only after this cryptographic check passes does the query execute against a live Postgres database (hosted on Supabase)

If the AI generates a modifying query (DELETE, DROP, UPDATE, etc.), the circuit rejects it and the request is blocked with a 403 — the query never reaches the database.

How we built it

  • Backend: FastAPI orchestrates the whole pipeline
  • AI layer: LangChain + Groq (openai/gpt-oss-120b) with structured output, forcing the LLM to return a strict schema (SQL string + safety boolean) rather than freeform text
  • ZK layer: A Compact smart contract (sql_guard.compact) defines a witness/circuit/ledger pattern — the circuit asserts the safety flag before writing the query's hash to on-chain state
  • Database: PostgreSQL via Supabase, connected asynchronously with asyncpg
  • Toolchain: Compiled the contract with Midnight's compactc compiler inside WSL, generating real proving/verifying keys and TypeScript bindings — then stood up a full local Midnight devnet (node, indexer, proof server) via Docker to deploy and interact with the compiled contract

    Challenges we ran into

    Almost every layer of this stack had its own setup gauntlet:

  • Windows/PowerShell quirks — curl aliasing to Invoke-WebRequest, execution policy blocking npm/npx, and a Windows-specific asyncpg SSL bug that silently manifested as an unrelated 'coroutine' object is not callable error

  • Model deprecation mid-hackathon — our original OpenAI billing setup and later a Groq model ID both stopped working overnight, requiring a live pivot to openai/gpt-oss-120b

  • Supabase networking — the direct connection hostname turned out to be IPv6-only, which our network couldn't resolve; switching to Supabase's connection pooler fixed it

  • WSL/Docker plumbing — from a missing unzip binary silently breaking the Compact compiler installer, to Docker group permissions requiring a full WSL session restart, to accidentally launching Docker Desktop's internal WSL distro instead of our own Ubuntu install

    Accomplishments that we're proud of

  • Built a full working pipeline end-to-end: natural language → LLM-generated SQL → cryptographic safety verification → real database execution

  • Successfully compiled a real Compact smart contract into a working zero-knowledge circuit with actual proving and verifying keys — not just a mockup

  • Got a full local Midnight devnet (node, indexer, proof server) running via Docker and deployed our contract to it

  • Debugged our way through a wide range of real infrastructure issues — Windows async bugs, DNS/IPv6 networking, compiler version mismatches — and came out the other side with something that actually works

  • Leaned heavily on AI tools (Claude) throughout the build — for scaffolding code, debugging errors in real time, and navigating unfamiliar Compact/Midnight syntax — which let us move fast enough to go from zero blockchain experience to a working ZK-verified application in a single weekend

    What we learned

  • How Compact's witness/circuit/ledger execution model works in practice, and how quickly ecosystem tooling can shift underneath tutorials in a fast-moving space

  • That "the AI said it's safe" and "it's cryptographically proven safe" are very different trust levels — and that gap is exactly where ZK verification earns its place in an AI pipeline

  • A lot of unglamorous but essential debugging: Windows async networking quirks, DNS/IPv6 resolution, and toolchain version management across Python, Node, and Compact simultaneously

    What's next for ZK-Verified Text-to-SQL Middleware

  • Wire the compiled contract into a live local devnet call (already deployed and running) so the ZK verification step is a real on-chain proof rather than a local safety check

  • Expand the policy beyond read-only detection to more granular guardrails (e.g. row-level restrictions, specific table allowlists)

  • Add a lightweight frontend so the full pipeline can be demoed without Swagger UI

Built With

Share this project:

Updates

Submission history