> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/concepts/resources/nilus/troubleshooting/snowflake-key-pair-authentication.md).

# Snowflake: Key-Pair Authentication

This page covers how key-pair authentication works, how to generate and register your keys in Snowflake, and how to connect securely from Nilus.

{% hint style="info" %}
**Reference:** [Snowflake documentation, Key-Pair Authentication & Key Rotation](https://docs.snowflake.com/en/user-guide/key-pair-auth)
{% endhint %}

## Overview

Snowflake supports **key-pair authentication** as a password-less alternative to username/password credentials. With key-pair authentication:

* You create a **public/private RSA key pair** locally.
* You register the **public key** with your Snowflake user.
* The Nilus connector (or any client) signs authentication tokens with the **private key**, and Snowflake verifies them using the registered public key.

**Benefits**

* Removes passwords from application configurations.
* Supports key rotation through dual public key support (`RSA_PUBLIC_KEY` and `RSA_PUBLIC_KEY_2`).
* Supported across Snowflake’s Python, JDBC, ODBC, and CLI clients.

## Generating a key pair

Create a secure directory and generate your key pair in **PKCS#8 PEM** format. Encrypted private keys are recommended.

```bash
mkdir -p ~/.snowflake/keys
cd ~/.snowflake/keys

# Generate encrypted private key (recommended)
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out snowflake_rsa_key.p8

# Or, unencrypted private key (not recommended)
# openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out snowflake_rsa_key.p8 -nocrypt

# Extract public key
openssl rsa -in snowflake_rsa_key.p8 -pubout -out snowflake_rsa_key.pub

# Secure file permissions
chmod 700 ~/.snowflake ~/.snowflake/keys
chmod 600 ~/.snowflake/keys/snowflake_rsa_key.p8 ~/.snowflake/keys/snowflake_rsa_key.pub

```

To retrieve the public key for Snowflake:

```bash
awk 'NR>1 && !/-----/' ~/.snowflake/keys/snowflake_rsa_key.pub | tr -d '\n'
```

<details>

<summary>(Optional) Generate a fingerprint for verification:</summary>

```bash
openssl rsa -pubin -in ~/.snowflake/keys/snowflake_rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
```

* It computes a SHA‑256 fingerprint of your public key so you can verify it matches what Snowflake stored.

**Breakdown of the pipeline:**

* `openssl rsa -pubin -in ... -outform DER:` loads your PEM public key and converts it to binary DER.
* `| openssl dgst -sha256 -binary:` computes the raw SHA‑256 hash (digest) of that DER.
* `| openssl enc -base64:` base64‑encodes the digest into a readable string.

**How to use it:**

* Compare the command’s output to RSA\_PUBLIC\_KEY\_FP from DESC USER \<user> after removing the SHA256: prefix. They must match; if not, the bound key and your local key differ.

Reference: Snowflake key‑pair auth and fingerprint verification steps [docs](https://docs.snowflake.com/en/user-guide/key-pair-auth).

</details>

## Registering the public key in Snowflake

You’ll need a role with privileges to modify users (e.g., `ACCOUNTADMIN`, `SECURITYADMIN`, or a custom role with `MODIFY PROGRAMMATIC AUTHENTICATION METHODS`).

```sql
USE ROLE ACCOUNTADMIN;

ALTER USER <your_user> SET RSA_PUBLIC_KEY='MIIBIjANBgkqh...';
```

Verify your setup:

```sql
DESC USER <your_user>;
```

**Troubleshooting**

| Issue                     | Cause / Resolution                                                                     |
| ------------------------- | -------------------------------------------------------------------------------------- |
| `JWT token is invalid`    | The private key used by the client doesn’t match the public key on the Snowflake user. |
| `Insufficient privileges` | The active role cannot modify the user; switch to `ACCOUNTADMIN` or equivalent.        |

## Testing a key-pair connection (Python example)

```python
import snowflake.connector

conn = snowflake.connector.connect(
    user="<your_user>",
    account="<your_account>",
    private_key_file="/absolute/path/to/snowflake_rsa_key.p8",
    role="<role>",
    warehouse="<warehouse>",
    database="<database>",
)
cs = conn.cursor()
try:
    cs.execute("select current_user(), current_role(), current_warehouse(), current_database()")
    print(cs.fetchone())
finally:
    cs.close()
    conn.close()
```

**Notes**

* No password is required when using key-pair authentication.
* If you used an encrypted private key, confirm your client can provide the passphrase.

## Configuring a Snowflake depot for Nilus

When defining a Snowflake depot in Nilus, include your private key under `connectionSecret.data.key`.

> ⚠️ Important: Keep private keys out of version control and shared files.

```yaml
version: v2alpha
name: "<depot-name>"
type: depot
tags:
  - snowflake
layer: user
depot:
  type: snowflake
  description: "<description>"
  spec:
    warehouse: "<WAREHOUSE>"
    url: "<ACCOUNT>.snowflakecomputing.com"
    database: "<DATABASE>"
    account: "<ACCOUNT>"
    role: "<ROLE>"
  external: true
  connectionSecret:
    - purpose: rw
      type: key-value-properties
      data:
        username: "<your_user>"
        auth_mode: key-pair
        key: |
          -----BEGIN PRIVATE KEY-----
          <paste your private key PEM contents here>
          -----END PRIVATE KEY-----

```

## Key rotation

Snowflake supports dual public keys per user for rotation.

1. Generate a new key pair.
2. Register the new public key as `RSA_PUBLIC_KEY_2`:

```sql
ALTER USER <your_user> SET RSA_PUBLIC_KEY_2='MIIBIjANBgkqh...';
```

1. Update Nilus and other clients to use the new private key.
2. Remove the old key:

```sql
ALTER USER <your_user> UNSET RSA_PUBLIC_KEY;
```

### Example: working depot

```yaml
version: v2alpha
name: "newsnowflakedepot"
type: depot
tags:
  - snowflake
layer: user
depot:
  type: snowflake
  description: "Snowflake Sample Data"
  spec:
    warehouse: "COMPUTE_WH"
    url: "<ACCOUNT>.snowflakecomputing.com"
    database: "SNOWFLAKE_SAMPLE_DATA"
    account: "<ACCOUNT>"
    role: "ACCOUNTADMIN"
  external: true
  connectionSecret:
    - purpose: rw
      type: key-value-properties
      data:
        username: "<your_user>"
        auth_mode: key-pair
        key: |
          -----BEGIN PRIVATE KEY-----
          <paste your private key PEM contents here>
          -----END PRIVATE KEY-----

```

## Security best practices

* Restrict file permissions for key storage (`chmod 600` on private keys).
* Prefer encrypted private keys with strong passphrases.
* Use a dedicated secret management system where possible.
* Rotate keys periodically and audit access.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/concepts/resources/nilus/troubleshooting/snowflake-key-pair-authentication.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
