Connect a Snowflake table
This page is for an administrator who has a table or view in Snowflake — client accounts, incidents, changes, a gold-layer view of almost anything — and wants to ask Prism questions about it. It connects that one object as a context stream that Prism reads where it lives: nothing is copied out of your warehouse, and every question becomes one statement, compiled by Prism from a short document you write and run under a read-only role you grant.
You will author that document — a source manifest — from the
snowflake_table recipe, which is a small worked example of an arbitrary table:
a record id, a timestamp and three plain attributes. You replace the view name
and the columns with your own. Nothing here needs Tetrate: the manifest and the
credential are entered in Prism's own admin surface, and the connection is
between your appliance and your warehouse.
If your table is a directory of your people — employee ids, work emails, a manager for each person — use Connect a Snowflake directory of your people instead. It is the same connection with the structure a directory needs on top.
Read Take a source live first if you have not connected any source yet. It covers what a probe does; this page is the layer above it.
Before you start: one chart value
A Snowflake source is query-through, so it is answered by the semantic query MCP, and that component has to be on:
mcps:
semanticMcp:
enabled: true # the only component that executes a query-through statement
Without it the source registers, probes and shows as connected while nothing on the agent can read it.
1. What to ask your DBA for
The same four things the directory page lists, for one table or view instead
of a directory: the object itself (cut a view if the table has columns you would
rather not hand over — the view is your access control), a TYPE = SERVICE
login with a key pair, a read-only role with USAGE on the warehouse, the
database and the schema plus SELECT on the one object, and the warehouse
the queries should run on. Connect a Snowflake directory of your
people walks through each, including why a password
will not do for a service login.
2. The five connection values
You enter these on the source in Admin → Context streams, not in the chart:
| Value | What it is |
|---|---|
account | Your account identifier, orgname-account_name |
warehouse | The virtual warehouse the queries run on — the spend lands there |
database | The database holding the table or view |
schema | The schema holding it. Optional: leave it empty when the service login's default schema is the right one |
user | The service login Prism signs in as |
The private key is entered on the same form and stored sealed; it is never a connection value.
3. The worked example, and which parts are yours
Every line you have to decide about carries a marker:
- STRUCTURAL — the engine needs it. Keep it.
- YOURS — yours to decide: the view, every column's name as your view spells
it (
sql:), and whether an attribute exists at all.
apiVersion: prism.tetrate.io/source/v0
name: client_accounts # yours: lower case, and it is permanent
kind: query-through # STRUCTURAL: nothing is copied out of your warehouse
connection:
auth: {type: database, credential_ref: accounts_key}
credential_mode: service
tier: warehouse
database:
engine: snowflake
auth_mode: key_pair # STRUCTURAL
account_parameter: account
warehouse_parameter: warehouse
database_parameter: database
schema_parameter: schema
user_parameter: user
read_only_role: PRISM_READER # yours: the role you granted
parameters:
account: {type: string, required: true}
warehouse: {type: string, required: true}
database: {type: string, required: true}
schema: {type: string, required: false}
user: {type: string, required: true}
model:
datasets:
- name: accounts
source: CLIENT_ACCOUNTS_V # yours: a BARE view name — see below
stream: Client accounts # yours: the name a reader sees beside every figure
primary_key: [account_id] # STRUCTURAL: one row per record
fields:
- name: account_id # STRUCTURAL: the key every count is taken over
type: string
sql: ACCOUNT_ID # yours
- name: updated_at # STRUCTURAL: the time windows and trends group by
type: timestamp
time_intervals: [DAY, WEEK, MONTH]
sql: LAST_MODIFIED # yours
- name: status # yours: an attribute — rename, replace or delete it
type: string
sql: ACCOUNT_STATUS # yours
- name: segment # yours
type: string
sql: SEGMENT # yours
metrics:
accounts:
type: count_distinct
sql: account_id # a FIELD name, not a column
time_field: updated_at
unit: accounts
policy:
source_label: Client accounts # yours: what a reader is told a figure came from
legacy_tools: []
verification:
status: connected_unverified
questions:
- prompt: How many accounts are there? Check it against a COUNT(*) in your own session.
query:
source: client_accounts
dataset: accounts
metrics: [accounts]
verdict: pending
dataset.source is a bare view name. It is written into the statement
verbatim, so a database or schema written into it would put your address into
the document; both come from the session instead, from the connection values
above. Write it as the object was created — Snowflake folds an unquoted name to
upper case.
Every field has an explicit sql:, even where it matches the name. A
column name that happens to match is indistinguishable from one somebody
checked, and the mapping is the part of this document you are copying.
Nothing here makes it your organizational directory. A manifest carries no
role:: which source is the directory every person-shaped answer resolves
through is a designation you make on a registered source (Designate on
Admin → Context streams), and a table that is not a list of people should
not be it.
4. Check every column exists — before you register anything
Run the statement Prism will run, in your own Snowflake session, as the service login, with the role you granted:
SELECT ACCOUNT_ID, LAST_MODIFIED, ACCOUNT_STATUS, SEGMENT
FROM CLIENT_ACCOUNTS_V
LIMIT 5;
with your own view and columns in place of the example's. If it fails, the source would register, probe and then fail on every question — the probe proves the connection, not the columns.
5. Register it, approve it, enable it
Open Admin → Context streams, pick the Snowflake table recipe
(snowflake_table), open Review the manifest and replace the document with
yours. Enter the five connection values and the private key, then probe. A
passing probe means the account was reachable, the key was not rejected, and
the session is the one Prism asked for; it does not mean the view exists or
that a column you named is real, which is what section 4 is for.
Then approve the source, and only then enable it: enable is refused
from probed.
6. Verify it against your own figures
Rewrite the verification questions around your own table — one or two counts you already know the answer to — and check each against a figure you trust. Enabling a source means this installation reached it; whether the figures are right is yours to decide, on the verification screen.