Skip to content

Conversation

Y--
Copy link
Collaborator

@Y-- Y-- commented Mar 14, 2025

Revamp MotherDuck settings and secret management

This PR removes any GUC setting for MotherDuck and replaces it with a combination of SERVER and USER MAPPING for a newly implemented pg_duckdb Foreign Data Wrapper.

New MotherDuck setup:

Users may now define one (and at most one) SERVER for motherduck:

CREATE SERVER <server name> 
FOREIGN DATA WRAPPER pg_duckdb
TYPE 'motherduck'
[OPTIONS (
     [tables_owner_role 'some user'],	-- the role bgw assigns to MD tables 
										-- (by default server creator/owner) 
     [default_database]					-- Which MD DB is synced (default "my_db")
)];

Once the SERVER is created, for MotherDuck to be enabled, it needs at least one USER MAPPING:

CREATE USER MAPPING FOR <PG user> 
SERVER <FDW server name> 
OPTIONS (
  token '<some token>'
);

Removed GUC settings:

The following GUC settings were thus removed and are now obsolete:

  • motherduck_enabled: now implied by a SERVER and USER MAPPING
  • motherduck_token: now defined in a USER MAPPING
  • motherduck_postgres_database: now implied by the database in which the SERVER & USER MAPPING are defined
  • motherduck_default_database: now defined as an option of the motherduck server

Convenience function:

In order to enable MotherDuck support easily, we also provide the following helper:

-- Token will be read from environment if not provided
-- Default database is `my_db` if not provided
SELECT duckdb.enable_motherduck('<token>', '<default_motherduck_db>')

@Y-- Y-- force-pushed the yl/secrets-md-fdw branch from 2036a37 to 7e5137b Compare March 14, 2025 16:07
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch 12 times, most recently from 645dbd1 to 2c53ebd Compare March 19, 2025 08:20
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch 2 times, most recently from f43c504 to 4b9eb9c Compare March 19, 2025 09:40
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch 2 times, most recently from 448567c to d822314 Compare March 19, 2025 10:07
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch from 485d8f7 to b4a9fff Compare March 19, 2025 16:33
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch from 0247b71 to 03edf5e Compare March 21, 2025 08:35
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch from 03edf5e to c8535cd Compare March 21, 2025 08:58
@Y-- Y-- force-pushed the yl/secrets-md-fdw branch from 7959f7b to 0727fc0 Compare March 21, 2025 12:58
JelteF added 3 commits March 21, 2025 14:00
We were checking ret instead of `errno` for the error codes. That does
not work on Linux at least. `ret` is always -1 there. So the additional
background workers would continuously restart.

This also uses the %m in other cases instead of manually calling `strerror`.
@Y-- Y-- marked this pull request as ready for review March 21, 2025 13:51
@Y-- Y-- requested a review from JelteF March 21, 2025 13:51
@Y-- Y-- enabled auto-merge (squash) March 21, 2025 13:51
@Y-- Y-- merged commit 2065ff1 into main Mar 21, 2025
14 checks passed
@Y-- Y-- deleted the yl/secrets-md-fdw branch March 21, 2025 15:18
Y-- added a commit that referenced this pull request Apr 15, 2025
In #668 we changed the
configuration of MotherDuck tokens to use `FOREIGN SERVER` + `USER
MAPPING` under the hood, along with some helper functions for the most
common usages to get people started.

In this PR, we align our secrets management with the same mechanism.
That way different PG users can use different S3 tokens to connect to
the same bucket. We also introduce two helper functions
`create_simple_secret` and `create_azure_secret` for the most basic
usage.

We are now validating secrets using DuckDB directly and store whatever
the user provides as long as it leads to a valid secret creation. This
allow to support virtually any kind of secrets type and their options
that DuckDB supports.

Since `SERVER` options are visible to any PG user, the sensitive ones
such as `connection_string`, `secret`, `session_token` and `token` are
prohibited to in its definition and must be stored in the `USER
MAPPING`.

DuckDB secrets are created by concatenating `SERVER` and `USER MAPPING`
options (if they exists).

Implements #683
Fixes #104
@YuweiXiao
Copy link
Contributor

Do we support SCOPE option? If not, I could help implement.

@JelteF
Copy link
Collaborator

JelteF commented Aug 12, 2025

It definitely should. It now validates the options with duckdb. If it doesn't in practice then there's a bug.

@YuweiXiao
Copy link
Contributor

Manually creating the server with option is working. But we didn't expose it through the udf create_simple_secret

CREATE SERVER my_server TYPE 's3' FOREIGN DATA WRAPPER duckdb OPTIONS (SCOPE 's3://my-other-bucket');

@JelteF
Copy link
Collaborator

JelteF commented Aug 12, 2025

The idea was that create_simple_secret was only for the most simple usecases. And then have more complicated ones use the regular create server syntax. I guess scope might be common enough that it warrants being an argument in create_simple_secret.

@YuweiXiao
Copy link
Contributor

YuweiXiao commented Aug 12, 2025

By the way, the foreign data wrapper DuckDB is not granted to normal users. So only superusers are able to create secrets, while normal users can only utilize them. Is this by design, or can we loosen the permissions?

Also, normal user can see secrets by select duckdb.raw_query($$FROM duckdb_secrets()$$)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants