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:
- An LLM (via Groq) translates it into a PostgreSQL query and classifies whether it's a safe, read-only
SELECTstatement - The query is hashed locally
- A Compact smart contract, compiled to a real zero-knowledge circuit, verifies the safety classification before the query is allowed to proceed
- 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
compactccompiler 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 contractChallenges we ran into
Almost every layer of this stack had its own setup gauntlet:
Windows/PowerShell quirks —
curlaliasing toInvoke-WebRequest, execution policy blocking npm/npx, and a Windows-specificasyncpgSSL bug that silently manifested as an unrelated'coroutine' object is not callableerrorModel 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-120bSupabase 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
unzipbinary 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 installAccomplishments 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
- asyncpg
- claude
- compact
- docker
- groq
- langchain
- midnight
- node.js
- postgresql
- python
- supabase
- typescript
Log in or sign up for Devpost to join the conversation.