Production gateway and policy pack for DuckDB Quack.
QuackGate is a tiny production gateway for DuckDB Quack: TLS, audit logs, rate limiting, and a Quack-native authentication/query-policy pack in one binary.
quackgate init --yes --force
quackgate policy render --config quackgate.yaml > quackgate_policy.sql
quackgate serve --config quackgate.yamlOpen http://localhost:7494/admin with Authorization: Bearer <admin.token>, then send Quack traffic through http://localhost:7494/quack.
DuckDB Quack exposes a remote DuckDB SQL surface over HTTP. That is useful, but production access needs boring controls: TLS termination, source IP policy, rate limiting, audit JSONL, health checks, and a server-side query policy.
QuackGate intentionally does not parse application/duckdb in v0.1.0. DuckDB's Quack authorization hook is the component that sees full SQL text, so SQL authentication and query policy are generated as DuckDB macros.
go build -o bin/quackgate ./cmd/quackgate
bin/quackgate init --yes --force
bin/quackgate policy render --config quackgate.yaml > quackgate_policy.sqlRun the generated policy SQL in the DuckDB session that starts Quack:
INSTALL quack FROM core_nightly;
LOAD quack;
.read quackgate_policy.sql
CALL quack_serve('quack:localhost');Then start the gateway:
bin/quackgate serve --config quackgate.yamlDemo flow:
- Authenticated client runs
SELECT 42: allowed. - Same client runs
INSERTunder the defaultread_onlyprofile: denied by the Quack authorization macro. /adminshows counters, token summary, upstream status, and recent gateway audit events without raw tokens.
DuckDB Quack client -> QuackGate HTTP/TLS gateway -> DuckDB Quack server
|
+-> healthz, readyz, metrics, admin, audit JSONL
DuckDB Quack server loads generated SQL:
quackgate_check_token(sid, client_token, server_token)
quackgate_authorize(sid, query)
The gateway transparently proxies /quack and unknown paths. It does not rewrite bodies, does not replace client tokens, and does not inspect SQL.
go install github.com/quackgate/quackgate/cmd/quackgate@latestOr download release binaries from GitHub Releases once v0.1.0 is published.
Start from configs/quackgate.example.yaml or run:
quackgate init --yes
quackgate verify --config quackgate.yamlImportant fields:
upstream.url: DuckDB Quack HTTP endpoint, usuallyhttp://localhost:9494.auth.tokens: plaintext tokens in local config; rendered policy stores only SHA-256.auth.token_file: merge tokens from a YAML file, useful for Kubernetes Secrets.policy.profile:read_only,read_write,allow_all, orcustom.gateway.audit_only: gateway-level allowlist/rate-limit decisions are logged but not blocked.
quackgate policy render emits deterministic SQL:
- creates
quackgate.token; - inserts SHA-256 token hashes;
- registers
quackgate_check_token; - registers
quackgate_authorize; - sets DuckDB Quack global auth/authz callbacks.
policy.mode=audit_only makes query authorization return true. Query-level would-deny audit is not implemented in v0.1.0 because SQL macros cannot reliably write audit rows and QuackGate does not parse the binary protocol.
QuackGate protects:
- TLS termination;
- global source IP allowlist;
- per-IP in-memory rate limit;
- Quack-native static token authentication;
- Quack-native global query policy;
- gateway-level JSONL audit.
QuackGate v0.1.0 does not provide RBAC, per-user query policy, per-table policy, JWT/OIDC for the standard DuckDB Quack client, or query audit correlated to a user. Those require a DuckDB extension or future official Quack hooks.
Use the built-in smoke benchmark:
quackgate bench --config quackgate.yaml --requests 1000 --concurrency 16By default it measures GET /healthz gateway overhead and does not require a DuckDB client.
docker compose up --buildThe compose demo uses a mock Quack HTTP upstream so CI and local demos do not depend on a fragile nightly DuckDB image. For real Quack, run DuckDB with the generated policy and point upstream.url at its HTTP URL.
Minimal manifests live in examples/k8s. Tokens can be mounted through auth.token_file from a Secret.
| Capability | QuackGate | nginx + auth_request | Custom middleware |
|---|---|---|---|
| Quack-native static auth | Yes | No | Maybe |
| Quack-native global query policy | Yes | No | Maybe |
| One binary gateway | Yes | No | No |
| Policy generator | Yes | No | No |
| Audit JSONL | Yes | Custom | Custom |
| 2-minute setup | Yes | No | No |
- JWT/OIDC via DuckDB extension or official Quack hook support.
- Per-user RBAC via
quackgate-duckdb-extension. - Per-table policies.
- Query audit with user correlation.
- Prometheus histograms.
- Multi-upstream routing.
- Homebrew tap.
- Managed / enterprise edition.
MIT