Skip to main content
Bag of words connects to Snowflake with the standard Snowflake driver, reads the tables, views, and semantic views in the schemas you point it at, and runs SQL against a warehouse you choose. You can authenticate with a username and password, with key pair (RSA) authentication — the option most Snowflake accounts require once MFA is enforced on human users — or per-user with Sign in with Snowflake (OAuth), where each person signs in with their own Snowflake account and queries run under their own role and permissions.

How it works

Bag of words opens a connection scoped to one database and one or more schema values, using the warehouse you specify for compute (and the role you specify, if any). During indexing it reads:
  • Tables and views from INFORMATION_SCHEMA, including table and column comments where they exist.
  • Semantic views — discovered with SHOW SEMANTIC VIEWS and described with DESC SEMANTIC VIEW. These are exposed to the agent alongside regular tables, and the agent knows to query them through the SEMANTIC_VIEW() function rather than as ordinary tables.
Schema names are normalized to uppercase, matching Snowflake’s INFORMATION_SCHEMA behavior. Queries are read-only.

Before you start

  • A Snowflake account identifier, in the organization-account form (for example ABCDEF-GHIJKL). This is the identifier from your account URL, not the full hostname.
  • A warehouse the connecting user can use, and a database to query.
  • The names of the schemas you want indexed. One schema, or several as a comma-separated list.
  • A user for Bag of words to connect as. A dedicated service user with a read-only role is the usual pattern.
  • Network access from the Bag of words host to your Snowflake account. If your account restricts access by network policy, allow the Bag of words egress IP.
Create a dedicated role with USAGE on the warehouse, database, and schemas, plus SELECT on the objects you want available, and grant it to the service user. Then set that role in the Role field so the connection can never see more than intended.

Step 1 — Generate a key pair (key-pair auth only)

Skip this step if you are using a username and password. Snowflake key-pair authentication uses a 2048-bit RSA key. You generate the pair yourself, register the public key on the Snowflake user, and paste the private key into Bag of words.
1

Generate the private key

For an encrypted key (recommended — openssl prompts you for a passphrase):
For an unencrypted key:
Either form works. Bag of words accepts a PKCS#8 PEM private key and decrypts it with the passphrase you provide.
2

Derive the public key

If the private key is encrypted, openssl asks for the passphrase here.
3

Register the public key on the Snowflake user

Open rsa_key.pub, and copy the body without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- lines and without line breaks. Then, as a user with SECURITYADMIN (or ownership of the target user):
Verify it registered:
4

Keep the private key safe

rsa_key.p8 is a credential. Store it in your secret manager and delete any working copies. Never register the private key with ALTER USER — only the public key goes to Snowflake.

Step 2 — Create an OAuth security integration (per-user sign-in only)

Skip this step unless you want Sign in with Snowflake — per-user OAuth where each person queries as themselves. Snowflake acts as its own OAuth authorization server: you register Bag of words as a client with a security integration, then save the integration’s client ID and secret on the connection.
1

Create the security integration

As ACCOUNTADMIN (or a role with CREATE INTEGRATION):
The redirect URI must match your Bag of words host exactly and must use HTTPS — for a local or non-TLS deployment, add OAUTH_ALLOW_NON_TLS_REDIRECT_URI = TRUE.
2

Read the client ID and secret

Copy OAUTH_CLIENT_ID and one of the OAUTH_CLIENT_SECRET values — they go into the connection’s OAuth Client ID and OAuth Client Secret fields in Step 3.
3

Check the roles users will sign in with

A Snowflake OAuth session cannot use ACCOUNTADMIN or SECURITYADMIN (they are on the integration’s blocked-roles list by default). With the connection’s Role field blank, each token is bound to the user’s default role, so that role needs USAGE on the warehouse, database, and schemas. If you set a Role on the connection, Bag of words requests the session:role:<ROLE> scope so the token authorizes exactly that role — users still need the role granted to them.
OAUTH_ISSUE_REFRESH_TOKENS = TRUE is what lets Bag of words renew the short-lived access token (about 10 minutes) without asking the user to sign in again. When the refresh token itself expires — 90 days at most — the user reconnects.

Step 3 — Add the connection in Bag of words

Go to Data Sources → Add data source → Snowflake and fill in the form. Then choose an authentication method (below), click Test Connection, and select the tables the agent may use.

Authentication modes

Snowflake supports three modes. Username/password and key pair can be used as a shared credential for the whole workspace (system scope) or as a per-user credential where each person supplies their own (user scope). Sign in with Snowflake is per-user only: each person authorizes through Snowflake’s own sign-in and consent screens, and their token is stored and refreshed for them.
Straightforward, but not usable for a user on which your account enforces MFA. For service accounts, prefer key pair.
To force everyone to use their own account, enable Require user authentication on the connection. With OAuth configured as the only user auth mode, each person’s Connect click goes straight to Snowflake’s sign-in page and back.
Using per-user credentials on a database connector — every person authenticating as themselves rather than through one shared login — requires an Enterprise license. See Authentication.

Troubleshooting

The PEM did not parse. Check that you pasted the whole file including both -----BEGIN/-----END lines, that no lines were reflowed or truncated, and that the passphrase field matches how the key was generated. An encrypted key with a blank passphrase, or an unencrypted key with a passphrase set, both fail here.
The public key registered on the Snowflake user does not match the private key you supplied. Re-derive the public key with openssl rsa -in rsa_key.p8 -pubout, re-run ALTER USER ... SET RSA_PUBLIC_KEY='...', and confirm DESC USER shows a new RSA_PUBLIC_KEY_FP. Also confirm the user field is the Snowflake login name, not an email address, unless they are the same.
The role in use has no USAGE on the database or schema, or no SELECT on the objects. Check the role field — with it blank, the user’s default role applies, which may be more restrictive than you expect. Also confirm the schema names are spelled as they appear in Snowflake; they are matched in uppercase.
The connecting role lacks USAGE on the warehouse named in the warehouse field, or the warehouse is suspended and the role cannot resume it. Grant USAGE (and OPERATE if auto-resume is off).
The connection is missing oauth_client_id/oauth_client_secret, or Require user authentication is off. Save the security integration’s client ID and secret on the connection credentials and enable the toggle — OAuth is then added to the allowed sign-in methods automatically.
The OAUTH_REDIRECT_URI on the security integration must exactly match https://<your-bow-host>/api/connections/oauth/callback — scheme, host, and path. Snowflake also refuses non-HTTPS redirect URIs unless the integration sets OAUTH_ALLOW_NON_TLS_REDIRECT_URI = TRUE.