connect a database

Connect Snowflake

Provisioning read-only credentials for Snowflake — the same instructions Evalyst shows you when a credential check fails.

source of truth: app repo docs/readonly/snowflake.md

Two things matter here: read-only access, and a warehouse you chose. Snowflake bills by warehouse-second, so attaching a source without pinning a small, auto-suspending warehouse means Evalyst spends your money on whatever size happens to be default.

USE ROLE ACCOUNTADMIN;

-- 1. a small warehouse that suspends almost immediately
CREATE WAREHOUSE IF NOT EXISTS EVALYST_WH
    WAREHOUSE_SIZE = XSMALL
    AUTO_SUSPEND = 60           -- seconds
    AUTO_RESUME = TRUE
    INITIALLY_SUSPENDED = TRUE;

-- 2. the role: usage, never modification
CREATE ROLE IF NOT EXISTS EVALYST_READER;
GRANT USAGE ON WAREHOUSE EVALYST_WH  TO ROLE EVALYST_READER;
GRANT USAGE ON DATABASE  <YOUR_DB>   TO ROLE EVALYST_READER;
GRANT USAGE ON ALL SCHEMAS IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;
GRANT SELECT ON ALL TABLES  IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;
GRANT SELECT ON ALL VIEWS   IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;

-- 3. and on objects created later
GRANT USAGE  ON FUTURE SCHEMAS IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;
GRANT SELECT ON FUTURE TABLES  IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;
GRANT SELECT ON FUTURE VIEWS   IN DATABASE <YOUR_DB> TO ROLE EVALYST_READER;

-- 4. the login
CREATE USER EVALYST
    PASSWORD = '<STRONG_PASSWORD>'
    DEFAULT_ROLE = EVALYST_READER
    DEFAULT_WAREHOUSE = EVALYST_WH
    MUST_CHANGE_PASSWORD = FALSE;
GRANT ROLE EVALYST_READER TO USER EVALYST;

-- 5. a hard ceiling on spend, independent of anything Evalyst does
CREATE RESOURCE MONITOR EVALYST_RM WITH CREDIT_QUOTA = 20
    TRIGGERS ON 100 PERCENT DO SUSPEND;
ALTER WAREHOUSE EVALYST_WH SET RESOURCE_MONITOR = EVALYST_RM;

Watch the role name in every GRANT: Snowflake accepts a grant to a role that does not exist, so one typo silently produces a role with no privileges and queries that return nothing. SHOW GRANTS TO ROLE EVALYST_READER; after step 3 to confirm.

Source config

{
  "account": "<org>-<account>",
  "database": "<YOUR_DB>",
  "schema": "PUBLIC",
  "role": "EVALYST_READER",
  "cost_caps": { "warehouse": "EVALYST_WH", "statement_timeout_ms": 30000 }
}

Credentials go in the vault, not here: DB_USER + DB_PASSWORD, or set "private_key_auth": true in config and supply SNOWFLAKE_PRIVATE_KEY (+ SNOWFLAKE_PRIVATE_KEY_PASSPHRASE) instead — key-pair auth is the better choice for a service identity.

Check it yourself

USE ROLE EVALYST_READER; USE WAREHOUSE EVALYST_WH;
SELECT COUNT(*) FROM <YOUR_DB>.PUBLIC.<TABLE>;   -- works
CREATE TABLE <YOUR_DB>.PUBLIC.PROBE (I INT);     -- must fail

Evalyst additionally pins STATEMENT_TIMEOUT_IN_SECONDS on every session and tags its queries QUERY_TAG = 'evalyst', so you can account for its spend in SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY.