Your company login, your role's secrets: S3, Postgres, APIs and more from a secrets service, with nothing on the laptop.
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 tresor FROM community;
LOAD tresor;
Example
INSTALL tresor FROM community;
-- no LOAD: attaching a tresor: path loads it
ATTACH 'tresor:secrets.corp.example' AS corp; -- log in once, with your company account
FROM corp.secrets(); -- the secrets your roles may use
FROM 's3://lake/sales/*.parquet'; -- the right one is found by scope, like any secret
About tresor
Stop copying keys into notebooks, .env files and CI variables. tresor makes your organization's secrets
part of DuckDB's own secret lookup: log in once with the company identity provider - Entra ID, Okta,
Keycloak, Auth0 - and every secret your roles may use is simply there. S3, GCS, R2, Azure, Postgres,
MySQL, HTTP APIs, Iceberg catalogs: queried as usual, with no key on the laptop and nothing to rotate by hand.
Website and docs: https://hugr-lab.com/tresor
One login, everywhere DuckDB runs. The browser or a device code, once; the login is remembered in the
OS keychain, so the CLI, DuckDB UI, Jupyter, DBeaver and your scripts all attach with no second sign-in.
In DuckDB UI or a notebook, FROM tresor_login(...) returns the link and code as a row.
Secrets by role, managed in one place. Administrators create secrets - from SQL
(CREATE PERSISTENT SECRET ... IN corp) or a web console - and grant their use to roles and groups.
Revoke a grant and the next query no longer sees the secret. The key material can stay in the vault you
already run (HashiCorp Vault / OpenBao, Azure Key Vault, AWS and GCP secret managers), referenced, never
copied.
Short-lived by design. Any parameter can be generated per caller on each read - a token minted for
you by token exchange, a claim of your own token - and cached only until shortly before it expires.
httpfs refreshes S3 credentials on its own. Variables work too: SET motherduck_token = corp.variable(...).
Pipelines without passwords. Jobs log in as themselves: GitHub Actions OIDC, Kubernetes service accounts, Azure managed identities, a private key - no stored secret at all. dbt-duckdb works through its profile.
Inside your own application. Python, Go, Rust, Java and DuckDB-wasm in the browser: an app that
already signed its user in hands tresor that same token (tresor_web_token) and each renewal - no second
login, and the app's refresh token never leaves it.
Audited and open. Every login, lookup, write and grant is an audit event in DuckDB's log, exportable over OpenTelemetry. Nothing secret is written to disk or logged. The service behind it speaks an open protocol, duckdb-secrets/1 - a short spec any service can implement; tresor-server is the production one (one container on Azure, Kubernetes, AWS or GCP).
Issues and feature requests: https://github.com/hugr-lab/tresor
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| tresor_login | table | NULL | NULL | |
| tresor_logoff | table | NULL | NULL | |
| tresor_secret_param | scalar | NULL | NULL | |
| tresor_version | scalar | NULL | NULL | |
| tresor_web_login | table | NULL | NULL | |
| tresor_web_token | table | 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 |
|---|---|---|---|---|---|
| temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |
| tresor_audit_level | tresor: what tresor writes to duckdb's log (type 'tresor'): off, denied (refusals and failures) or all | VARCHAR | GLOBAL | [] | off |
| tresor_http_client | tresor: the HTTP client of its requests - builtin (its own) or duckdb (DuckDB's, httpfs where loaded; the only one in wasm); the default from TRESOR_HTTP_CLIENT | VARCHAR | GLOBAL | [] | builtin |
| tresor_keychain | tresor: where a person's login is remembered - auto (the OS credential store, where there is one), off, or memory (this instance only); the default from TRESOR_KEYCHAIN | VARCHAR | GLOBAL | [] | auto |