Skip to main content
Version: 0.8.1

Getting started

This page runs the service on a laptop, with SQLite and a local key, and attaches DuckDB to it. Docker does the same in one command - the service, Keycloak with a realm, and sample secrets.

1. An identity provider​

The service verifies tokens from any OIDC issuer. Two ways to get one:

  • Keycloak in docker, as tresor's own tests use it: docker compose -p tresor-kc up -d in tresor's server/ (its docker-compose.yml and test realm). The issuer is then http://127.0.0.1:18480/realms/tresor.
  • Microsoft Entra ID: register the service's API and the clients as tresor's Entra guide says.

2. The service​

Get the binary (go build ./cmd/tresor-server), or run the image ghcr.io/hugr-lab/tresor-server:edge.

A configuration for the Keycloak above:

server.yaml
listen: 127.0.0.1:8443
public_url: http://127.0.0.1:8443 # plain http only on this machine
state:
kind: sqlite
path: ./tresor.db
keys:
kind: local
key_env: TRESOR_KEK # 32 bytes, base64
issuers:
- issuer: http://127.0.0.1:18480/realms/tresor
audience: duckdb-secrets
client_id: duckdb
scopes: [openid]
human_flows: [authorization_code, device_code]
service_flows: [client_credentials]
roles_claim: realm_access.roles
service: {claim: client_id}
policy:
admins: [role:secrets_admin]
export TRESOR_KEK="$(openssl rand -base64 32)" # keep it: the database's material is sealed under it
./tresor-server -config server.yaml

The same settings can come from the environment instead of a file: see Configuration.

The service answers:

  • GET /healthz: the process is up.
  • GET /readyz: the state store, the key and every issuer answer.
  • GET /.well-known/duckdb-secrets: the protocol's discovery.

3. DuckDB​

INSTALL tresor FROM community; -- DuckDB 2.0.0's community extensions
LOAD tresor;

ATTACH 'tresor:127.0.0.1:8443' AS corp (INSECURE_HTTP true); -- a browser login
SELECT * FROM corp.whoami();

An administrator (a secrets_admin here) stores a secret, and grants its use to a role:

CREATE PERSISTENT SECRET lake IN corp (TYPE s3, KEY_ID 'AKIA...', SECRET '...', SCOPE 's3://lake');
CALL corp.grant_secret('lake', 'role:analysts', ['use']);

Anyone with the role then reads s3://lake/... with no secret of their own. tresor's getting started goes on from here: people and services, servers acting for users, what DuckDB sees.

A DuckDB in a sandbox (enable_external_access = false) stops tresor's own requests too: name the service's URL and the identity provider's hosts first (tresor's DuckDB's sandbox):

SET allowed_directories = ['https://secrets.corp.example/', 'https://login.corp.example/'];
SET enable_external_access = false;

Web pages: tresor in DuckDB-wasm​

A page that runs DuckDB in the browser loads tresor there too, and calls the service across origins (tresor's protocol, Browsers). Name the page's origin:

cors:
allowed_origins: [https://notebook.example]

The service then answers CORS on discovery and /v1 for that page only (Configuration). The page signs in at the IdP itself (tresor's tresor_web_login): register its origin with the IdP's SPA client.

Next​