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

# Snowflake Key-Pair Write

*This is one of several Snowflake connectors, each its own integration card. This article covers **Snowflake Provisioning (Key-Pair Authentication)** (connector* `snowflake-keypair-write`*), which syncs and provisions users and roles using JWT key-pair authentication. For read-only key-pair access, use [Snowflake Read-Only (Key-Pair Authentication)](/integrations/library/snowflake/snowflake-key-pair-read). For OAuth-based sync and provisioning, use [Snowflake](/integrations/library/snowflake/snowflake-multi-auth). For token-based read-only access, use [Snowflake Read-Only (PAT)](/integrations/library/snowflake/snowflake-pat).*

## After this article

You'll be able to connect Snowflake to Lumos over key-pair authentication with write access. Lumos syncs users and roles and provisions them (create, update, deactivate, delete, and role assignment).

## Capabilities

| Functionality | Type | Sync | Provision | Description |
| :- | :- | :- | :- | :- |
| Users | Account | Yes | Yes | View, create, update, deactivate, and delete Snowflake user accounts |
| Roles | Permission | Yes | Yes | Role definitions and assignments. Assign and unassign roles |
| Privileges | Permission | Yes (opt-in) | No | Object-level privileges on databases, schemas, and tables. Privilege sync is **off by default** and enabled via a connector setting |

## Required plan and roles

* **Snowflake plan:** no minimum plan is required.
* **Integration user:** create a dedicated Snowflake user for Lumos with a login name, for example `CREATE USER LUMOS_INTEGRATION_USER LOGIN_NAME=lumos_integration`. Because this connector authenticates with a key pair, set the user to `TYPE = SERVICE` or `PASSWORD = NULL` so Snowflake doesn't enforce password expiry and block key-pair login with error 390106.
* **Role and warehouse:** connect with a warehouse and a role that can manage users and roles. The role needs `GRANT CREATE USER ON ACCOUNT` and `GRANT MANAGE GRANTS ON ACCOUNT`, plus `GRANT USAGE ON WAREHOUSE`. To register the RSA public key on the integration user, the role also needs `GRANT MODIFY PROGRAMMATIC AUTHENTICATION METHODS ON USER`. For privilege sync, grant the `SNOWFLAKE.USAGE_VIEWER` and `SNOWFLAKE.SECURITY_VIEWER` database roles so the role can read object grants. The connection identity is derived from **warehouse + account**.
* **Key pair:** generate the RSA key pair for the connection before submitting the connection form (use **Get Key**), then register the matching public key on the integration user with `ALTER USER <user> SET RSA_PUBLIC_KEY = '<your-public-key>'`.

## Read-only access vs provisioning

**Is read-only possible?** The setup below grants write access, and this card is meant for provisioning. If you connect it with a role that lacks `MANAGE GRANTS ON ACCOUNT`, sync still runs and Lumos reads each user's email, first name, and last name from `SNOWFLAKE.ACCOUNT_USAGE.USERS` (which needs only `SNOWFLAKE.SECURITY_VIEWER`), but write actions fail. For a supported read-only connection, use the Snowflake Read-Only (Key-Pair Authentication) card instead.

**What read-only requires.** Use the Snowflake Read-Only (Key-Pair Authentication) connector, not this one. It authenticates the same way, a dedicated integration user with an RSA key pair, but the connecting role is scoped to `SNOWFLAKE.USAGE_VIEWER` and `SNOWFLAKE.SECURITY_VIEWER` only, with no user or role management grants.

**What full provisioning requires.** A dedicated integration user set to `TYPE = SERVICE` (or with its password set to `NULL`) so key-pair login isn't blocked by password expiry, connected through a role granted `CREATE USER ON ACCOUNT`, `MANAGE GRANTS ON ACCOUNT`, `USAGE ON WAREHOUSE`, and `MODIFY PROGRAMMATIC AUTHENTICATION METHODS ON USER` to register the RSA key. Follow the steps below for the full setup SQL.

**Watch out for.** Switching between the read-only and provisioning key-pair connectors means adding a new integration card, not just changing the role granted to an existing connection. Object-level privilege sync is opt-in and off by default even on this provisioning connector. A public key mismatch after key rotation surfaces as a JWT signature error (390144). Reconnect in place with the matching key pair rather than generating a new one, since a new pair can orphan other integrations still using the old private key.

