# Set up RelationalAI in Snowflake

RelationalAI (RAI) runs inside your Snowflake account as a [native app](https://docs.snowflake.com/en/developer-guide/native-apps/native-apps-about), so your data never leaves your account.
This guide takes a Snowflake administrator through the first-time setup: request access to the RAI native app, install and activate the app, grant user access, and hand off connection details to developers.

**Estimated setup time:** 20–30 minutes

**Prerequisites**

- A Snowflake account and the `ORGADMIN` or `ACCOUNTADMIN` role.
- A query warehouse for developers. An `X-SMALL` size is fine. [Create one](https://docs.snowflake.com/en/user-guide/warehouses-tasks#label-warehouse-create) if you don't already have it.

## Review installation impact

Before you request access, review the privileges the app requires, the resources it creates, and its impact on your Snowflake costs.

### What access does the app receive?

**Required privileges**

Snowflake grants these privileges when you install the app. You cannot revoke them while the app is installed.

- Run automated data workflows. Privileges: [`EXECUTE TASK`](https://docs.snowflake.com/en/sql-reference/sql/execute-task) · `EXECUTE MANAGED TASK`
- Create and manage the app's dedicated warehouse. Privileges: [`CREATE WAREHOUSE`](https://docs.snowflake.com/en/sql-reference/sql/create-warehouse)
- Create compute pools for RAI workloads. Privileges: [`CREATE COMPUTE POOL`](https://docs.snowflake.com/en/sql-reference/sql/create-compute-pool.html)
- Expose a secure endpoint for [authenticated client connections](#grant-user-access). Privileges: [`BIND SERVICE ENDPOINT`](https://docs.snowflake.com/en/developer-guide/native-apps/container-services)

**Optional privilege**

This privilege is not included at installation. Grant it only if you use a feature that integrates with Snowflake Cortex.

- Enable [Snowflake Cortex](https://www.snowflake.com/en/product/features/cortex/) integrations. Privileges: [`IMPORTED PRIVILEGES ON SNOWFLAKE DB`](https://docs.snowflake.com/en/sql-reference/sql/grant-privilege#imported-privileges)

**Security boundaries**

- **Data:** Installation does not grant blanket access to existing tables or views. You configure data sources separately, and Snowflake checks object-level privileges when they are accessed through RAI.
- **Users:** You choose who can use the app by [granting RAI application roles to Snowflake account roles](#grant-user-access).
- **Connections:** The service endpoint accepts authenticated client connections. Connected users still need the required RAI roles and Snowflake grants. External clients use the public internet unless [Private Link](#grant-user-access) is configured.

**Check row access and masking policies before sharing sensitive data.** RAI evaluates these policies against a shared `RELATIONALAI` role, not each user's configured role. Review [how Snowflake access control is handled](/manage/data/index.md#how-snowflake-access-control-is-handled).

### What resources and costs should I expect?

**Cost overview**

RAI costs depend on how much storage and compute you use. Snowflake charges for both. RelationalAI adds a surcharge only to compute used by reasoners.

The sections below show what the app creates and when each resource can incur charges. Review the cost model with whoever approves Snowflake spend before you install.

For more, see [Understand and optimize costs](/manage/app/costs/index.md).

**Application footprint**

Installation creates the application database. You then activate the app to start its services and managed compute. Activating the app adds the service, warehouse, and compute pools that run it.

- **Application database**
  Snowflake creates this [application object](https://docs.snowflake.com/en/developer-guide/native-apps/consumer-guide-model) during installation, and it remains when you deactivate the app. Snowflake charges a small amount to store it, and RelationalAI adds no surcharge. Resources: `RELATIONALAI`
- **Snowflake virtual warehouse**
  Activating the app creates this [virtual warehouse](https://docs.snowflake.com/en/user-guide/warehouses) for Snowflake operations. Snowflake charges for compute while the warehouse runs. RelationalAI doesn't add a surcharge. Resources: `RELATIONAL_AI_ERP_WAREHOUSE`
  `X-SMALL`
- **Compute pools for app operations**
  Activating the app creates these [compute pools](https://docs.snowflake.com/en/developer-guide/snowpark-container-services/working-with-compute-pool) to support its core operations. The pool objects don't incur charges. Snowflake charges for compute running in them. RelationalAI doesn't add a surcharge. Resources: `RELATIONAL_AI_ERP_COMPUTE_POOL`
  `CPU_X64_XS` · AWS and Azure`RELATIONAL_AI_COMPILE_CACHE_SPCS`
  `HIGHMEM_X64_M` · AWS and Azure
- **App service in Snowpark Container Services**
  Activating the app creates a managed [service in Snowpark Container Services](https://docs.snowflake.com/en/developer-guide/snowpark-container-services/working-with-services) to run RelationalAI inside your Snowflake account. Its usage is included in the app's compute pool charges. RelationalAI doesn't add a surcharge.

**Compute pools for reasoners**

Reasoners run logic, prediction, and optimization workloads. Activating the app creates the [compute pools](https://docs.snowflake.com/en/developer-guide/snowpark-container-services/working-with-compute-pool) they can use. Available sizes differ between AWS and Azure.

- **Standard compute for reasoners**
  Runs logic, prediction, and optimization workloads. Snowflake charges for compute while reasoners run and for any reserved nodes. RelationalAI adds a surcharge only while reasoners run. Resources: `RELATIONAL_AI_HIGHMEM_X64_S`
  AWS and Azure`RELATIONAL_AI_HIGHMEM_X64_M`
  AWS and Azure
- **High-memory compute by cloud**
  Provides larger high-memory options where each cloud supports them. Larger sizes cost more per hour. Snowflake charges while reasoners run and for any reserved nodes. RelationalAI adds a surcharge only while reasoners run. Resources: `RELATIONAL_AI_HIGHMEM_X64_L`
  Logic and prediction workloads · AWS only`RELATIONAL_AI_HIGHMEM_X64_SL`
  Logic workloads · Azure only
- **Compute with GPUs for prediction workloads**
  Runs prediction workloads on GPU instances. Snowflake charges for compute while reasoners run and for any reserved nodes. RelationalAI adds a surcharge only while reasoners run. Resources: `RELATIONAL_AI_GPU_NV_S`
  AWS only`RELATIONAL_AI_GPU_NV_SM`
  Azure only
- **CPU pools for future use**
  Current workloads don't use these pools. The pool objects don't incur charges. Snowflake charges only if you reserve nodes. RelationalAI doesn't add a surcharge while the pools are unused. Resources: `RELATIONAL_AI_CPU_X64_S`
  AWS and Azure`RELATIONAL_AI_CPU_X64_M`
  AWS and Azure

**When charges apply**

- **Installation:** Creates the application database. Snowflake charges a small amount to store it.
- **Activation:** Adds the other resources listed here and starts the app's managed compute. Snowflake can begin charging for compute.
- **Idle compute pools:** A pool with no reserved nodes and no running reasoners doesn't incur compute charges.
- **Deactivation:** [Deactivating the app](/manage/app/shut-down/index.md) suspends the app service, warehouse, and compute pools, reducing most compute charges. The application database continues to incur storage charges, and some background tasks may continue to use a small amount of compute.

For the complete resource inventory and commands to inspect each resource, see [Resources the app creates](/manage/app/resources/index.md).

## Request app access

RAI is available on the Snowflake Marketplace, but you must request access before you can install and activate it:

1. Sign in to Snowsight as an `ORGADMIN` or `ACCOUNTADMIN`.

2. Open the [RelationalAI Marketplace listing](https://app.snowflake.com/marketplace/listing/GZTYZOOIX8H/relationalai-relationalai).
   Click the *Get* button then fill out and submit the access request form.

3. Wait for RelationalAI to enable access. A representative notifies you when the app is available to install.

## Install and activate the app

Once access to the app is enabled, follow these steps to install the app in your Snowflake account:

1. In Snowsight, go to *Catalog > Apps*. RelationalAI appears under *Recently shared with you*.

2. Click *Buy*, review the pricing dialog, and confirm. The app installs into your account as the `RELATIONALAI` application database.

3. Wait for the *INSTALLED* column to show that installation finished.

4. Run the following SQL as `ACCOUNTADMIN` in a new worksheet:

   ```sql
   -- Check you're an admin who can install apps and grant
   -- account privileges, and that the RELATIONALAI app exists.
   USE ROLE ACCOUNTADMIN;
   SHOW APPLICATIONS LIKE 'RELATIONALAI';

   -- Start the app. The first activation sets up compute and
   -- can take a few minutes.
   CALL RELATIONALAI.APP.ACTIVATE();

   -- Check the services. Wait a few minutes and rerun this line
   -- until every service shows READY.
   CALL RELATIONALAI.APP.SERVICE_STATUS();

   -- Turn on change data capture (CDC), then confirm it's on.
   CALL RELATIONALAI.APP.RESUME_CDC();
   CALL RELATIONALAI.APP.CDC_STATUS();
   ```

   :::tip
   If activation fails with an error about the account parameter `PREVENT_UNLOAD_TO_INTERNAL_STAGES`, that setting is blocking the app from writing to its internal stage.
   See [Fix app activation errors caused by settings in your Snowflake account](/manage/app/start-the-app/index.md#fix-app-activation-errors-caused-by-snowflake-account-settings) for the fix, then activate again.
   :::

## Grant user access

You'll grant users access in two steps:

1. Use the form below to generate SQL for the users you specify, then run it in Snowflake.
   The SQL grants them access to the RAI Native App and its service endpoint.
2. Create an invite link for each user you granted access to.
   Each link opens the [Start building with PyRel](/get-started/start-building-with-pyrel/index.md) guide with that user's connection values pre-filled.
   Users can copy the values into their project configuration.
   Invite links contain no secrets, so you can share them safely.
   Deliver any required secrets separately and securely.

:::tip
You can return to this section to prepare access for more users.
:::

Open this page in a browser to personalize the setup SQL and invite links automatically. To do this yourself, follow these steps for the Snowflake users you're granting access to:

### Step 1: Generate and run user access SQL

1. Gather the values under "Script inputs" below for the warehouse and for each user.
2. Choose exactly one authentication method under "Choose an authentication method" below.
3. Copy the base script, replace its placeholders, then paste in the SQL for your chosen method (replacing its own placeholders too) before the final section.
4. Run the combined script as `ACCOUNTADMIN` in a new Snowsight worksheet or SnowSQL, then continue to Step 2.

#### Script inputs

- `<warehouse_name>`: the existing query warehouse to grant both roles access to. No default; an `X-SMALL` warehouse is fine.
- `<user_name>`: the Snowflake username of the user you're granting access to. No default; repeat the developer/admin/user blocks for each additional user.

#### Choose an authentication method

- **OAuth browser sign-in**: recommended for most developers. PyRel signs in interactively through a temporary local callback server.
- **Programmatic access token**: for headless scripts and automation without interactive sign-in.
- **JWT key pair**: for automation managed with per-user key pairs the developer generates and sends you only the public key for.

#### Base script (all authentication methods)

```sql
-- Create the standard Snowflake roles. Each one receives the
-- matching RelationalAI application role. Existing roles are left unchanged.
CREATE ROLE IF NOT EXISTS RAI_ADMIN;
GRANT APPLICATION ROLE RELATIONALAI.ALL_ADMIN TO ROLE RAI_ADMIN;

CREATE ROLE IF NOT EXISTS RAI_DEVELOPER;
GRANT APPLICATION ROLE RELATIONALAI.RAI_USER TO ROLE RAI_DEVELOPER;

-- Grant each user the selected RAI_DEVELOPER or RAI_ADMIN role.
GRANT ROLE RAI_DEVELOPER TO USER <user_name>;
GRANT ROLE RAI_ADMIN TO USER <user_name>;

-- Grant both standard roles access to an existing warehouse.
-- Use a warehouse your account already has. This script does not create one.
GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE RAI_DEVELOPER;
GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE RAI_ADMIN;

-- Check that the roles and users got the grants above.
SHOW GRANTS TO ROLE RAI_DEVELOPER;
SHOW GRANTS TO ROLE RAI_ADMIN;
SHOW GRANTS TO USER <user_name>;
```

#### Optional: Set up model deployment (Public Preview)

Add the following SQL only for Developer-role users who opt into model deployment. It creates dedicated output and metadata schemas and grants broad object-creation privileges in both, including tables, views, tasks, procedures, and functions. Public Preview is for evaluation and testing, not production applications. Preview features do not include a service-level agreement or a commitment to technical support.

Use an existing database. Replace every placeholder below and insert this SQL before SHOW GRANTS in the base script so the final checks include the optional grants.

- `<deployment_schema>`: the database.schema for this developer's PyRel outputs. Suggested default: `RAI_MODELS.<UPPERCASE_USERNAME>_DEV`. Change it only to use a custom database or schema, and give each developer a distinct one.
- `<meta_schema>`: stores information PyRel uses to manage and update the deployed model. By default, PyRel names the metadata schema by appending `_META` to `<deployment_schema>`. Replace this placeholder in the optional SQL.
- `<deployment_database>`: set to the database portion of `<deployment_schema>`. Replace this placeholder in the optional SQL.
- `<meta_database>`: set to the database portion of `<meta_schema>`. Replace this placeholder in the optional SQL.

```sql
-- Create one development schema and one metadata schema for each developer.
-- The metadata schema stores PyRel deployment bookkeeping.
-- Optional model deployment (Public Preview), for evaluation and testing.
CREATE SCHEMA IF NOT EXISTS <deployment_schema>;
CREATE SCHEMA IF NOT EXISTS <meta_schema>;

-- Give each developer the privileges PyRel needs to deploy and refresh models.
-- The grants apply only to that developer's development and metadata schemas.
-- Optional model deployment access for opted-in Developer users.
GRANT USAGE ON DATABASE <deployment_database> TO USER <user_name>;
GRANT USAGE ON SCHEMA <deployment_schema> TO USER <user_name>;
GRANT CREATE TABLE, CREATE DYNAMIC TABLE, CREATE HYBRID TABLE,
      CREATE VIEW, CREATE TASK, CREATE PROCEDURE, CREATE FUNCTION,
      CREATE STAGE, CREATE SEQUENCE, CREATE TAG
  ON SCHEMA <deployment_schema> TO USER <user_name>;

GRANT USAGE ON DATABASE <meta_database> TO USER <user_name>;
GRANT USAGE ON SCHEMA <meta_schema> TO USER <user_name>;
GRANT CREATE TABLE, CREATE DYNAMIC TABLE, CREATE HYBRID TABLE,
      CREATE VIEW, CREATE TASK, CREATE PROCEDURE, CREATE FUNCTION,
      CREATE STAGE, CREATE SEQUENCE, CREATE TAG
  ON SCHEMA <meta_schema> TO USER <user_name>;
```

#### Authentication method SQL

Insert exactly one of these before the final SHOW GRANTS checks in the base script, then run the combined script:

**OAuth browser sign-in**

```sql
-- Direct Access with OAuth: interactive browser sign-in.
-- The redirect URI must be plain-HTTP localhost, because the RAI
-- Python client finishes sign-in on a local callback with no TLS.
-- Keep this value only for that localhost callback.
CREATE SECURITY INTEGRATION RAI_DIRECT_ACCESS_OAUTH
  TYPE = OAUTH
  ENABLED = TRUE
  OAUTH_CLIENT = CUSTOM
  OAUTH_CLIENT_TYPE = 'PUBLIC'
  OAUTH_REDIRECT_URI = '<oauth_redirect_uri>'
  OAUTH_ALLOW_NON_TLS_REDIRECT_URI = TRUE
  OAUTH_ENFORCE_PKCE = TRUE
  OAUTH_ISSUE_REFRESH_TOKENS = TRUE
  OAUTH_REFRESH_TOKEN_VALIDITY = 86400
  ALLOWED_ROLES_LIST = ('RAI_ADMIN', 'RAI_DEVELOPER');
```

Additional input for this method:

- `<oauth_redirect_uri>`: the local callback URL PyRel's browser sign-in uses. Defaults to `http://localhost:54321/snowflake/oauth-redirect`; change only the port if that one is unavailable, and keep it plain-HTTP localhost.

**Programmatic access token**

```sql
-- Direct Access with a programmatic access token (PAT), for
-- headless use. This creates one token per user, and each
-- secret prints once below. Copy each one now and store it
-- securely; it can't be retrieved later (rotate to reissue).
-- A PAT needs a network policy on the user. Check existing
-- account and user policies first; a user policy wins over the
-- account one.
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT;

-- Bootstrap only. ('0.0.0.0/0') allows every address and isn't
-- safe for production. Replace it with your approved IP ranges
-- before you go live.
CREATE NETWORK POLICY IF NOT EXISTS RAI_DIRECT_ACCESS_POLICY
  ALLOWED_IP_LIST = ('0.0.0.0/0');

-- Run this statement, then immediately copy the displayed token
-- to your secret manager. Snowflake shows this secret only once.
ALTER USER <user_name>
  ADD PROGRAMMATIC ACCESS TOKEN RAI_DIRECT_ACCESS_TOKEN
  ROLE_RESTRICTION = '<direct_access_role>'
  DAYS_TO_EXPIRY = 15;
ALTER USER <user_name> SET NETWORK_POLICY = RAI_DIRECT_ACCESS_POLICY;

-- Check each token's role, expiry, and status (not the secret).
SHOW USER PROGRAMMATIC ACCESS TOKENS FOR USER <user_name>;
```

Additional input for this method:

- `<direct_access_role>`: set to `RAI_DEVELOPER` or `RAI_ADMIN` to match the role you assigned this user above.

**JWT key pair**

```sql
-- Direct Access with a key pair (JWT). The developer makes an
-- encrypted key pair locally and sends you only the public key.
-- Register it here. Leave out the -----BEGIN/-----END lines.
ALTER USER <user_name> SET RSA_PUBLIC_KEY = '<public_key>';

-- Check the registered public key fingerprint.
DESC USER <user_name>;
```

Additional input for this method:

- `<public_key>`: the public key the developer generated and sent you, with the `-----BEGIN/END PUBLIC KEY-----` lines removed. No default.

### Step 2: Complete developer handoffs

#### Look up the account identifier

Developers need this to connect to the Snowflake account where you installed RelationalAI.

```sql
SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME() AS account_identifier;
```

#### Look up the PrivateLink zone (PrivateLink accounts only)

Complete this only when developers must connect through Snowflake PrivateLink. Drop the leading `*.` from the returned zone before using it.

```sql
-- Private Link accounts only. This returns the ingress zone
-- developers set as spcs_privatelink_zone. Drop the leading "*.".
SELECT value AS app_service_privatelink_url
FROM TABLE(FLATTEN(INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())))
WHERE key = 'app-service-privatelink-url';
```

#### Look up the OAuth client ID (OAuth only)

Needed only if you chose OAuth browser sign-in in Step 1.

```sql
DESC SECURITY INTEGRATION RAI_DIRECT_ACCESS_OAUTH;
```

#### Build each Developer-role user's invite link

For each user you assigned the Developer role, build this URL by replacing the bracketed values with the ones you used above, then send it to that user:

```text
https://docs.relational.ai/get-started/start-building-with-pyrel?config_version=1&account=<account_identifier>&warehouse=<warehouse_name>&username=<user_name>&auth=<auth_method>
```

- Only if you set up model deployment for this user, append `&deployment_schema=<deployment_schema>&meta_schema=<meta_schema>`. Otherwise, omit these parameters.
- `<auth_method>`: set to `oauth`, `pat`, or `jwt` to match the method you chose and ran in Step 1.
- If you chose OAuth, also append `&client_id=<oauth_client_id>&redirect_uri=<oauth_redirect_uri>`.
- If the account uses PrivateLink, also append `&private_link=true&private_link_zone=<private_link_zone>`.

## Shut down the app (Optional)

If you set up the app only to evaluate it and no longer need it running, stop it to reduce ongoing Snowflake compute costs.
Run this SQL as `ACCOUNTADMIN`:

```sql
CALL RELATIONALAI.APP.DEACTIVATE();
```

`APP.DEACTIVATE()` suspends the app service, warehouse, compute pools, and CDC.
It also deletes reasoners and cancels in-progress jobs.

:::caution
The app doesn't reactivate automatically. An administrator must [start the app again](/manage/app/start-the-app/index.md) before developers can use PyRel.
:::

:::note
Deactivation reduces most compute costs, but it doesn't uninstall the app.
The application database continues to incur storage charges, and diagnostic and billing tasks can still use a small amount of Snowflake compute.
See [Shut down the app](/manage/app/shut-down/index.md) for more aggressive cost-saving options.
:::

## Where to go next

After setup, use these guides to operate the RAI Native App and its resources:

- [Overview](/manage/index.md): Learn how the RAI Native App works and how to administer it.
- [Native App](/manage/app/index.md): Check status, configure, and troubleshoot the RAI Native App.
- [Data sources](/manage/data/index.md): Manage RelationalAI's access to your Snowflake data.
- [Reasoners](/manage/reasoners/index.md): Monitor and manage the reasoning engines that evaluate PyRel queries.
