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 []