Skip to content

MotherDuck plugin for DuckDB - #511

Merged
rr3khan merged 15 commits into
1Password:mainfrom
sterlinm:motherduck-plugin
Oct 8, 2026
Merged

rr3khan merged 15 commits into
1Password:mainfrom
sterlinm:motherduck-plugin

Conversation

@sterlinm

@sterlinm sterlinm commented Jan 27, 2025 •

Copy link
Copy Markdown
Contributor

Overview

Creating a plugin for the DuckDB CLI to allow you to securely store your MotherDuck token using 1password.

Type of change

  • Created a new plugin
  • Improved an existing plugin
  • Fixed a bug in an existing plugin
  • Improved contributor utilities or experience

Related Issue(s)

  • Resolves: #
  • Relates: #

How To Test

The plugin is used when the duckdb CLI is called and the user attempts to connect to MotherDuck without providing a token via environment variable or as part of the connection string.

This would require authentication with 1password: duckdb 'md:'.

From the DuckDB CLI interface, if you run PRAGMA PRINT_MD_TOKEN; it should print out the token that you have stored in 1password.

These would not require authentication with 1password:

  • duckdb
  • duckdb localdb.ddb
  • duckdb 'md:my_db?motherduck_token=<motherduck_token>
  • motherduck_token=<motherduck_token> duckdb 'md:'

You can test that it uses the token from the connection string or environment variable (rather than 1password) by running the following commands:

  • duckdb 'md:my_db?motherduck_token=<motherduck_token> -c 'PRAGMA print_md_token'
  • motherduck_token=<motherduck_token> duckdb 'md:' -c 'PRAGMA print_md_token'

The token that is printed out should match the provided token rather than the one saved in 1password.

Changelog

@sterlinm

Copy link
Copy Markdown
Contributor Author

Hi folks! If there's any more information you need from me, please let me know. Thanks!

@sterlinm

Copy link
Copy Markdown
Contributor Author

Hi! Just checking in on this again. Thanks!

@sterlinm

Copy link
Copy Markdown
Contributor Author

Is it fair to assume that the shell extensions project is dead?

@edif2008 edif2008 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! 😄

I've left a couple of improvements that I've seen by trying out MotherDuck myself.

Comment thread plugins/motherduck/plugin.go Outdated
Comment thread plugins/motherduck/duckdb.go Outdated
Comment thread plugins/motherduck/access_token.go Outdated
Comment thread plugins/motherduck/access_token.go Outdated
Comment thread plugins/motherduck/access_token.go
@sterlinm

Copy link
Copy Markdown
Contributor Author

@edif2008 Thanks for the review, and sorry for the delayed response! I'll address your comments soon.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR contains unsigned commits. To get your PR merged, please sign those commits (git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}) and force push them to this branch (git push --force-with-lease).

If you're new to commit signing, there are different ways to set it up:

Sign commits with gpg

Follow the steps below to set up commit signing with gpg:

  1. Generate a GPG key
  2. Add the GPG key to your GitHub account
  3. Configure git to use your GPG key for commit signing
Sign commits with ssh-agent

Follow the steps below to set up commit signing with ssh-agent:

  1. Generate an SSH key and add it to ssh-agent
  2. Add the SSH key to your GitHub account
  3. Configure git to use your SSH key for commit signing
Sign commits with 1Password

You can also sign commits using 1Password, which lets you sign commits with biometrics without the signing key leaving the local 1Password process.

Learn how to use 1Password to sign your commits.

Watch the demo

sterlinm added 3 commits June 20, 2025 00:51
- length is not fixed so remove
- token can include . and _
…duck.

Defer to environment variable or provided token value if either is set.
@sterlinm
sterlinm force-pushed the motherduck-plugin branch from 4620375 to 14818e7 Compare June 20, 2025 07:52
@sterlinm

Copy link
Copy Markdown
Contributor Author

@edif2008 This should be ready for another look. Thanks!

@sterlinm

Copy link
Copy Markdown
Contributor Author

@edif2008 One design choice I'm not sure how to address that I'd love advice on.

