Native App Setup Guide
This guide walks through setting up and launching the RelationalAI Rel Agent. By the end, you’ll have a running engine and access to the Rel Agent UI in your browser.
Prerequisites
Section titled “Prerequisites”- Rel Agent preview access enabled for your account.
- The RAI Native App installed in your Snowflake account.
- A Snowflake account with
ACCOUNTADMINprivileges (or equivalent). - A warehouse for the Rel Agent service to use.
Set Up the App
Section titled “Set Up the App”The script below walks you through the following steps:
-
Set configuration variables. Define the engine name, secrets location, service user, role, warehouse, and Native App name — all in one place so the rest of the script can reference them automatically.
-
Enable Cortex. Ensure cross-region Cortex is active on your account so the Rel Agent can call Snowflake’s LLM service.
-
Create secrets. Store your Snowflake credentials and LLM token as Snowflake secrets, then grant the Native App read access to them.
-
Configure network access. Create a network rule that allows outbound traffic from the Rel Agent service, wire it into an External Access Integration, and grant the Native App access to both.
-
Verify role access and launch the engine. Confirm that your service role exists, is granted to the service user, has warehouse access, and holds a RAI application role — then start the Rel Agent engine.
-
Access the Rel Agent UI. Retrieve the engine’s ingress URL and open it in your browser.
To run the script, you can use a Snowflake notebook, a SQL worksheet, or the SnowSQL command-line client.
- Download the Rel Agent setup notebook.
View a preview of the setup notebook.
Rel Agent Setup
Step 1 — Set configuration variables
Replace the placeholder values below with your own, then run this block.
-- ============================================================-- Configuration — update these values for your environment-- ============================================================-- EngineSET engine_name = 'my_rel_agent'; -- name you choose for this engineSET engine_size = 'S'; -- compute size (S, M, L, etc.)-- Secrets location (FQNs are derived automatically)SET secret_db = 'modeler_setup'; -- database for secrets and network ruleSET secret_schema = $secret_db || '.config'; -- schema for secrets and network ruleSET cred_secret = $secret_schema || '.SNOWFLAKE_CREDENTIALS';SET llm_secret = $secret_schema || '.LLM_KEY';SET network_rule = $secret_schema || '.modeler_network_rule';-- CredentialsSET service_user = '<your_service_user>'; -- Snowflake user for the Rel Agent-- AccessSET eai_name = 'modeler_eai'; -- External Access Integration nameSET service_role = '<role_with_warehouse_access>';SET warehouse = '<warehouse_name>';SET native_app = 'RELATIONALAI'; -- name of the installed Native AppStep 2 — Enable Cortex
Cortex must be enabled on your Snowflake account before the Rel Agent can use it for LLM access. LOOK FOR: CORTEX_ENABLED_CROSS_REGION should be set to ‘ANY_REGION’.
SHOW PARAMETERS LIKE 'CORTEX_ENABLED_CROSS_REGION' IN ACCOUNT;-- Enable cross-region Cortex if not already setALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';Step 3 — Create secrets
The Rel Agent requires two secrets: one for Snowflake authentication and one for LLM access via Cortex. Replace
<your_password_or_pat>and<your_llm_token>with real values before running. LOOK FOR: Both SNOWFLAKE_CREDENTIALS (type PASSWORD) and LLM_KEY (type GENERIC_STRING) should appear.-- Create a database and schema for your secrets (or use existing ones)CREATE DATABASE IF NOT EXISTS IDENTIFIER($secret_db);CREATE SCHEMA IF NOT EXISTS IDENTIFIER($secret_schema);-- Create the credentials secret (must be TYPE = PASSWORD)CREATE SECRET IF NOT EXISTS IDENTIFIER($cred_secret)TYPE = PASSWORDUSERNAME = $service_userPASSWORD = '<your_password_or_pat>';-- Create the LLM key secret for Cortex accessCREATE SECRET IF NOT EXISTS IDENTIFIER($llm_secret)TYPE = GENERIC_STRINGSECRET_STRING = '<your_llm_token>';SHOW SECRETS IN SCHEMA IDENTIFIER($secret_schema);-- Grant the Native App access to the secretsGRANT USAGE ON DATABASE IDENTIFIER($secret_db) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON SCHEMA IDENTIFIER($secret_schema) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($cred_secret) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($llm_secret) TO APPLICATION IDENTIFIER($native_app);-- LOOK FOR: USAGE on the database and schema, READ on both secrets, all granted to the native app.SHOW GRANTS ON DATABASE IDENTIFIER($secret_db);SHOW GRANTS ON SCHEMA IDENTIFIER($secret_schema);SHOW GRANTS ON SECRET IDENTIFIER($cred_secret);SHOW GRANTS ON SECRET IDENTIFIER($llm_secret);Step 4 — Configure network access
The Rel Agent needs outbound network access to communicate with Snowflake’s auth gateway. The 0.0.0.0 rule allows general egress. You can tighten this to your account’s specific Snowflake endpoint(s) to limit access.
Note: ALLOWED_NETWORK_RULES must be a literal name — session variables cannot be used here. If you changed
$network_ruleabove, update the value in the CREATE EXTERNAL ACCESS INTEGRATION statement below to match.LOOK FOR: The network rule with MODE = EGRESS, the EAI with ENABLED = true, and USAGE privilege on both granted to the native app.
CREATE OR REPLACE NETWORK RULE IDENTIFIER($network_rule)TYPE = HOST_PORTMODE = EGRESSVALUE_LIST = ('0.0.0.0')COMMENT = 'Allow outbound traffic for Rel Agent service to Snowflake endpoints';-- Note: ALLOWED_NETWORK_RULES must be a literal — update if you changed $network_rule.CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION IDENTIFIER($eai_name)ALLOWED_NETWORK_RULES = (modeler_setup.config.modeler_network_rule)ENABLED = TRUE;-- Grant the Native App accessGRANT USAGE ON NETWORK RULE IDENTIFIER($network_rule) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON INTEGRATION IDENTIFIER($eai_name) TO APPLICATION IDENTIFIER($native_app);SHOW NETWORK RULES IN SCHEMA IDENTIFIER($secret_schema);SHOW EXTERNAL ACCESS INTEGRATIONS;SHOW GRANTS ON NETWORK RULE IDENTIFIER($network_rule);SHOW GRANTS ON INTEGRATION IDENTIFIER($eai_name);If your service user is blocked by existing network policies, run the block below to create and assign one. Otherwise, skip to Step 5.
CREATE NETWORK POLICY modeler_service_policyALLOWED_IP_LIST = ('0.0.0.0/0');ALTER USER IDENTIFIER($service_user) SET NETWORK_POLICY = modeler_service_policy;Step 5 — Verify role access and launch the engine
Before launching, confirm that
$service_roleexists, is granted to your service user, has warehouse access, and has a RAI application role. This is the most common source of setup failures. LOOK FOR:$service_roleshould appear in each result set. If the role is missing from any check, run the corresponding GRANT shown in the comments.-- Does the role exist?SHOW ROLES;SELECT "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "name" = UPPER($service_role);-- Is it granted to the service user?SHOW GRANTS TO USER IDENTIFIER($service_user);SELECT "role" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "role" = UPPER($service_role);-- If not: GRANT ROLE IDENTIFIER($service_role) TO USER IDENTIFIER($service_user);-- Does the role have USAGE on the warehouse?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "name" = UPPER($warehouse);-- If not: GRANT USAGE ON WAREHOUSE IDENTIFIER($warehouse) TO ROLE IDENTIFIER($service_role);-- Does the role have a RAI application role (e.g. RAI_USER or RAI_DEVELOPER)?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "granted_on", "grantee_name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "granted_on" = 'APPLICATION_ROLE' and "grantee_name" = UPPER(($service_role));-- If not: GRANT APPLICATION ROLE RELATIONALAI.<rai_role> TO ROLE IDENTIFIER($service_role);Once the checks above pass, create the engine. LOOK FOR: STATUS = RUNNING. If GONE or FAILED, see the Troubleshooting section of the setup guide.
CALL RELATIONALAI.api.create_reasoner_async('modeler',$engine_name,$engine_size,PARSE_JSON('{"settings":{"modeler":{' ||'"snowflake_credentials_secret":"' || $cred_secret || '",' ||'"llm_key_secret":"' || $llm_secret || '",' ||'"snowflake_role":"' || $service_role || '",' ||'"warehouse_name":"' || $warehouse || '",' ||'"external_access_integrations":["' || $eai_name || '"]' ||'}}}'));-- LOOK FOR: STATUS = RUNNING. If GONE or FAILED, see "Getting service logs" in the Troubleshooting section.CALL RELATIONALAI.api.get_reasoner('modeler', $engine_name);Step 6 — Access the Rel Agent UI
Once the engine is running, retrieve its ingress endpoint URL and open it in your browser. The SPCS ingress authenticates you automatically via your Snowflake account credentials.
CALL RELATIONALAI.api.modeler_endpoints($engine_name); - Go to https://app.snowflake.com and select + Create Projects > Notebook > Import .ipynb File at the top of the left sidebar.
- Upload the
relationalai-rel-agent-setup.ipynbfile. - Choose a database and schema to save the notebook in.
- Any database and schema will do — you can delete the notebook after setup.
- If you don’t have any database available in the dropdown, you can create one by doing
create database <name>;from a SQL worksheet.
- Choose Run on warehouse and click Create.
- Run the cells one at a time.
Copy the block below and paste it into a Snowflake SQL worksheet. Update the configuration variables at the top, then run the blocks in order.
Before running this worksheet, update the variables in the configuration block below.
/*# Rel Agent Setup*/
/*## Step 1 — Set configuration variables*/
/*Replace the placeholder values below with your own, then run this block.*/
-- ============================================================-- Configuration — update these values for your environment-- ============================================================
-- EngineSET engine_name = 'my_rel_agent'; -- name you choose for this engineSET engine_size = 'S'; -- compute size (S, M, L, etc.)
-- Secrets location (FQNs are derived automatically)SET secret_db = 'modeler_setup'; -- database for secrets and network ruleSET secret_schema = $secret_db || '.config'; -- schema for secrets and network ruleSET cred_secret = $secret_schema || '.SNOWFLAKE_CREDENTIALS';SET llm_secret = $secret_schema || '.LLM_KEY';SET network_rule = $secret_schema || '.modeler_network_rule';
-- CredentialsSET service_user = '<your_service_user>'; -- Snowflake user for the Rel Agent
-- AccessSET eai_name = 'modeler_eai'; -- External Access Integration nameSET service_role = '<role_with_warehouse_access>';SET warehouse = '<warehouse_name>';SET native_app = 'RELATIONALAI'; -- name of the installed Native App
/*## Step 2 — Enable Cortex*/
/*Cortex must be enabled on your Snowflake account before the Rel Agent canuse it for LLM access. LOOK FOR: CORTEX_ENABLED_CROSS_REGION should be setto 'ANY_REGION'.*/
SHOW PARAMETERS LIKE 'CORTEX_ENABLED_CROSS_REGION' IN ACCOUNT;
-- Enable cross-region Cortex if not already setALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';
/*## Step 3 — Create secrets*/
/*The Rel Agent requires two secrets: one for Snowflake authentication andone for LLM access via Cortex. Replace `<your_password_or_pat>` and`<your_llm_token>` with real values before running. LOOK FOR: BothSNOWFLAKE_CREDENTIALS (type PASSWORD) and LLM_KEY (type GENERIC_STRING)should appear.*/
-- Create a database and schema for your secrets (or use existing ones)CREATE DATABASE IF NOT EXISTS IDENTIFIER($secret_db);CREATE SCHEMA IF NOT EXISTS IDENTIFIER($secret_schema);
-- Create the credentials secret (must be TYPE = PASSWORD)CREATE SECRET IF NOT EXISTS IDENTIFIER($cred_secret) TYPE = PASSWORD USERNAME = $service_user PASSWORD = '<your_password_or_pat>';
-- Create the LLM key secret for Cortex accessCREATE SECRET IF NOT EXISTS IDENTIFIER($llm_secret) TYPE = GENERIC_STRING SECRET_STRING = '<your_llm_token>';
SHOW SECRETS IN SCHEMA IDENTIFIER($secret_schema);
-- Grant the Native App access to the secretsGRANT USAGE ON DATABASE IDENTIFIER($secret_db) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON SCHEMA IDENTIFIER($secret_schema) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($cred_secret) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($llm_secret) TO APPLICATION IDENTIFIER($native_app);
-- LOOK FOR: USAGE on the database and schema, READ on both secrets, all granted to the native app.SHOW GRANTS ON DATABASE IDENTIFIER($secret_db);SHOW GRANTS ON SCHEMA IDENTIFIER($secret_schema);SHOW GRANTS ON SECRET IDENTIFIER($cred_secret);SHOW GRANTS ON SECRET IDENTIFIER($llm_secret);
/*## Step 4 — Configure network access*/
/*The Rel Agent needs outbound network access to communicate withSnowflake's auth gateway. The 0.0.0.0 rule allows general egress. You cantighten this to your account's specific Snowflake endpoint(s) to limitaccess.*/
/*Note: ALLOWED_NETWORK_RULES must be a literal name — session variablescannot be used here. If you changed `$network_rule` above, update thevalue in the CREATE EXTERNAL ACCESS INTEGRATION statement below to match.*/
/*LOOK FOR: The network rule with MODE = EGRESS, the EAI with ENABLED =true, and USAGE privilege on both granted to the native app.*/
CREATE OR REPLACE NETWORK RULE IDENTIFIER($network_rule) TYPE = HOST_PORT MODE = EGRESS VALUE_LIST = ('0.0.0.0') COMMENT = 'Allow outbound traffic for Rel Agent service to Snowflake endpoints';
-- Note: ALLOWED_NETWORK_RULES must be a literal — update if you changed $network_rule.CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION IDENTIFIER($eai_name) ALLOWED_NETWORK_RULES = (modeler_setup.config.modeler_network_rule) ENABLED = TRUE;
-- Grant the Native App accessGRANT USAGE ON NETWORK RULE IDENTIFIER($network_rule) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON INTEGRATION IDENTIFIER($eai_name) TO APPLICATION IDENTIFIER($native_app);
SHOW NETWORK RULES IN SCHEMA IDENTIFIER($secret_schema);SHOW EXTERNAL ACCESS INTEGRATIONS;SHOW GRANTS ON NETWORK RULE IDENTIFIER($network_rule);SHOW GRANTS ON INTEGRATION IDENTIFIER($eai_name);
/*If your service user is blocked by existing network policies, run theblock below to create and assign one. Otherwise, skip to Step 5.*/
CREATE NETWORK POLICY modeler_service_policy ALLOWED_IP_LIST = ('0.0.0.0/0');
ALTER USER IDENTIFIER($service_user) SET NETWORK_POLICY = modeler_service_policy;
/*## Step 5 — Verify role access and launch the engine*/
/*Before launching, confirm that `$service_role` exists, is granted to yourservice user, has warehouse access, and has a RAI application role. Thisis the most common source of setup failures. LOOK FOR: `$service_role`should appear in each result set. If the role is missing from any check,run the corresponding GRANT shown in the comments.*/
-- Does the role exist?SHOW ROLES;SELECT "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "name" = UPPER($service_role);
-- Is it granted to the service user?SHOW GRANTS TO USER IDENTIFIER($service_user);SELECT "role" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "role" = UPPER($service_role);-- If not: GRANT ROLE IDENTIFIER($service_role) TO USER IDENTIFIER($service_user);
-- Does the role have USAGE on the warehouse?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "name" = UPPER($warehouse);-- If not: GRANT USAGE ON WAREHOUSE IDENTIFIER($warehouse) TO ROLE IDENTIFIER($service_role);
-- Does the role have a RAI application role (e.g. RAI_USER or RAI_DEVELOPER)?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "granted_on", "grantee_name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "granted_on" = 'APPLICATION_ROLE' and "grantee_name" = UPPER(($service_role));-- If not: GRANT APPLICATION ROLE RELATIONALAI.<rai_role> TO ROLE IDENTIFIER($service_role);
/*Once the checks above pass, create the engine. LOOK FOR: STATUS = RUNNING.If GONE or FAILED, see the Troubleshooting section of the setup guide.*/
CALL RELATIONALAI.api.create_reasoner_async( 'modeler', $engine_name, $engine_size, PARSE_JSON( '{"settings":{"modeler":{' || '"snowflake_credentials_secret":"' || $cred_secret || '",' || '"llm_key_secret":"' || $llm_secret || '",' || '"snowflake_role":"' || $service_role || '",' || '"warehouse_name":"' || $warehouse || '",' || '"external_access_integrations":["' || $eai_name || '"]' || '}}}' ));
-- LOOK FOR: STATUS = RUNNING. If GONE or FAILED, see "Getting service logs" in the Troubleshooting section.CALL RELATIONALAI.api.get_reasoner('modeler', $engine_name);
/*## Step 6 — Access the Rel Agent UI*/
/*Once the engine is running, retrieve its ingress endpoint URL and open itin your browser. The SPCS ingress authenticates you automatically via yourSnowflake account credentials.*/
CALL RELATIONALAI.api.modeler_endpoints($engine_name);Copy the block below into a file and run it with the SnowSQL command-line client.
Start by updating the variables in the configuration block below before running.
/*# Rel Agent Setup*/
/*## Step 1 — Set configuration variables*/
/*Replace the placeholder values below with your own, then run this block.*/
-- ============================================================-- Configuration — update these values for your environment-- ============================================================
-- EngineSET engine_name = 'my_rel_agent'; -- name you choose for this engineSET engine_size = 'S'; -- compute size (S, M, L, etc.)
-- Secrets location (FQNs are derived automatically)SET secret_db = 'modeler_setup'; -- database for secrets and network ruleSET secret_schema = $secret_db || '.config'; -- schema for secrets and network ruleSET cred_secret = $secret_schema || '.SNOWFLAKE_CREDENTIALS';SET llm_secret = $secret_schema || '.LLM_KEY';SET network_rule = $secret_schema || '.modeler_network_rule';
-- CredentialsSET service_user = '<your_service_user>'; -- Snowflake user for the Rel Agent
-- AccessSET eai_name = 'modeler_eai'; -- External Access Integration nameSET service_role = '<role_with_warehouse_access>';SET warehouse = '<warehouse_name>';SET native_app = 'RELATIONALAI'; -- name of the installed Native App
/*## Step 2 — Enable Cortex*/
/*Cortex must be enabled on your Snowflake account before the Rel Agent canuse it for LLM access. LOOK FOR: CORTEX_ENABLED_CROSS_REGION should be setto 'ANY_REGION'.*/
SHOW PARAMETERS LIKE 'CORTEX_ENABLED_CROSS_REGION' IN ACCOUNT;
-- Enable cross-region Cortex if not already setALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';
/*## Step 3 — Create secrets*/
/*The Rel Agent requires two secrets: one for Snowflake authentication andone for LLM access via Cortex. Replace `<your_password_or_pat>` and`<your_llm_token>` with real values before running. LOOK FOR: BothSNOWFLAKE_CREDENTIALS (type PASSWORD) and LLM_KEY (type GENERIC_STRING)should appear.*/
-- Create a database and schema for your secrets (or use existing ones)CREATE DATABASE IF NOT EXISTS IDENTIFIER($secret_db);CREATE SCHEMA IF NOT EXISTS IDENTIFIER($secret_schema);
-- Create the credentials secret (must be TYPE = PASSWORD)CREATE SECRET IF NOT EXISTS IDENTIFIER($cred_secret) TYPE = PASSWORD USERNAME = $service_user PASSWORD = '<your_password_or_pat>';
-- Create the LLM key secret for Cortex accessCREATE SECRET IF NOT EXISTS IDENTIFIER($llm_secret) TYPE = GENERIC_STRING SECRET_STRING = '<your_llm_token>';
SHOW SECRETS IN SCHEMA IDENTIFIER($secret_schema);
-- Grant the Native App access to the secretsGRANT USAGE ON DATABASE IDENTIFIER($secret_db) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON SCHEMA IDENTIFIER($secret_schema) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($cred_secret) TO APPLICATION IDENTIFIER($native_app);GRANT READ ON SECRET IDENTIFIER($llm_secret) TO APPLICATION IDENTIFIER($native_app);
-- LOOK FOR: USAGE on the database and schema, READ on both secrets, all granted to the native app.SHOW GRANTS ON DATABASE IDENTIFIER($secret_db);SHOW GRANTS ON SCHEMA IDENTIFIER($secret_schema);SHOW GRANTS ON SECRET IDENTIFIER($cred_secret);SHOW GRANTS ON SECRET IDENTIFIER($llm_secret);
/*## Step 4 — Configure network access*/
/*The Rel Agent needs outbound network access to communicate withSnowflake's auth gateway. The 0.0.0.0 rule allows general egress. You cantighten this to your account's specific Snowflake endpoint(s) to limitaccess.*/
/*Note: ALLOWED_NETWORK_RULES must be a literal name — session variablescannot be used here. If you changed `$network_rule` above, update thevalue in the CREATE EXTERNAL ACCESS INTEGRATION statement below to match.*/
/*LOOK FOR: The network rule with MODE = EGRESS, the EAI with ENABLED =true, and USAGE privilege on both granted to the native app.*/
CREATE OR REPLACE NETWORK RULE IDENTIFIER($network_rule) TYPE = HOST_PORT MODE = EGRESS VALUE_LIST = ('0.0.0.0') COMMENT = 'Allow outbound traffic for Rel Agent service to Snowflake endpoints';
-- Note: ALLOWED_NETWORK_RULES must be a literal — update if you changed $network_rule.CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION IDENTIFIER($eai_name) ALLOWED_NETWORK_RULES = (modeler_setup.config.modeler_network_rule) ENABLED = TRUE;
-- Grant the Native App accessGRANT USAGE ON NETWORK RULE IDENTIFIER($network_rule) TO APPLICATION IDENTIFIER($native_app);GRANT USAGE ON INTEGRATION IDENTIFIER($eai_name) TO APPLICATION IDENTIFIER($native_app);
SHOW NETWORK RULES IN SCHEMA IDENTIFIER($secret_schema);SHOW EXTERNAL ACCESS INTEGRATIONS;SHOW GRANTS ON NETWORK RULE IDENTIFIER($network_rule);SHOW GRANTS ON INTEGRATION IDENTIFIER($eai_name);
/*If your service user is blocked by existing network policies, run theblock below to create and assign one. Otherwise, skip to Step 5.*/
CREATE NETWORK POLICY modeler_service_policy ALLOWED_IP_LIST = ('0.0.0.0/0');
ALTER USER IDENTIFIER($service_user) SET NETWORK_POLICY = modeler_service_policy;
/*## Step 5 — Verify role access and launch the engine*/
/*Before launching, confirm that `$service_role` exists, is granted to yourservice user, has warehouse access, and has a RAI application role. Thisis the most common source of setup failures. LOOK FOR: `$service_role`should appear in each result set. If the role is missing from any check,run the corresponding GRANT shown in the comments.*/
-- Does the role exist?SHOW ROLES;SELECT "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "name" = UPPER($service_role);
-- Is it granted to the service user?SHOW GRANTS TO USER IDENTIFIER($service_user);SELECT "role" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "role" = UPPER($service_role);-- If not: GRANT ROLE IDENTIFIER($service_role) TO USER IDENTIFIER($service_user);
-- Does the role have USAGE on the warehouse?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "name" = UPPER($warehouse);-- If not: GRANT USAGE ON WAREHOUSE IDENTIFIER($warehouse) TO ROLE IDENTIFIER($service_role);
-- Does the role have a RAI application role (e.g. RAI_USER or RAI_DEVELOPER)?SHOW GRANTS TO ROLE IDENTIFIER($service_role);SELECT "privilege", "granted_on", "grantee_name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "privilege" = 'USAGE' AND "granted_on" = 'APPLICATION_ROLE' and "grantee_name" = UPPER(($service_role));-- If not: GRANT APPLICATION ROLE RELATIONALAI.<rai_role> TO ROLE IDENTIFIER($service_role);
/*Once the checks above pass, create the engine. LOOK FOR: STATUS = RUNNING.If GONE or FAILED, see the Troubleshooting section of the setup guide.*/
CALL RELATIONALAI.api.create_reasoner_async( 'modeler', $engine_name, $engine_size, PARSE_JSON( '{"settings":{"modeler":{' || '"snowflake_credentials_secret":"' || $cred_secret || '",' || '"llm_key_secret":"' || $llm_secret || '",' || '"snowflake_role":"' || $service_role || '",' || '"warehouse_name":"' || $warehouse || '",' || '"external_access_integrations":["' || $eai_name || '"]' || '}}}' ));
-- LOOK FOR: STATUS = RUNNING. If GONE or FAILED, see "Getting service logs" in the Troubleshooting section.CALL RELATIONALAI.api.get_reasoner('modeler', $engine_name);
/*## Step 6 — Access the Rel Agent UI*/
/*Once the engine is running, retrieve its ingress endpoint URL and open itin your browser. The SPCS ingress authenticates you automatically via yourSnowflake account credentials.*/
CALL RELATIONALAI.api.modeler_endpoints($engine_name);Engine Defaults
Section titled “Engine Defaults”The engine starts with the following configuration:
| Setting | Default |
|---|---|
| LLM Provider | Cortex (Snowflake internal) |
| Model | claude-sonnet-4-5 (Claude 4.5 Sonnet) |
| Authentication | OAuth via Snowflake credentials |
| Max tokens | 64,000 |
| Temperature | 0.1 |
| Request timeout | 45 seconds |
| Max concurrent requests | 5 |
| Max retries | 3 |
Troubleshooting
Section titled “Troubleshooting””Modeler not enabled for your account”
The Rel Agent preview must be explicitly enabled for your Snowflake account. Contact your RelationalAI representative to request access. After it has been enabled, it can take 10–20 minutes to propagate to your account.
”Credentials not provided”
Your settings JSON is missing one or more required fields. Ensure all are present:
snowflake_credentials_secretllm_key_secretsnowflake_rolewarehouse_name
”Secret not found”
- Verify the secret exists:
SHOW SECRETS IN SCHEMA IDENTIFIER($secret_schema); - Ensure the name is fully qualified:
database.schema.secret_name
”Invalid secret type”
The credentials secret must be TYPE = PASSWORD. Other types are not supported.
”Invalid secret name”
Secret names must:
- Start with a letter.
- Contain only letters, numbers, underscores, and periods.
- Be 255 characters or fewer.
- Be fully qualified (e.g.,
database.schema.secret_name).
”Role does not exist” or “Role not granted”
This is one of the most common setup issues. The snowflake_role specified in your engine settings must:
- Actually exist in your Snowflake account.
- Be granted to the service user specified in your credentials secret.
- Have the necessary permissions (warehouse usage, database/schema access, RAI application role).
To diagnose:
-- Does the role exist?SHOW ROLES;SELECT "name" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "name" = UPPER($service_role);
-- Is it granted to your service user?SHOW GRANTS TO USER IDENTIFIER($service_user);
-- What permissions does it have?SHOW GRANTS TO ROLE IDENTIFIER($service_role);
-- Grant the role to the service user if missingGRANT ROLE IDENTIFIER($service_role) TO USER IDENTIFIER($service_user);
-- Grant a RAI application role if missingGRANT APPLICATION ROLE RELATIONALAI.<rai_role> TO ROLE IDENTIFIER($service_role);“Insufficient privileges” or “Not authorized”
- Confirm the app has
READon the secret andUSAGEon the database and schema. - Check grants:
SHOW GRANTS ON SECRET IDENTIFIER($cred_secret); - Verify the
snowflake_roleyou specified has the right permissions. - Ensure the role has a RAI application role (e.g.,
RAI_USER,RAI_DEVELOPER) granted to it.
”External access not configured” or “Network error”
- Confirm the EAI exists and is
ENABLED = TRUE. - Confirm the integration is granted to the application.
- Verify the integration name in your
create_reasoner_asynccall matches exactly.
”Warehouse not found” or “Warehouse access denied”
- Verify the warehouse exists:
SHOW WAREHOUSES;and check that$warehouseappears. - Ensure the
snowflake_rolehasUSAGEon the warehouse:GRANT USAGE ON WAREHOUSE IDENTIFIER($warehouse) TO ROLE IDENTIFIER($service_role);
Models silently fail to build
If models appear to accept input but never finish building (no error, just stuck), the most likely cause is a missing, invalid, or unauthorized LLM token. Verify that:
llm_key_secretpoints to a valid secret.- The token is not expired or revoked.
- The service user has been granted access to use Cortex.
Getting service logs
SPCS service logs are useful for diagnosing startup failures, unexpected behavior, or errors on a running engine.
-
List all services:
SHOW SERVICES IN ACCOUNT; -
Get the fully qualified service name, including its hash suffix:
SELECT "database_name" || '.' || "schema_name" || '.' || "name" AS service_fqnFROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))WHERE "name" ILIKE '%' || $engine_name || '%'; -
Fetch the logs using the fully qualified name:
SELECT * FROM TABLE(<service_fqn>!SPCS_GET_LOGS());
The result is a table with columns TIMESTAMP, INSTANCE_ID, CONTAINER_NAME, LOG, and RECORD_ATTRIBUTES. A typical snippet looks like:
| TIMESTAMP | INSTANCE_ID | CONTAINER_NAME | LOG | RECORD_ATTRIBUTES |
|---|---|---|---|---|
| 2026-03-25 14:15:55.903 | 0 | modelerservice | INFO: 10.16.186.15:48214 - "GET /ping HTTP/1.1" 200 OK | {"log.iostream": "stdout", "snow.application.shared": true} |
| 2026-03-25 14:15:55.902 | 0 | modelerservice | 1ms ▸ HTTP::GET /ping | {"log.iostream": "stdout", "snow.application.shared": true} |
| 2026-03-25 14:15:55.901 | 0 | modelerservice | ▸ HTTP::GET /ping 09d4352f-e7d5-45f4-bac5-6b68f6e766aa | {"log.iostream": "stdout", "snow.application.shared": true} |
The LOG column contains the message. Look for lines containing ERROR or WARN — these usually indicate the root cause. Logs are in reverse chronological order, so start from the top for the most recent entries.