harbor
Client/Server-DuckDB über einen HTTP-Port — Web-UI, JSON /sql und natives ATTACH (TYPE harbor)
Maintainer: shreeve
Installation und Laden
INSTALL harbor FROM community;LOAD harbor;Beispiel
-- Load the extension and start the server in the background.-- harbor_serve returns once the server is accepting connections;-- harbor_wait keeps the process alive in daemon mode (containers,-- systemd).LOAD harbor;CALL harbor_serve(bind := '127.0.0.1', port := 9494);-- ┌─────────────────────────────────┐-- │ token │-- ├─────────────────────────────────┤-- │ a1b2c3d4e5f6... │-- └─────────────────────────────────┘
-- Hit it from another shell:-- curl http://127.0.0.1:9494/health-- curl -H "Authorization: Bearer <token>" \-- -X POST http://127.0.0.1:9494/sql \-- -H 'Content-Type: application/json' \-- -d '{"sql":"SELECT 42 AS the_answer"}'---- {"ok":true,"kind":"select","columns":[{"name":"the_answer","duckdbType":"INTEGER","lossless":true}],-- "data":[[42]],"rowCount":1,"timeMs":0}
-- Browser users open http://127.0.0.1:9494/ — the harbor login-- page asks for the token once, sets a HttpOnly SameSite=Strict-- cookie, then proxies the official DuckDB UI through.
-- A second DuckDB attaches the server's catalog natively — catalog-- discovery and table scans both ride /sql, so multi-table JOINs,-- projection pushdown, and CLI autocomplete all work:-- LOAD harbor;-- ATTACH 'harbor:127.0.0.1:9494' AS h (TYPE harbor, TOKEN '<token>');-- SELECT * FROM h.main.orders o JOIN h.main.customers c USING (customer_id);
-- Stop the server:CALL harbor_stop();Über harbor
harbor ist eine einzelne DuckDB-Erweiterung. Nach dem Laden wird Ihre DuckDB-
Instanz zu einer Client/Server-Datenbank auf einem HTTP-Port:
| Surface | Endpoints | What it gives you |
|---|---|---|
| JSON SQL | POST /sql, /sql/sessions/* |
NDJSON-Streaming + einmaliges JSON, vorbereitete Parameter (inkl. LIST/STRUCT/MAP), principal-eigene Sitzungen, Durchsetzung von harbor_query_timeout_s |
| Native attach | clientseitiges ATTACH 'harbor:host' (TYPE harbor) |
Katalog des Servers aus jedem DuckDB durchsuchen und abfragen — Multi-Tabellen-JOINs, Projektions-Pushdown und CLI-Autovervollständigung; Katalog + Scans laufen beide über /sql (nur lesend) |
| DuckDB UI | GET /, /ddb/*, /localEvents |
Cookie-geschütztes Proxy zur offiziellen DuckDB-UI; CSP+Nonce auf der Anmeldeseite |
| Admin | /health, /whoami, /tables, /schema/:db/:t, /checkpoint, /sessions, /interrupt |
Zentralisiertes __HARBOR_ADMIN__:resource:action Default-Deny + Operator-Opt-in harbor_allow_admin_without_authz |
| Auth | /auth/login, /auth/logout |
Bearer / X-Harbor-Token / HMAC-signiertes Cookie harbor_session |
Alles auf demselben Port, gegen dieselbe prozessinterne DuckDB, mit dem selben Sitzungspool und Authentifizierungsmodell.
Anwendungsfälle:
- Einen DuckDB-Prozess betreiben und Nutzer über die
passende Schnittstelle darauf zugreifen lassen: Browser (UI), DuckDB-CLI/Clients
(
ATTACH ... TYPE harbor), Backend-Code (/sql). - Brücke zwischen SQL-Clients und Anwendungen, ohne einen separaten Datenbankserver aufzusetzen.
- Container-native Bereitstellungen —
harbor_wait()blockiert bis SIGTERM, sodass harbor sauber unter systemd / Docker / Kubernetes läuft.
Status: v0.4-Release, getestet über die DuckDB-Community-Erweiterungs- Matrix (linux_amd64/arm64, osx_amd64/arm64, windows_amd64/_mingw, wasm_mvp/eh/threads).
Quellcode, Designspezifikation, Contributor Guide, vollständige Release Notes: github.com/shreeve/duckdb-harbor.
Vendors the official duckdb-ui; targets DuckDB v1.5.3.
Hinzugefügte Funktionen
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| harbor_check_token | scalar | NULL | NULL | |
| harbor_identify | table | NULL | NULL | |
| harbor_nop_authorization | scalar | NULL | NULL | |
| harbor_serve | table | NULL | NULL | |
| harbor_stop | table | NULL | NULL | |
| harbor_version | scalar | NULL | NULL | |
| harbor_wait | table | NULL | NULL | |
| whoami | table_macro | NULL | NULL |
Überladene Funktionen
Diese Erweiterung fügt keine Funktionsüberladungen hinzu.
Hinzugefügte Typen
Diese Erweiterung fügt keine Typen hinzu.
Hinzugefügte Einstellungen
| name | description | input_type | scope | aliases |
|---|---|---|---|---|
| harbor_allow_admin_without_authz | When true AND no custom harbor_authorization_function is set, admin endpoints (HARBOR_ADMIN:*) bypass the internal default-deny rule. Off by default; harbor_serve logs a loud WARN at startup when the combination is in effect. | BOOLEAN | GLOBAL | [] |
| harbor_auth_cookie_ttl_s | TTL in seconds for HMAC-signed harbor_session cookies issued by /auth/login (default 12h) | UBIGINT | GLOBAL | [] |
| harbor_authentication_function | Name of a Harbor callback function for authentication | VARCHAR | GLOBAL | [] |
| harbor_authorization_function | Name of a Harbor callback function for authorization | VARCHAR | GLOBAL | [] |
| harbor_cors_origins | Comma-separated allow-list of origins for cross-origin /auth/, /sql, /info (empty = no cross-origin permitted; ‘’ is rejected) | VARCHAR | GLOBAL | [] |
| harbor_loaded_at_us | Epoch microseconds at extension load | BIGINT | GLOBAL | [] |
| harbor_max_request_body_bytes | Maximum POST body size for /sql JSON requests; larger requests return 413 PAYLOAD_TOO_LARGE (default 256 MiB) | UBIGINT | GLOBAL | [] |
| harbor_max_response_rows | Cap on rows returned per /sql request; 0 = unlimited; truncation reflected in the NDJSON end record’s truncated:true field (default 0) | UBIGINT | GLOBAL | [] |
| harbor_max_sessions | Maximum concurrent DB sessions across all principals; new session creation past this limit returns 429 SESSION_LIMIT (default 1024) | UBIGINT | GLOBAL | [] |
| harbor_query_timeout_s | Per-query wall-clock timeout in seconds. 0 disables the timeout. Non-zero values interrupt any Connection::Execute (/sql, /ddb/run, admin transients) that runs longer than the configured limit, returning HTTP 504 with errorCode QUERY_TIMEOUT. Default 0. | UBIGINT | GLOBAL | [] |
| harbor_stop_drain_timeout_s | Seconds harbor_stop waits for in-flight request handlers to drain per attempt before re-checking active requests (default 30; 0 = poll without waiting) | UBIGINT | GLOBAL | [] |
| ui_polling_interval | UI catalog watcher polling interval in milliseconds (0 disables) | UINTEGER | GLOBAL | [] |
| ui_remote_url | Remote URL the UI proxies GET /.* requests to (default ui.duckdb.org) | VARCHAR | GLOBAL | [] |
| whoami_hostname | Network hostname / public address | VARCHAR | GLOBAL | [] |
| whoami_meta | Provider-specific metadata as JSON | VARCHAR | GLOBAL | [] |
| whoami_name | Human-readable name for this node | VARCHAR | GLOBAL | [] |
| whoami_provider | Deployment provider (ec2, docker, local, …) | VARCHAR | GLOBAL | [] |
| whoami_region | Deployment region | VARCHAR | GLOBAL | [] |
| whoami_started_at | Node start time (ISO-8601 TIMESTAMP) | VARCHAR | GLOBAL | [] |