Configure sources and credentials

Every source is part of the reviewed repository contract. The manifest stores connection metadata and the name of a password variable, but never the password itself.

Declare a source

[[sources]]
name = "reporting"
host = "sql.example.com"
port = 1433
database = "Reporting"
user = "skiff_reader"
password_env = "REPORTING_DB_PASS"
trust_cert = false
snapshot = false
Field Requirement
name Unique, nonempty source name used by [[queries]]
host SQL Server hostname or address
port Optional; defaults to 1433
database Database selected when the connection opens
user SQL Server login name
password_env Name of the process environment variable holding the password
trust_cert Optional; defaults to false
snapshot Optional; defaults to false

Source names are matched case-insensitively. Skiff rejects empty or duplicate names, invalid ports, and password-variable names containing =.

Use least-privilege logins

SQL Server permissions are the authorization boundary. Give each source login SELECT access to only the intended tables or views. Skiff checks query shape, but it does not reproduce database grants with an application allowlist.

Do not set trust_cert = true for a production server. That option disables certificate verification and exists for deliberately untrusted development certificates.

Supply passwords through the process

export REPORTING_DB_PASS='...'
skiff check

You may load a gitignored .env with your shell or direnv; Skiff itself reads only the process environment. This keeps values out of skiff.toml but does not make the environment a secrets manager.

Choose source consistency

By default, a source runs without a transaction. Schedule refreshes outside the source's load window and use checks to catch tables that disagree.

Set snapshot = true when all queries for one source must observe the same database state:

[[sources]]
name = "reporting"
host = "sql.example.com"
database = "Reporting"
user = "skiff_reader"
password_env = "REPORTING_DB_PASS"
snapshot = true

This requires ALLOW_SNAPSHOT_ISOLATION on that database and adds row-versioning cost to writes. Have the database owner make that decision; do not substitute NOLOCK.

Different sources load in parallel. Snapshot consistency applies within one source, not across independent SQL Server databases.

Set global limits

[limits]
max_rows = 500000
timeout_secs = 60

timeout_secs must be greater than zero. max_rows must be greater than zero or -1; set it to -1 to disable the row limit while keeping the timeout. The defaults are 500,000 rows per query and 60 seconds.

Keep paths inside the repository

The output, query files, and check files must use relative paths that remain inside the repository. Query and check files must end in .sql; the output must end in .duckdb.

Skiff resolves real paths before use and rejects traversal, absolute paths, and symlink escapes. The destination must be a regular, single-link file when it already exists.