Configure Snowflake authentication
Configure how PyRel signs in to Snowflake from your development machine or an automated application. Choose an authentication method and verify the connection before using it to deploy a model.
- Prerequisites
- Access to a Snowflake account with the RelationalAI Native App installed, plus your account, warehouse, and user details from your Snowflake administrator.
- A working PyRel installation.
Choose an authentication method
Section titled “Choose an authentication method”Choose a method allowed by your Snowflake account’s authentication policy. For local development, you can complete browser or MFA prompts. For an unattended application or CI job that deploys models, choose a method that doesn’t need a person to sign in. Arrange the credentials, public key, or OAuth integration with your administrator before configuring that method.
| Method | Use when | Supports optional Direct Access? |
|---|---|---|
| Username/password | Your account allows password sign-in and you can store the password securely. | No |
| Username/password with MFA | You can complete your account’s MFA prompt or supply a current passcode. Not suitable for unattended jobs. | No |
| OAuth token | Your application already obtains and refreshes Snowflake OAuth access tokens. | No |
| OAuth authorization code | You can complete an interactive browser sign-in using an OAuth integration and a local callback. | Yes |
| OAuth client credentials | Your identity provider and Snowflake integration support machine-to-machine OAuth for an unattended application. | No |
| Key-pair (JWT) | A Snowflake user has a registered public key and your application can securely access the matching private key. | Yes |
| External browser | You can complete browser sign-in on the machine running PyRel. Not suitable for unattended jobs. | No |
| Programmatic access token (PAT) | Your administrator has provisioned a Snowflake PAT for the intended user and role. | Yes |
These are client authentication choices. A scheduled refresh in Snowflake doesn’t rerun your local browser sign-in. Its permissions and any additional reasoner credentials must be configured for the deployment. Follow Configure deployment for deployment settings.
If your application already owns a Snowpark session, see Use an existing Snowpark session.
Configure your connection
Section titled “Configure your connection”Define authentication inside a named entry under connections.
The examples use the name sf.
Set default_connection when you have more than one connection, or let PyRel use your only connection automatically.
Authentication proves your identity to Snowflake.
It doesn’t grant permission to deploy a model or read its source tables.
The connection’s role sets the initial Snowflake role when PyRel creates a session.
The separate deployment.role selects the role used to deploy and refresh the model.
Your sign-in must allow that role, and the role needs the required privileges.
See Set the deployment target.
Replace the example account, warehouse, and user with your own values. Supply secrets through environment variables, a secret manager, or protected files. Don’t put credential values in source control. Set each environment variable used by your chosen example before loading the configuration. Missing required variables stop configuration loading rather than supplying a credential.
Choose your configuration method once, then use the example for your authenticator. These examples define connection settings without opening a session. After configuring a method, continue to Validate your connection.
Save your chosen configuration in raiconfig.yaml.
See Load configuration from files for file locations, overrides, and profiles.
Configure username/password authentication
Section titled “Configure username/password authentication”Set SNOWFLAKE_PASSWORD before loading this file:
connections: sf: type: snowflake authenticator: username_password account: my_account warehouse: my_warehouse user: my_user password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"Use the MFA variant instead if your account requires MFA.
Configure username/password authentication with MFA
Section titled “Configure username/password authentication with MFA”Snowflake handles the MFA flow.
For a Duo Push prompt, omit passcode and approve the prompt.
If your method requires a code, generate a fresh one and set SNOWFLAKE_PASSCODE immediately before signing in.
connections: sf: type: snowflake authenticator: username_password_mfa account: my_account warehouse: my_warehouse user: my_user password: "{{ env_var('SNOWFLAKE_PASSWORD') }}" # Include only when your MFA method requires a code: # passcode: "{{ env_var('SNOWFLAKE_PASSCODE') }}"If sign-in fails because a passcode expired, generate a new code and retry. See Snowflake’s MFA connection guidance.
Configure OAuth authentication
Section titled “Configure OAuth authentication”Obtain a Snowflake OAuth access token outside PyRel and set SNOWFLAKE_OAUTH_TOKEN.
PyRel passes the token to Snowflake but doesn’t acquire or refresh it.
connections: sf: type: snowflake authenticator: oauth account: my_account warehouse: my_warehouse token: "{{ env_var('SNOWFLAKE_OAUTH_TOKEN') }}"When the token expires or changes, obtain a replacement and follow Clear the session cache.
Configure OAuth authorization-code authentication
Section titled “Configure OAuth authorization-code authentication”This method opens a browser and exchanges an authorization code for tokens. Your OAuth integration must allow the local callback URI you configure. Complete the administrator setup in Grant user access.
connections: sf: type: snowflake authenticator: oauth_authorization_code account: my_account warehouse: my_warehouse user: my_user oauth_client_id: my_oauth_client_id oauth_redirect_uri: "http://localhost:8080/callback" # Include if your OAuth client requires a secret: # oauth_client_secret: "{{ env_var('SNOWFLAKE_OAUTH_CLIENT_SECRET') }}"The callback must use a loopback host such as localhost or 127.0.0.1.
This authenticator can create a Snowpark session without enabling Direct Access.
To use it for Direct Access too, follow Enable Direct Access.
Configure OAuth client-credentials authentication
Section titled “Configure OAuth client-credentials authentication”Use an OAuth client ID, client secret, and token endpoint provisioned by your identity provider. Your Snowflake OAuth integration must accept the resulting tokens.
connections: sf: type: snowflake authenticator: oauth_client_credentials account: my_account warehouse: my_warehouse role: MY_ROLE oauth_client_id: my_oauth_client_id oauth_client_secret: "{{ env_var('SNOWFLAKE_OAUTH_CLIENT_SECRET') }}" oauth_token_request_url: "https://idp.example.com/oauth/token" oauth_scope: "session:role:MY_ROLE"Replace the endpoint and scope with the values required by your integration.
oauth_scope is optional.
Set oauth_credentials_in_body: true if your identity provider requires credentials in the request body rather than HTTP Basic authentication.
Snowflake’s connector handles token acquisition for this flow.
This method doesn’t support connection-based Direct Access.
Configure key-pair authentication
Section titled “Configure key-pair authentication”Register the public key on the Snowflake user before using the matching private key. See Key-pair authentication and rotation.
connections: sf: type: snowflake authenticator: jwt account: my_account warehouse: my_warehouse user: my_user private_key_path: /path/to/key.pem # Include only for an encrypted key: # private_key_passphrase: "{{ env_var('SNOWFLAKE_PRIVATE_KEY_PASSPHRASE') }}"PyRel reads the key when it needs to create a Snowpark session. Restrict the file’s permissions and keep it out of source control. If authentication fails, check that the process can read the file and that Snowflake has the matching public key.
Configure external browser authentication
Section titled “Configure external browser authentication”Run this method in an environment that can launch a browser and complete sign-in:
connections: sf: type: snowflake authenticator: externalbrowser account: my_account warehouse: my_warehouse user: my_userFor CI or an unattended application, choose a non-interactive method instead.
Configure programmatic access token authentication
Section titled “Configure programmatic access token authentication”Obtain a Snowflake PAT for the intended user. For administrator setup, see Grant user access.
connections: sf: type: snowflake authenticator: programmatic_access_token account: my_account warehouse: my_warehouse user: my_user token: "{{ env_var('SNOWFLAKE_PROGRAMMATIC_ACCESS_TOKEN') }}"To read a protected token file instead, replace token with token_file_path: /path/to/token.txt.
PyRel doesn’t issue or rotate PATs.
If the PAT is restricted to a role, that restriction must allow the role your deployment needs.
Arrange token permissions and rotation with your administrator.
Define multiple connections
Section titled “Define multiple connections”Use separate named connections when the account, warehouse, user, or authentication differs. If only the deployment target differs, use configuration profiles instead.
default_connection: sf_devconnections: sf_dev: type: snowflake authenticator: externalbrowser account: my_dev_account warehouse: my_warehouse user: my_user sf_test: type: snowflake authenticator: externalbrowser account: my_test_account warehouse: my_warehouse user: my_userThis selects sf_dev as the default without connecting to either account.
Use your chosen authenticator in each entry.
Create a configuration with create_config().
The dictionaries below use the same fields as the file examples.
See Create configuration in code for configuration overrides.
Configure username/password authentication in Python
Section titled “Configure username/password authentication in Python”import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "username_password", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", "password": os.environ["SNOWFLAKE_PASSWORD"], }, },)Use the MFA variant instead if your account requires MFA.
Configure username/password authentication with MFA in Python
Section titled “Configure username/password authentication with MFA in Python”Snowflake handles the MFA flow.
For a Duo Push prompt, leave SNOWFLAKE_PASSCODE unset and approve the prompt.
If your method requires a code, generate a fresh one and set that variable immediately before signing in.
import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "username_password_mfa", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", "password": os.environ["SNOWFLAKE_PASSWORD"], "passcode": os.getenv("SNOWFLAKE_PASSCODE"), }, },)If sign-in fails because a passcode expired, generate a new code and retry. See Snowflake’s MFA connection guidance.
Configure OAuth authentication in Python
Section titled “Configure OAuth authentication in Python”Obtain a Snowflake OAuth access token outside PyRel and set SNOWFLAKE_OAUTH_TOKEN.
PyRel passes the token to Snowflake but doesn’t acquire or refresh it.
import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "oauth", "account": "my_account", "warehouse": "my_warehouse", "token": os.environ["SNOWFLAKE_OAUTH_TOKEN"], }, },)When the token expires or changes, obtain a replacement and follow Clear the session cache.
Configure OAuth authorization-code authentication in Python
Section titled “Configure OAuth authorization-code authentication in Python”This method opens a browser and exchanges an authorization code for tokens. Your OAuth integration must allow the local callback URI you configure. Complete the administrator setup in Grant user access.
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "oauth_authorization_code", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", "oauth_client_id": "my_oauth_client_id", "oauth_redirect_uri": "http://localhost:8080/callback", }, },)If your OAuth client requires a secret, add oauth_client_secret from your secret manager or environment.
The callback must use a loopback host such as localhost or 127.0.0.1.
This authenticator can create a Snowpark session without enabling Direct Access.
To use it for Direct Access too, follow Enable Direct Access.
Configure OAuth client-credentials authentication in Python
Section titled “Configure OAuth client-credentials authentication in Python”Use an OAuth client ID, client secret, and token endpoint provisioned by your identity provider. Your Snowflake OAuth integration must accept the resulting tokens.
import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "oauth_client_credentials", "account": "my_account", "warehouse": "my_warehouse", "role": "MY_ROLE", "oauth_client_id": "my_oauth_client_id", "oauth_client_secret": os.environ["SNOWFLAKE_OAUTH_CLIENT_SECRET"], "oauth_token_request_url": "https://idp.example.com/oauth/token", "oauth_scope": "session:role:MY_ROLE", }, },)Replace the endpoint and scope with the values required by your integration.
oauth_scope is optional.
Add "oauth_credentials_in_body": True to the connection dictionary if your identity provider requires credentials in the request body rather than HTTP Basic authentication.
Snowflake’s connector handles token acquisition for this flow.
This method doesn’t support connection-based Direct Access.
Configure key-pair authentication in Python
Section titled “Configure key-pair authentication in Python”Register the public key on the Snowflake user before using the matching private key. See Key-pair authentication and rotation.
import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "jwt", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", "private_key_path": "/path/to/key.pem", "private_key_passphrase": os.getenv("SNOWFLAKE_PRIVATE_KEY_PASSPHRASE"), }, },)Set SNOWFLAKE_PRIVATE_KEY_PASSPHRASE if the key is encrypted.
PyRel reads the key when it needs to create a Snowpark session.
Restrict the file’s permissions and keep it out of source control.
You can supply PEM key contents through private_key instead of private_key_path when your application holds the key in memory.
If authentication fails, check access to the key and its matching public key in Snowflake.
Configure external browser authentication in Python
Section titled “Configure external browser authentication in Python”Run this method in an environment that can launch a browser and complete sign-in:
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "externalbrowser", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", }, },)For CI or an unattended application, choose a non-interactive method instead.
Configure programmatic access token authentication in Python
Section titled “Configure programmatic access token authentication in Python”Obtain a Snowflake PAT for the intended user. For administrator setup, see Grant user access.
import os
from relationalai.config import create_config
cfg = create_config( connections={ "sf": { "type": "snowflake", "authenticator": "programmatic_access_token", "account": "my_account", "warehouse": "my_warehouse", "user": "my_user", "token": os.environ["SNOWFLAKE_PROGRAMMATIC_ACCESS_TOKEN"], }, },)To read a protected token file instead, replace token with "token_file_path": "/path/to/token.txt" in the connection dictionary.
PyRel doesn’t issue or rotate PATs.
If the PAT is restricted to a role, that restriction must allow the role your deployment needs.
Arrange token permissions and rotation with your administrator.
Use a typed auth class instead of a dictionary
Section titled “Use a typed auth class instead of a dictionary”Typed authentication objects are an alternative to connection dictionaries, not an additional setup step. For example, this defines the same external-browser connection:
from relationalai.config import ExternalBrowserAuth, create_config
cfg = create_config( connections={ "sf": ExternalBrowserAuth( account="my_account", warehouse="my_warehouse", user="my_user", ), },)See the Snowflake authentication classes for the class and fields for each method.
Define multiple connections in Python
Section titled “Define multiple connections in Python”Use separate named connections when the account, warehouse, user, or authentication differs. If only the deployment target differs, use configuration profiles instead.
from relationalai.config import create_config
cfg = create_config( default_connection="sf_dev", connections={ "sf_dev": { "type": "snowflake", "authenticator": "externalbrowser", "account": "my_dev_account", "warehouse": "my_warehouse", "user": "my_user", }, "sf_test": { "type": "snowflake", "authenticator": "externalbrowser", "account": "my_test_account", "warehouse": "my_warehouse", "user": "my_user", }, },)This selects sf_dev as the default without connecting to either account.
Use your chosen authenticator in each entry.
To use a configuration object with a model, pass it explicitly:
from relationalai.config import create_configfrom relationalai.semantics import Model
cfg = create_config()m = Model("MyModel", config=cfg)This example loads file-backed configuration.
For programmatic configuration, use the cfg from your chosen Python example instead.
Constructing the configuration doesn’t verify credentials or deploy the model.
Use an existing Snowpark session
Section titled “Use an existing Snowpark session”PyRel can reuse a Snowpark session supplied by your application or available as the active session. This commonly happens in Snowflake Notebooks, but isn’t limited to notebooks. When PyRel reuses a session, signing in again with your configured credentials isn’t necessary. A connection check then validates that session, not the credentials in your configuration.
With your connection configuration saved in a file, pass an existing Snowpark session to create_config(snowflake_session=...).
In this example, session is the session your application has already created:
from relationalai.config import create_config
cfg = create_config(snowflake_session=session)PyRel loads your configuration as usual but uses the supplied session instead of signing in with the configured credentials. Passing a session doesn’t replace the connection configuration. Your application is responsible for supplying and managing the session. In Snowflake Notebooks, manage the session context through the notebook’s supported controls. See Session context in Notebooks.
Validate your connection
Section titled “Validate your connection”Validate the connection before attempting a deployment. These checks confirm that a Snowpark session can run a simple SQL query. They don’t prove access to source tables, permission to deploy, or Direct Access connectivity.
To test configured credentials rather than reuse an existing session, run the check in a fresh process without a supplied or active Snowpark session.
Validate the default connection with the CLI
Section titled “Validate the default connection with the CLI”Run rai connect from the directory containing your configuration:
rai connectLook for Connected successfully and confirm that the connection details shown match your intended account and warehouse.
The command runs SELECT 1 and selects the configured warehouse.
It checks only the default connection.
If you use profiles, select one with rai --profile dev connect or RAI_PROFILE.
See configuration profiles.
If the check fails, follow the reported suggestion and inspect the resolved settings with rai config explain.
Check the selected profile, account, authenticator, and required environment variables.
For expired credentials, follow Clear the session cache.
For warehouse or role errors, ask your administrator to confirm access.
Validate the default connection in Python
Section titled “Validate the default connection in Python”Use the configuration object directly, without creating a model:
from relationalai.config import create_config
cfg = create_config()session = cfg.get_session()print(session.sql("SELECT 1 AS CONNECTION_OK").collect()[0]["CONNECTION_OK"])1For programmatic configuration, use your existing cfg instead of calling create_config() again.
The result confirms that the session can run SQL.
If it fails, check the selected configuration and credentials as described in the CLI section.
Validate a specific named connection
Section titled “Validate a specific named connection”After defining sf_dev, select it by name:
from relationalai.config import SnowflakeConnection, create_config
cfg = create_config()conn = cfg.get_connection(SnowflakeConnection, name="sf_dev")session = conn.get_session()print(session.sql("SELECT 1 AS CONNECTION_OK").collect()[0]["CONNECTION_OK"])1If the connection name isn’t found, check the loaded file and profile or use your programmatically created cfg.
As with the default connection, an existing active session can be reused.
Use a fresh process to test a different connection’s credentials independently.
Clear the session cache
Section titled “Clear the session cache”PyRel caches the Snowpark session on each connection object. Clearing that cache removes the reference, but doesn’t close the session, reload configuration files or environment variables, or guarantee a new sign-in. PyRel can find and reuse an active session again.
After rotating credentials:
- Update the environment variable, secret manager value, or protected file.
- Reload the configuration if credentials were read into it, or rebuild the programmatic configuration from the updated values.
- Use a fresh process without an active session to verify that the new credentials work.
In a long-running application, manage session ownership explicitly.
If PyRel created the session, conn.close() closes it and clears that connection’s cache.
If the session was supplied or reused, the application or notebook that owns it must manage its lifecycle.
To drop only the cached reference on a connection you already obtained:
conn.clear_session_cache()The next conn.get_session() resolves a session again.
It doesn’t necessarily create a new one or prompt for authentication.
For multiple connection objects, manage each affected object’s cache separately.
Browser or OAuth token caches are also distinct from this Snowpark session cache.
Enable Direct Access
Section titled “Enable Direct Access”Direct Access is an optional client transport for supported operations. It sends those requests to the RelationalAI Native App’s ingress endpoint rather than through Snowflake SQL service functions, which can reduce per-call overhead. It doesn’t eliminate Snowflake sessions, deployment SQL, or deployment privileges.
Use key-pair (JWT), OAuth authorization-code, or PAT authentication.
Supplying an OAuth token with authenticator: oauth and using OAuth client credentials aren’t supported by connection-based Direct Access authentication.
Complete Grant user access before enabling it.
Direct Access isn’t available in Snowflake Notebooks or Streamlit.
Add direct_access: true at the top level of your file, not inside a connection.
For programmatic configuration, pass direct_access=True to create_config().
For example, this file enables Direct Access with a PAT:
direct_access: trueconnections: sf: type: snowflake authenticator: programmatic_access_token account: my_account warehouse: my_warehouse user: my_user token: "{{ env_var('SNOWFLAKE_PROGRAMMATIC_ACCESS_TOKEN') }}"Configure Private Link ingress
Section titled “Configure Private Link ingress”For a Private Link account, set spcs_privatelink_zone inside the connection so Direct Access uses your private ingress path.
Ask an administrator with the ACCOUNTADMIN role to run:
SELECT value::stringFROM TABLE(FLATTEN(INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())))WHERE key = 'app-service-privatelink-url';The result contains the account’s ingress domain, such as *.example.privatelink.snowflake.app.
Remove the leading *. and add the remaining domain to the connection:
direct_access: trueconnections: sf: type: snowflake authenticator: programmatic_access_token account: my_account warehouse: my_warehouse user: my_user token: "{{ env_var('SNOWFLAKE_PROGRAMMATIC_ACCESS_TOKEN') }}" spcs_privatelink_zone: example.privatelink.snowflake.appFor Python, set spcs_privatelink_zone in the connection dictionary or typed auth object.
Use the actual domain returned for your account.
If the query doesn’t return an ingress domain, ask your administrator to confirm the Private Link setup.
For Private Link accounts, run rai doctor and review its Direct Access and Private Link diagnostics.
Resolve any authentication, ingress, or network failures it reports before relying on the private connection.
A successful rai connect alone doesn’t validate this path.
Continue to deployment
Section titled “Continue to deployment”Once the intended connection works, follow Deploy a model to deploy and verify model outputs. Keep deployment settings and any credentials required by deployed reasoner workloads in the deployment configuration. Don’t assume the client authenticator configures those credentials automatically. See the deployment configuration reference for the separate PAT secret and external access integration settings.