Before you begin
You will need:- A Snowflake user authenticated via key-pair (not password). Follow Snowflake’s key-pair authentication guide to generate an RSA key pair and register the public key on the user with
ALTER USER <user> SET RSA_PUBLIC_KEY='...'. - The private key in PEM format (starts with
-----BEGIN PRIVATE KEY-----). Keep it safe — you’ll paste it into SegmentStream during setup. - A Snowflake warehouse the user can use, and privileges to
USAGEon the warehouse,USAGEon the database and schema, andSELECTon the tables the query touches. - (Optional) A dedicated role to scope permissions.
Example Snowflake setup
If you’re setting up SegmentStream access from scratch, the pattern below is a good starting point. It creates a dedicated role and service user, wraps the source data in a secure view so only what you deliberately expose is readable, and grants the minimum privileges needed. Run asACCOUNTADMIN:
Getting started
Navigate to Data Sources
Inside the admin panel navigate to the Data Sources page and click + NEW on the top right corner.
Provide the private key
Paste the Private Key (PEM) into the input field. If the key is encrypted, also fill in the Private Key Passphrase. Click Save.
Configure the connection
Fill in the connection and query fields (see Configuration fields below), then click Save.
Configuration fields
Your Snowflake account identifier, including the region and cloud
(e.g.
xy12345.us-east-1 or xy12345.eu-central-1.aws). You can find it
in the URL you use to log in to Snowflake — everything between https://
and .snowflakecomputing.com.The Snowflake username the private key is registered against.
The Snowflake warehouse used to run the query. The user must have
USAGE
privilege on this warehouse.Optional. The role Snowflake assumes when running the query. Leave empty
to use the user’s default role.
The database that contains the tables you want to query.
The schema inside the database. Combined with
Database, this is the
search path Snowflake uses for unqualified table names in your query.The
SELECT statement executed on every daily run. Use {{date_from}}
and {{date_to}} placeholders to filter to the daily window — see
Writing the query.Name of the BigQuery table (inside your project’s SegmentStream dataset)
that the query result is loaded into. The table is created on the first
successful run and re-populated on every subsequent run.
When enabled, the destination table is date-partitioned by the daily
window, and each run replaces the day’s partition with the query
results. When disabled, each run replaces the entire table.
Writing the query
SegmentStream runs your query once per day, substituting the placeholders{{date_from}} and {{date_to}} with the daily window as YYYY-MM-DD
strings. Wrap the placeholders in single quotes so Snowflake interprets them
as dates:
Destination table
The destination table lives in the SegmentStream-managed BigQuery dataset for your project. The schema is inferred from the query output on the first run and enforced on subsequent runs; adding a new column to the query requires deleting the destination table and letting SegmentStream re-create it. When Partition table by date is enabled the table has a date partition column matching the daily window, and each run replaces the partition for its own window only — safe for backfills and re-runs. When it’s disabled the whole table is truncated and reloaded on every run.Troubleshooting
Authentication failed / JWT signature error
Authentication failed / JWT signature error
Check that the private key you pasted matches the public key registered
on the Snowflake user with
DESC USER <user>. The RSA_PUBLIC_KEY_FP
fingerprint on Snowflake side should match the fingerprint of the
private key you provided.Warehouse suspended or user has no privilege
Warehouse suspended or user has no privilege
The Snowflake user must have
USAGE on the warehouse and privileges to
read from the database, schema, and tables the query references. Run
SHOW GRANTS TO USER <user> in Snowflake to audit.Query returned zero rows
Query returned zero rows
Confirm that
{{date_from}} and {{date_to}} cover the range you
expect — the default is a one-day window ending at your project’s most
recent active date. If you use >= date_from AND < date_to
(recommended), the window excludes the upper bound; adjust filters
accordingly.