Skip to content

The catalog file

The catalog file (--catalog) says what curral attaches at startup: extensions, secrets, databases and settings. After startup the DuckDB configuration is locked, so changes to this file need a restart.

# INSTALL + LOAD at boot. Autoloading is off afterwards, so list every
# extension a query may need.
extensions: [httpfs, iceberg]
# SET GLOBAL key = value
settings: {}
# CREATE OR REPLACE SECRET name (TYPE type, KEY value, ...)
secrets:
- name: lake_catalog
type: iceberg
params: { CLIENT_ID: "${ICEBERG_CLIENT_ID}", CLIENT_SECRET: "${ICEBERG_CLIENT_SECRET}" }
# ATTACH 'path' AS name (KEY value, ...)
databases:
- name: sales
path: ${CURRAL_DATA:-./data}/sales.duckdb
- name: lake
path: ${ICEBERG_WAREHOUSE}
schema: analytics
options: { TYPE: iceberg, SECRET: lake_catalog, ENDPOINT: "${ICEBERG_ENDPOINT}" }
# Catalog used for unqualified names. Defaults to the first database.
default: sales
# Escape hatch: SQL run after the ATTACHes and before lockdown.
init_sql: []

Any string value accepts ${VAR} and ${VAR:-default}.

  • A missing variable without a default aborts startup, so credentials are never empty by accident.
  • Variables referenced in the catalog are removed from the process environment after startup.
  • Secret values and paths are redacted in the log.
Field
name catalog name used in SQL (sales.main.orders)
path anything DuckDB can ATTACH: a file, a warehouse, a connection string
schema schema for unqualified names; default main. Iceberg has no main, so set the namespace
options passed through to ATTACH as-is (TYPE, SECRET, READ_ONLY…)
cache_ttl cache REST catalog metadata; see Iceberg and R2

Because options are passed through, Iceberg, Postgres, S3 and any other ATTACH-capable source work the same way.

By default enable_external_access is off: read_parquet('s3://...'), COPY ... TO and new ATTACHes are blocked. To let curral read remote storage that attached catalogs point to, allow only those prefixes:

Terminal window
curral serve ... --allowed-path s3://my-bucket/ --allowed-path /srv/data/

--external-access turns external access fully on. Prefer --allowed-path.

Terminal window
curral check --catalog catalog.yaml --users users.yaml --policy policy.rego

check validates every file and mounts the catalog without starting HTTP.