> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradime.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Snowflake DinoAI Agent Key-Pair Setup

> Set up Snowflake key-pair authentication for the DinoAI Background Agent by generating RSA keys, creating a service user, granting access, and configuring the connection in Paradime.

## Snowflake DinoAI Agent Key-Pair Setup

<Info>
  We recommend creating a dedicated Snowflake service user for the DinoAI agent environment, with the minimum permissions required to read and write to your database.
</Info>

<Info>
  **IP Restrictions** If your Snowflake account uses network policies, make sure to allowlist the Paradime IPs for your data region.\
  \
  👉 See: [Paradime IP addresses](https://docs.paradime.io/app-help/developers/ip-restrictions)
</Info>

***

#### Step 1. Generate the Key Pair

Run the following commands in your terminal to generate an RSA private key and extract the public key.

**Option A — Encrypted private key (recommended)**

```bash theme={"system"}
# Generate a 2048-bit RSA private key encrypted with AES-256
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -out dinoai_rsa_key.p8

# Extract the public key
openssl rsa -in dinoai_rsa_key.p8 -pubout -out dinoai_rsa_key.pub
```

You'll be prompted to set a passphrase. Keep it — you'll need it when configuring the connection in Paradime.

**Option B — Unencrypted private key**

```bash theme={"system"}
# Generate an unencrypted 2048-bit RSA private key
openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -inform PEM -out dinoai_rsa_key.p8

# Extract the public key
openssl rsa -in dinoai_rsa_key.p8 -pubout -out dinoai_rsa_key.pub
```

**Get the public key value**

```bash theme={"system"}
cat dinoai_rsa_key.pub
```

<Info>
  Copy only the content **between** the header and footer lines — not the lines themselves.\
  i.e. everything between `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----`
</Info>

***

#### Step 2. Create the Snowflake Service User

Run the SQL below in a Snowflake worksheet to create a dedicated service user, role, and warehouse.

**Create user, role, and warehouse**

```sql theme={"system"}
use role securityadmin;

-- Create warehouse (skip if one already exists)
create warehouse if not exists transforming
    warehouse_size = xsmall
    auto_suspend = 60
    auto_resume = true
    initially_suspended = true;

-- Create the transformer role and grant warehouse access
create role if not exists transformer;
grant all on warehouse transforming to role transformer;

-- Create the DinoAI service user
create user paradime_dinoai_user
    password = '<generate_a_strong_password>'
    default_warehouse = transforming
    default_role = transformer;

-- Assign the role to the user
grant role transformer to user paradime_dinoai_user;
```

**Grant database permissions**

The DinoAI agent needs three levels of access across your Snowflake databases:

| Database                                   | Access level     | Why                                                                         |
| ------------------------------------------ | ---------------- | --------------------------------------------------------------------------- |
| **Dev database** (e.g. `dev`)              | **Read + Write** | DinoAI creates and modifies tables/views during background agent sessions   |
| **Production database** (e.g. `analytics`) | **Read only**    | DinoAI reads prod models to understand your data and generate accurate code |
| **Source database** (e.g. `raw`)           | **Read only**    | DinoAI inspects raw source tables to understand upstream data structures    |

Replace the database names below with your actual Snowflake databases.

```sql theme={"system"}
use role sysadmin;

-- -------------------------
-- DEV DATABASE — read + write
-- DinoAI builds and modifies objects here during agent sessions
-- -------------------------
grant all on database <your_dev_database> to role transformer;
grant all on all schemas in database <your_dev_database> to role transformer;
grant all on future schemas in database <your_dev_database> to role transformer;
grant all on all tables in database <your_dev_database> to role transformer;
grant all on future tables in database <your_dev_database> to role transformer;
grant all on all views in database <your_dev_database> to role transformer;
grant all on future views in database <your_dev_database> to role transformer;

-- -------------------------
-- PRODUCTION DATABASE — read only
-- DinoAI reads prod models to understand your existing data
-- -------------------------
grant usage on database <your_prod_database> to role transformer;
grant usage on all schemas in database <your_prod_database> to role transformer;
grant usage on future schemas in database <your_prod_database> to role transformer;
grant select on all tables in database <your_prod_database> to role transformer;
grant select on future tables in database <your_prod_database> to role transformer;
grant select on all views in database <your_prod_database> to role transformer;
grant select on future views in database <your_prod_database> to role transformer;

-- -------------------------
-- SOURCE DATABASE — read only
-- DinoAI inspects raw source tables to understand upstream data
-- -------------------------
grant usage on database <your_source_database> to role transformer;
grant usage on all schemas in database <your_source_database> to role transformer;
grant usage on future schemas in database <your_source_database> to role transformer;
grant select on all tables in database <your_source_database> to role transformer;
grant select on future tables in database <your_source_database> to role transformer;
grant select on all views in database <your_source_database> to role transformer;
grant select on future views in database <your_source_database> to role transformer;
```

<Info>
  If your source and production data live in the same database but different schemas, replace the database-level grants with schema-level grants.\
  e.g. `grant select on all tables in schema <your_database>.<your_schema> to role transformer;`
</Info>

***

#### Step 3. Assign the Public Key to the User

Once the user is created, assign the RSA public key to enable key-pair authentication.

```sql theme={"system"}
use role securityadmin;

-- Paste the public key content here (no header/footer lines, key must be on a single line)
alter user paradime_dinoai_user set rsa_public_key='MIIBIjANBgkqhkiG9w0BAQEF...';
```

**Verify the key was assigned**

```sql theme={"system"}
desc user paradime_dinoai_user;
```

Check that the `RSA_PUBLIC_KEY` column is populated.

**(Optional) Verify the fingerprint**

Cross-check that the key in Snowflake matches your local key.

```bash theme={"system"}
# Get the SHA-256 fingerprint of your local public key
openssl rsa -pubin -in dinoai_rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
```

```sql theme={"system"}
-- Compare against what Snowflake stored
select name, rsa_public_key_fp
from table(information_schema.users())
where name = 'PARADIME_DINOAI_USER';
```

***

#### Step 4. Configure the Connection in Paradime

1. Click **Settings** in the top menu bar
2. Click **Connections** in the left sidebar
3. Click **Add New** next to **DinoAI Background Agent Environment**
4. Select **Snowflake** as the connection type
5. Choose **Key-Pair Authentication**

Fill in the fields as follows:

| Field                   | Description                                       | Example                                 |
| ----------------------- | ------------------------------------------------- | --------------------------------------- |
| Profile                 | Profile name from your `dbt_project.yaml`         | `dbt-snowflake`                         |
| Target                  | Target name for the DinoAI connection             | `dinoai`                                |
| Account                 | Your Snowflake account identifier                 | `vj71689.eu-west-2.aws`                 |
| Role                    | Role assigned to the service user                 | `transformer`                           |
| Database                | The **dev** database DinoAI will build objects in | `dev`                                   |
| Warehouse               | Virtual warehouse for agent sessions              | `transforming`                          |
| Username                | Service user created in Step 2                    | `paradime_dinoai_user`                  |
| Private Key             | Full private key including header/footer lines    | `-----BEGIN ENCRYPTED PRIVATE KEY-----` |
| Passphrase *(optional)* | Passphrase set when generating the key            | `passphrase_xyz`                        |
| Schema                  | Default schema for dbt objects at runtime         | `dbt_dinoai`                            |
| Threads                 | Number of concurrent threads                      | `8`                                     |

<Warning>
  When pasting the **Private Key**, you must include the full header and footer lines:

  ```
  -----BEGIN ENCRYPTED PRIVATE KEY-----
  < key content >
  -----END ENCRYPTED PRIVATE KEY-----
  ```

  Omitting them will cause the connection to fail.
</Warning>

***

#### Step 5. Allowlist Paradime IPs (if using network policies)

If your Snowflake account has IP restrictions, allowlist the Paradime IPs for your data region.

```sql theme={"system"}
-- Add Paradime IPs to an existing network policy
alter network policy <your_policy_name>
    set allowed_ip_list = ('<paradime_ip_1>', '<paradime_ip_2>');

-- Apply the policy to the DinoAI service user
alter user paradime_dinoai_user set network_policy = <your_policy_name>;
```

👉 Full IP list [here](/developers/ip-restrictions).

***

#### Troubleshooting

**JWT token errors on connection test**

* Run `DESC USER paradime_dinoai_user;` and verify `RSA_PUBLIC_KEY` is populated
* Make sure the private key in Paradime includes the header/footer lines
* If using an encrypted key, confirm the passphrase is correct

**Permission denied during agent runs**

* Verify grants were run as `SYSADMIN`, not `SECURITYADMIN`
* Check future grants are in place — new schemas/tables won't inherit permissions without them
* Run `SHOW GRANTS TO ROLE transformer;` to audit what the role can access
* If DinoAI can't read source or prod data, double-check read grants on those databases

**Connection timeout / network errors**

* Ensure Paradime IPs are allowlisted in your Snowflake network policy (Step 5)
* Verify the account identifier format matches [Snowflake's documentation](https://docs.snowflake.com/en/user-guide/admin-account-identifier)


## Related topics

- [Snowflake](/products/settings/connections/dinoai-background-agent-environment/snowflake.md)
- [Snowflake cost connection](/products/settings/connections/cost-connection/snowflake-connection.md)
- [DinoAI Agent](/guides/paradime-101/getting-started-with-the-paradime-ide/dinoai-accelerating-your-analytics-engineering-workflow/dinoai-agent/index.md)