As it is now, if the user has set motherduck_token in their environment variables the plugin will use that value and not prompt the user to authenticate with 1password at all. The idea is that if you've already set the environment variable than you don't want to get prompted for authentication.

Ideally this would be something you could configure when you initialize the plugin, but I'm not sure if there's a good way to do that, but I'm not sure if that's supported.

Other than that I think this is ready to go. Let me know if there's anything else I should address. Thanks!

@sterlinm

sterlinm commented Jul 2, 2025

Copy link
Copy Markdown
Contributor Author

I've been using this locally now and it's been pretty convenient. I'd love to get it officially supported so I could promote it to people. Thanks!

@sterlinm

Copy link
Copy Markdown
Contributor Author

Hi! Just checking in again to see if we can get this merged. 😄

@sterlinm

Copy link
Copy Markdown
Contributor Author

Checking in again, thanks!

@sterlinm

Copy link
Copy Markdown
Contributor Author

@edif2008 Let me know if there's anything I can do that would make it easy to get this merged. Thanks!

@SimonBarendse SimonBarendse left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! 🙌

@SimonBarendse
SimonBarendse requested review from Marton6 and edif2008 and removed request for edif2008 October 29, 2025 17:17
@sterlinm

Copy link
Copy Markdown
Contributor Author

Thanks @SimonBarendse! I'm really excited to see movement on this!

@rr3khan rr3khan closed this Sep 23, 2026
@rr3khan rr3khan reopened this Sep 23, 2026
rr3khan and others added 2 commits October 8, 2026 14:08
Replace space indentation with tabs in ForMotherDuckButTokenNotSet so
golangci-lint's gofmt check passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rr3khan and others added 7 commits October 8, 2026 14:20
The provisioner and importer use the lowercase motherduck_token env var,
which the MotherDuck extension gives precedence over MOTHERDUCK_TOKEN.
Align the test expectations with that and drop leftover TODO comments.
Add NeedsAuth cases for local databases, MotherDuck connection strings,
ATTACH from a command, and a token supplied via the connection string or
the motherduck_token env var. Token env vars are cleared so a developer's
own shell doesn't affect the results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MotherDuck extension reads its token from either motherduck_token or
MOTHERDUCK_TOKEN. The plugin only deferred to motherduck_token, so with
just MOTHERDUCK_TOKEN set it still prompted and injected motherduck_token,
which takes precedence and silently replaced the user's token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ixes

DuckDB connects to MotherDuck for 'motherduck:' as well as 'md:', and
matches the prefix case-insensitively ('MD:' works too). Those connections
previously skipped the plugin and fell back to MotherDuck's browser login.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plain substring match on "md:" also fired on text like 'cmd:' inside a
query passed with -c, prompting for a token DuckDB wouldn't use. Require
the prefix to not follow a word character. Also drop the empty-args check,
which the loop already covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ken=

DuckDB accepts 'token=' as an alias for 'motherduck_token=' in a MotherDuck
connection string, and that token wins over any env var. Skip the plugin
for either parameter so users aren't prompted for a token that won't be
used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The importer only looked at motherduck_token, so a token exported as
MOTHERDUCK_TOKEN, which the MotherDuck extension also reads, wasn't
offered during op plugin init.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rr3khan

rr3khan commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Thanks so much for the contribution, @sterlinm, and for sticking with this PR for so long! 🦆

I merged in the latest main and pushed some fixes so CI passes:

  • Formatted duckdb.go with gofmt, and changed the test env var to motherduck_token to match the plugin.
  • While testing against the DuckDB CLI I also tightened a few edge cases:
    • The plugin no longer asks for a token when MOTHERDUCK_TOKEN is already set (DuckDB reads both names).
    • It now recognizes motherduck: and uppercase MD: connection strings.
    • It no longer asks for a token when the connection string already has a token= parameter.
    • It no longer triggers on md: inside other words, like cmd:.
    • The importer now finds MOTHERDUCK_TOKEN too.
    • Added tests for when the plugin needs authentication.

I'm merging this now, and the plugin will be available in the next 1Password CLI release. Thanks again!

@rr3khan
rr3khan merged commit c7b77ba into 1Password:main Oct 8, 2026
3 checks passed
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.

4 participants