Remote secret storage with OPAQUE authentication, MFA login, and managed catalog discovery
Compatibility Matrix
This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 |
|---|---|---|---|---|---|
| Linux AMD64 | |||||
| Linux ARM64 | |||||
| macOS AMD64 | |||||
| macOS ARM64 | |||||
| Windows AMD64 | |||||
| Windows ARM64 | |||||
| WebAssembly |
Installing and Loading
INSTALL boilstream FROM community;
LOAD boilstream;
Example
INSTALL httpfs; LOAD httpfs;
INSTALL boilstream FROM community;
LOAD boilstream;
-- Use your server and credentials; avoid retaining credentials in SQL history.
PRAGMA boilstream_login('https://api.example.com/user@example.com', 'your-password', '123456');
-- Discover catalogs and inspect available secret metadata.
-- Login does not automatically attach catalogs.
FROM boilstream_ducklakes();
FROM boilstream_secrets();
PRAGMA boilstream_help;
About boilstream
BoilStream provides remote secret storage with OPAQUE password authentication, email/password registration, MFA login, and bootstrap-token authentication. It supports per-connection session state, signed requests, encrypted responses, and managed catalog discovery with explicit attachment.
Version 0.8.2 hardens URL validation and credential cleanup and qualifies a pinned DuckDB 2.0 WASM baseline. Native macOS/Linux ARM64 and browser EH Quack integration were tested. Threaded Quack compatibility passes with the pinned, source-built shared-memory artifact included in the regression workflow's downloads. DuckDB's public threaded Quack artifact is still incompatible; browser deployments must serve the compatible paired artifact as described in the compatibility guide. Load threaded extensions before enabling query workers. MVP WASM is excluded.
Remote operations require a compatible BoilStream server and HTTPS (HTTP is allowed only for exact loopback hosts). Native HTTP uses httpfs; managed Quack attachment requires the core quack extension. Authentication does not provide blanket protection against compromised TLS endpoints or embedding processes.
The upstream OPAQUE dependency upgrade resolves the production Rust audit advisory and is tested against existing OPAQUE 3 password records. Host-library findings and full browser server-authentication coverage remain separate. See the compatibility and deployment guide and dependency upgrade evidence.
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| boilstream_attach_ducklake | pragma | NULL | NULL | |
| boilstream_auth_result | table | NULL | NULL | |
| boilstream_bootstrap_session | pragma | NULL | NULL | |
| boilstream_buckets | table | NULL | NULL | |
| boilstream_create_ducklake | pragma | NULL | NULL | |
| boilstream_ducklakes | table | NULL | NULL | |
| boilstream_help | pragma | NULL | NULL | |
| boilstream_login | pragma | NULL | NULL | |
| boilstream_quack_authn | scalar | NULL | NULL | |
| boilstream_quack_authz | scalar | NULL | NULL | |
| boilstream_quack_debug_session_count | scalar | NULL | NULL | |
| boilstream_register_user | pragma | NULL | NULL | |
| boilstream_secrets | table | NULL | NULL | |
| boilstream_verify_mfa | pragma | NULL | NULL | |
| ducklake_add_data_files | table | NULL | NULL | |
| ducklake_cleanup_old_files | table | NULL | NULL | |
| ducklake_commit | table | NULL | NULL | |
| ducklake_current_snapshot | table | NULL | NULL | |
| ducklake_delete_orphaned_files | table | NULL | NULL | |
| ducklake_expire_snapshots | table | NULL | NULL | |
| ducklake_flush_inlined_data | table | NULL | NULL | |
| ducklake_last_committed_snapshot | table | NULL | NULL | |
| ducklake_list_files | table | NULL | NULL | |
| ducklake_merge_adjacent_files | table | NULL | NULL | |
| ducklake_options | table | NULL | NULL | |
| ducklake_rewrite_data_files | table | NULL | NULL | |
| ducklake_scan | table | NULL | NULL | |
| ducklake_set_commit_message | table | NULL | NULL | |
| ducklake_set_option | table | NULL | NULL | |
| ducklake_settings | table | NULL | NULL | |
| ducklake_snapshots | table | NULL | NULL | |
| ducklake_table_changes | table_macro | NULL | NULL | |
| ducklake_table_deletions | table | NULL | NULL | |
| ducklake_table_info | table | NULL | NULL | |
| ducklake_table_insertions | table | NULL | NULL | |
| murmur3_32 | scalar | NULL | NULL | |
| postgres_clear_cache | table | NULL | NULL | |
| postgres_close_pinned_connection | scalar | NULL | NULL | |
| postgres_configure_pool | table | NULL | NULL | |
| postgres_execute | table | NULL | NULL | |
| postgres_hstore_get | scalar | NULL | NULL | |
| postgres_hstore_to_json | scalar | NULL | NULL | |
| postgres_pin_connection | scalar | NULL | NULL | |
| postgres_query | table | NULL | NULL | |
| quack_active_connections | table | NULL | NULL | |
| quack_cancel | table | NULL | NULL | |
| quack_check_token | scalar | NULL | NULL | |
| quack_clear_cache | table | NULL | NULL | |
| quack_connection_id | scalar | NULL | NULL | |
| quack_generate_keys | table | NULL | NULL | |
| quack_identify | table | NULL | NULL | |
| quack_nop_authorization | scalar | NULL | NULL | |
| quack_query | table | NULL | NULL | |
| quack_query_by_name | table | NULL | NULL | |
| quack_serve | table | NULL | NULL | |
| quack_server_list | table | NULL | NULL | |
| quack_stop | table | NULL | NULL | |
| quack_uri_parser | scalar | NULL | NULL | |
| read_postgres_binary | table | NULL | NULL | |
| scan_data_from_quack_client | table | NULL | NULL | |
| whoami | table_macro | NULL | NULL |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
| name | description | input_type | scope | aliases | typed_value |
|---|---|---|---|---|---|
| boilstream_grammar_auto_activate | Activate the boilstream SQL syntax (BOILSTREAM …, CREATE/ATTACH DUCKLAKE) on every new connection | BOOLEAN | GLOBAL | [] | true |
| default_secret_storage | Allows switching the default storage for secrets. | VARCHAR | GLOBAL | [] | boilstream |
| ducklake_default_data_inlining_row_limit | Default row limit for data inlining (0 disables inlining) | UBIGINT | GLOBAL | [] | 10 |
| ducklake_default_version | Default DuckLake version for new catalogs | VARCHAR | GLOBAL | [] | NULL |
| ducklake_max_retry_count | The maximum amount of retry attempts for a ducklake transaction | UBIGINT | GLOBAL | [] | 10 |
| ducklake_retry_backoff | Backoff factor for exponentially increasing retry wait time | DOUBLE | GLOBAL | [] | 1.5 |
| ducklake_retry_wait_ms | Time between retries | UBIGINT | GLOBAL | [] | 100 |
| ducklake_target_file_size | Target file size for insertion and compaction | VARCHAR | GLOBAL | [] | NULL |
| ducklake_write_deletion_vectors | [EXPERIMENTAL] Write Iceberg V3 deletion vectors (puffin) instead of positional delete files (parquet) | BOOLEAN | GLOBAL | [] | false |
| pg_array_as_varchar | Read Postgres arrays as varchar - enables reading mixed dimensional arrays | BOOLEAN | GLOBAL | [] | false |
| pg_connection_cache | Whether or not to use the connection pooling. This option is deprecated, instead to disable the connection pooling use "SET pg_pool_max_connections=0" for newly attached Postgres databases and "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', max_connections=0)" for already attached Postgres databases. | BOOLEAN | GLOBAL | [] | true |
| pg_connection_limit | The maximum amount of concurrent Postgres connections. This option is deprecated, instead use "SET pg_pool_max_connections = 42" for newly attached Postgres databases and "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', max_connections=42)" for already attached Postgres databases. | UBIGINT | GLOBAL | [] | 6 |
| pg_debug_show_queries | DEBUG SETTING: print all queries sent to Postgres to stdout | BOOLEAN | GLOBAL | [] | false |
| pg_enable_filter_pushdown | Whether or not to use filter pushdown | BOOLEAN | GLOBAL | [] | true |
| pg_idle_in_transaction_timeout_millis | Postgres idle in transaction timeout in milliseconds to set on scan connections | UINTEGER | GLOBAL | [] | NULL |
| pg_null_byte_replacement | When writing NULL bytes to Postgres, replace them with the given character | VARCHAR | GLOBAL | [] | NULL |
| pg_numeric_as_varchar | Read Postgres numerics without precision and scale or precision > 38 as varchar instead of double | BOOLEAN | GLOBAL | [] | false |
| pg_numeric_nan_as_null | Read Postgres numeric NaN value as NULL instead of throwing an error | BOOLEAN | GLOBAL | [] | true |
| pg_oauth_token | OAuth bearer token for PostgreSQL OAUTHBEARER authentication. Takes priority over the PGOAUTHTOKEN environment variable | VARCHAR | GLOBAL | [] | NULL |
| pg_pages_per_task | The amount of pages per task | UBIGINT | GLOBAL | [] | 1000 |
| pg_pool_acquire_mode | How to acquire connections from the pool: 'force' (always connect, ignore pool limit), 'wait' (block until available), 'try' (fail immediately if unavailable) (default: force) | VARCHAR | GLOBAL | [] | force |
| pg_pool_enable_reaper_thread | Whether to enable the connection pool reaper thread, that periodically scans the pool to check the 'max_lifetime_millis' and 'idle_timeout_millis' and closes the connection which exceed the specified values. Either 'max_lifetime_millis' or 'idle_timeout_millis' must be set to a non-zero value for this option to be effective. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', enable_reaper_thread=TRUE)" | BOOLEAN | GLOBAL | [] | true |
| pg_pool_enable_thread_local_cache | Whether to enable the connection caching in thread-local cache. Such connections are getting pinned to the threads and are not made available to other threads, while still taking the place in the pool. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', enable_thread_local_cache=FALSE)" | BOOLEAN | GLOBAL | [] | false |
| pg_pool_health_check_query | The query that is used to check that the connection is healthy. Setting this option to an empty string disables the health check. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', health_check_query=SELECT 42)" | VARCHAR | GLOBAL | [] | SELECT 1 |
| pg_pool_idle_timeout_millis | Maximum number of milliseconds the connection can be kept idle in the pool. This number is checked when the connection is taken from the pool. When the connection pool reaper thread is enabled ('pg_pool_enable_reaper_thread' option), then this number is checked in background periodically. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', idle_timeout_millis=300000)" | UBIGINT | GLOBAL | [] | 60000 |
| pg_pool_max_connections | Maximum number of connections that are allowed to be cached in a connection pool for each attached Postgres database. This number can be temporary exceeded when parallel scans are used. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', max_connections=42)" | UBIGINT | GLOBAL | [] | 6 |
| pg_pool_max_lifetime_millis | Maximum number of milliseconds the connection can be kept open. This number is checked when the connection is taken from the pool and returned to the pool. When the connection pool reaper thread is enabled ('pg_pool_enable_reaper_thread' option), then this number is checked in background periodically. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', max_lifetime_millis=600000)" | UBIGINT | GLOBAL | [] | 0 |
| pg_pool_wait_timeout_millis | Maximum number of milliseconds to wait when acquiring a connection from a pool where all available connections are already taken. This option only applies to newly attached Postgres databases, to configure a database that is already attached use "FROM postgres_configure_pool(catalog_name='my_attached_postgres_db', wait_timeout_millis=60000)" | UBIGINT | GLOBAL | [] | 30000 |
| pg_query_mode | Query mode, one of: 'AUTO', 'COPY_BINARY', 'PLAIN_QUERY_BINARY', 'PLAIN_QUERY_TEXT' | VARCHAR | GLOBAL | [] | AUTO |
| pg_staleness_query | Custom query used in place of the default table staleness query when pg_staleness_query_enabled resolves to true. Must contain a ${SCHEMA} placeholder and return at least 3 columns (identity, name, revision marker). Empty (default) uses the built-in pg_class/xmin query. | VARCHAR | GLOBAL | [] | NULL |
| pg_staleness_query_enabled | Whether or not the table catalog cache checks Postgres for external DDL changes before serving a cache hit. Defaults to the opposite of pg_use_information_schema_introspection when not explicitly set (off for pg protocol compatible databases that may not support the underlying query, on for Postgres). | BOOLEAN | GLOBAL | [] | false |
| pg_statement_timeout_millis | Postgres statement timeout in milliseconds to set on scan connections | UINTEGER | GLOBAL | [] | NULL |
| pg_use_binary_copy | Whether or not to use BINARY copy to read data | BOOLEAN | GLOBAL | [] | true |
| pg_use_ctid_scan | Whether or not to parallelize scanning using table ctids | BOOLEAN | GLOBAL | [] | true |
| pg_use_information_schema_introspection | Use SQL-standard information_schema views for ATTACH-time schema discovery instead of pg_catalog.For compatibility with pg protocol compatible databases like spanner, cockroach, redshift, … | BOOLEAN | GLOBAL | [] | false |
| pg_use_text_protocol | Whether or not to use TEXT protocol to read data. This is slower, but provides better compatibility with non-Postgres systems | BOOLEAN | GLOBAL | [] | false |
| quack_authentication_function | Name of a callback function for authentication | VARCHAR | GLOBAL | [] | quack_check_token |
| quack_authorization_function | Name of a callback function for authorization | VARCHAR | GLOBAL | [] | quack_nop_authorization |
| quack_cache_max_rows | Maximum rows the server retains in the result cache (0 = unlimited) | UBIGINT | GLOBAL | [] | 100000 |
| quack_debug_drop_batch | DEBUG SETTING: do not send the SEND_DATA batch with this dense index (0 = off); the terminal message must then fail the statement instead of inserting less data | UBIGINT | GLOBAL | [] | 0 |
| quack_debug_duplicate_sends | DEBUG SETTING: send every SEND_DATA batch two times, imitating a transport retry; the receiver must drop the duplicate | UBIGINT | GLOBAL | [] | 0 |
| quack_debug_emit_delay_ms | DEBUG SETTING: max random delay in ms before the fetch collector publishes a batch, stressing out-of-order emission | UBIGINT | GLOBAL | [] | 0 |
| quack_debug_fetch_delay_ms | DEBUG SETTING: max random delay in ms before a FETCH response is published, stressing out-of-order batch arrival | UBIGINT | GLOBAL | [] | 0 |
| quack_debug_send_delay_ms | DEBUG SETTING: max random delay in ms before a SEND_DATA request goes out, stressing out-of-order batch arrival on the server | UBIGINT | GLOBAL | [] | 0 |
| quack_default_client_id | client_id used when ATTACH / quack_query omit one; precomputed at load from $QUACK_CLIENT_ID (empty opts out) or a random per-instance id. Set to '' to opt out. | VARCHAR | GLOBAL | [] | 5e23ab2c-790d-44d1-929f-4f8698e09826 |
| quack_default_heartbeat_timeout | Heartbeat lease timeout in seconds requested by clients when ATTACH / quack_query omit heartbeat_timeout | UBIGINT | GLOBAL | [] | 60 |
| quack_enable_reconnects | Enable reconnect support (clients acknowledge results, the server caches the last result until acknowledged) | BOOLEAN | GLOBAL | [] | false |
| quack_fetch_read_ahead | FETCH requests kept in flight ahead of the scan (0 = number of async threads) | UBIGINT | GLOBAL | [] | 0 |
| quack_loaded_at_us | Epoch microseconds at extension load | BIGINT | GLOBAL | [] | 1794161885659028 |
| quack_prepare_inline_rows | Rows returned inline in the PREPARE response before the remainder is left to FETCH; drains whole batches, so it may overshoot to a batch boundary | UBIGINT | GLOBAL | [] | 24576 |
| quack_rebalance_buffer_bytes | Pending (unstamped) bytes the batch rebalancer buffers before gating non-minimum producers (0 = automatic, memory-manager governed) | UBIGINT | GLOBAL | [] | 0 |
| quack_result_ttl | Seconds an idle cached result is kept before it is dropped (0 = never) | UBIGINT | GLOBAL | [] | 3600 |
| quack_server_keep_alive_timeout | Seconds an idle keep-alive connection is kept open by the RPC server | UBIGINT | GLOBAL | [] | 300 |
| quack_server_max_connections | Maximum concurrent connections the RPC server accepts; beyond this new connections are refused | UBIGINT | GLOBAL | [] | 1024 |
| quack_server_stream_buffer_bytes | Server-side per-stream byte budget, at most a quarter of memory_limit: FETCH counts serialized payload bytes, INSERT counts decoded chunk allocations; 0 disables the limit | UBIGINT | GLOBAL | [] | 268435456 |
| quack_target_batch_bytes | Target in-memory size of one rebalanced batch (one wire message payload); batches are cut when they reach this size | UBIGINT | GLOBAL | [] | 33554432 |
| temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |
| 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 | [] |