## Instructions

**Phase 1: Prepare the Snowflake integration user**

1. Log in to your Snowflake account at `https://your-account-identifier.snowflakecomputing.com`.
2. Go to **Projects -> Workspaces (Worksheets)** and click **+ Add New** to create a new SQL worksheet.
3. Insert the following statements into the worksheet and run them step by step. They create the integration user and role, grant the account-usage and provisioning privileges, and allow key-pair registration:

```sql theme={null}
// 1) Create a new user
CREATE USER LUMOS_INTEGRATION_USER LOGIN_NAME=lumos_integration PASSWORD='123456789';

// 2) Create a new role
USE ROLE SECURITYADMIN;
CREATE ROLE LUMOS_INTEGRATION_ROLE;

// 3) Allow the role to read SNOWFLAKE.ACCOUNT_USAGE views.
USE ROLE ACCOUNTADMIN;
GRANT DATABASE ROLE SNOWFLAKE.USAGE_VIEWER TO ROLE LUMOS_INTEGRATION_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.SECURITY_VIEWER TO ROLE LUMOS_INTEGRATION_ROLE;
GRANT USAGE ON WAREHOUSE <warehouse-name> TO ROLE LUMOS_INTEGRATION_ROLE;

// 4) Grant provisioning permissions to the role.
USE ROLE ACCOUNTADMIN;
GRANT CREATE USER ON ACCOUNT TO ROLE LUMOS_INTEGRATION_ROLE;
GRANT MANAGE GRANTS ON ACCOUNT TO ROLE LUMOS_INTEGRATION_ROLE;

// 5) Associate the necessary permissions to the user and role.
GRANT ROLE LUMOS_INTEGRATION_ROLE TO USER LUMOS_INTEGRATION_USER;
ALTER USER LUMOS_INTEGRATION_USER SET DEFAULT_ROLE='LUMOS_INTEGRATION_ROLE';
GRANT MODIFY PROGRAMMATIC AUTHENTICATION METHODS ON USER LUMOS_INTEGRATION_USER TO ROLE LUMOS_INTEGRATION_ROLE;
```

4. Generate a key pair. In the connection form's key field, enter a key identifier of your choice, select **Generate new keys, even if keys exist already**, and click **Get Key**.
5. Copy the public key and assign it to the integration user:

```sql theme={null}
ALTER USER LUMOS_INTEGRATION_USER SET RSA_PUBLIC_KEY='<your-public-key>';
```

If password expiry blocks key-pair login (error 390106), set the user to `TYPE = SERVICE` or run `ALTER USER LUMOS_INTEGRATION_USER SET PASSWORD = NULL`.

**Phase 2: Connect in Lumos**

1. Find the **Snowflake Provisioning (Key-Pair Authentication)** card in your Lumos integrations (Reconnect or add new).
2. Provide the account identifier, warehouse, role, and integration user.
3. Generate the key pair with **Get Key** before submitting, then click **Connect**.

## Troubleshooting

**Key-pair connection fails with error 390106 ("Specified password has expired").** Set the integration user to `TYPE = SERVICE` or run `ALTER USER <user> SET PASSWORD = NULL`. Snowflake enforces password expiry even for key-pair auth, and SSO enforcement doesn't block key-pair service users.

**Error 390144 (JWT signature mismatch).** The stored public key no longer matches the private key held by the connection. Reconnect the integration in place with the matching key pair rather than generating a new one. A new pair can orphan other integrations still using the previous private key.

**Connection form rejected the key-pair credential.** The form was submitted before the key pair was generated. Click **Get Key** to generate the pair before submitting.

**Automated removals never dispatch.** The Lumos matched-account safety check skips Snowflake accounts with a NULL email (common for service or ghost users). Populate the email attribute on users you want Lumos to deprovision automatically. Duplicate or ghost user records with no email can also cause provisioning to target the wrong account.

**Privileges are not syncing.** Object-level privilege sync is opt-in on this connector. Enable the privilege-sync connector setting if you need database, schema, or table privileges.
