Set up Snowflake External OAuth

Configure External OAuth so users in your organization can connect to Snowflake using Single Sign-On (SSO) through Microsoft Entra ID.

With MCP and Entropy Intelligence, users can execute SQL directly on data product's underlying data sources, such as Snowflake. With Snowflake External OAuth, users don't need to manage Snowflake credentials or Personal Access Tokens. Instead, they sign in with their organization's identity provider (e.g., Entra ID), and the token is used to authenticate with Snowflake.

Overview

The setup involves three systems:

  1. Microsoft Entra ID — Acts as the identity provider, issuing OAuth tokens
  2. Snowflake — Trusts the Entra ID tokens via an External OAuth security integration
  3. Entropy Data — Orchestrates the OAuth flow and uses the token to query Snowflake

Prerequisites

  • Snowflake account with ACCOUNTADMIN or SECURITYADMIN role
  • Microsoft Entra ID tenant with permissions to register applications
  • Entropy Data organization with Owner role

Official Documentation

Snowflake's External OAuth overview covers the full protocol and configuration options. The Entra ID-specific guide provides detailed steps for Azure setups.

Key points from the official documentation relevant to Entropy Data:

  • Redirect URI: The Entra ID app registration must use the Web platform flow with the redirect URI set to https://<your-entropy-data-host>/connections/snowflake/oauth2/callback. Without this, the OAuth callback from Entra ID will fail.
  • Scope pattern: Snowflake uses session:scope:<role_name> in the access token to determine which Snowflake role to activate for the session. (session:scope: is the prefix for the user-delegation flow that Entropy Data uses; the session:role: prefix applies only to the client-credentials flow where a client authenticates as itself.) The full OAuth scope must be built as the Application ID URI followed by the scope name, e.g., <app-id>/session:scope:DATAPRODUCT_USER. Role names are case-sensitiveDATAPRODUCT_USER and dataproduct_user are not the same.
  • Audience list: Set EXTERNAL_OAUTH_AUDIENCE_LIST to your Application ID URI. This must match the aud claim in the Entra ID token exactly, otherwise Snowflake will reject the token.
  • Any role mode: Set EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE' on the security integration. Without this, Snowflake only allows roles explicitly listed in the token's scope, which can cause unexpected access errors.
  • Blocked privileged roles: By default, Snowflake blocks ACCOUNTADMIN, ORGADMIN, SECURITYADMIN, and GLOBALORGADMIN from External OAuth sessions. Do not use these roles with Entropy Data — create dedicated roles like DATAPRODUCT_USER instead.
  • Network policies: Snowflake allows attaching a network policy directly to the External OAuth security integration. When set, this policy overrides any user- or account-level network policies. Consider this if your organization restricts Snowflake access by IP.
  • Other identity providers: This guide covers Microsoft Entra ID. For Okta or PingFederate, use session:role:<role_name> scopes (no Application ID URI prefix) and the username mapping claim, and see Snowflake's provider-specific guides for the issuer and key settings.

Step 1: Register an Application in Entra ID

  1. Go to Azure PortalMicrosoft Entra IDApp registrationsNew registration

  2. Set the Name (e.g., Entropy Data Snowflake)

  3. Set Redirect URI to:

    • Type: Web
    • URI: https://<your-entropy-data-host>/connections/snowflake/oauth2/callback

    The Entropy Data configuration form (Step 3) shows this exact URI in the Redirect URI field with a copy button, so you can copy it from there instead of assembling it by hand.

  4. Click Register

After registration, note down:

  • Application (client) ID
  • Directory (tenant) ID

Create a Client Secret

  1. Go to Certificates & secretsNew client secret
  2. Add a description and choose an expiration
  3. Copy the Value immediately (it won't be shown again)

Configure API Permissions (App Roles / Scopes)

  1. Go to Expose an API
  2. Set the Application ID URI if not already set (e.g., https://entropy-data.com/<app-id>)
  3. Click Add a scope:
    • Scope name: session:scope:DATAPRODUCT_USER (this maps to a Snowflake role)
    • Who can consent: Admins and users
    • Display name: Snowflake DATAPRODUCT_USER role
    • Description: Access Snowflake with the DATAPRODUCT_USER role
  4. Add additional scopes for other Snowflake roles as needed

Important: The scope name must follow the pattern session:scope:<SNOWFLAKE_ROLE>. The role name should match the Snowflake role exactly, including case.

OAuth Client vs. OAuth Resource

In OAuth terms, this setup involves two roles, both modeled as app registrations in Entra ID:

  • The OAuth client requests tokens on behalf of the user: it holds the redirect URI, the client ID, and the client secret. This role is played by Entropy Data.
  • The OAuth resource is what the token is issued for: the app registration that exposes the session:scope:... scopes under Expose an API, representing Snowflake as the protected resource. Its Application ID URI becomes the token's aud claim, which is why the same value must appear in Snowflake's EXTERNAL_OAUTH_AUDIENCE_LIST (Step 2) and as the scope prefix in the Scopes field (Step 3).

This guide uses a single app registration for both roles, which keeps the setup simple: the same app holds the redirect URI and client secret and exposes the session scopes. Snowflake's official Entra ID guide instead creates two separate app registrations (a "Snowflake OAuth resource" and an "OAuth client"). That split also works with Entropy Data: take the Client ID and Client Secret from the client app, take the Application ID URI and scopes from the resource app, and grant the client app access to the resource's scopes under API permissions.

Alternative: One session:role-any Scope Instead of One Scope per Role

Instead of defining one scope per Snowflake role, you can define a single scope named session:role-any. Snowflake then activates whatever role the user requests (subject to their grants) and also activates the user's secondary roles.

  1. Under Expose an APIAdd a scope, set the Scope name to session:role-any
  2. In the Entropy Data Scopes field (Step 3), use offline_access <application-id-uri>/session:role-any instead of the {role} pattern

This requires EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE' on the Snowflake security integration, which the SQL in Step 2 already sets.

Step 2: Create the Snowflake Security Integration

Run the following SQL in Snowflake as ACCOUNTADMIN. The Entropy Data configuration form (Step 3) generates this statement with the issuer, JWKS URL, and audience already filled in from your form values, so you can copy it from there:

CREATE OR REPLACE SECURITY INTEGRATION ENTROPYDATA_EXTERNAL_OAUTH
  TYPE = EXTERNAL_OAUTH
  ENABLED = TRUE
  EXTERNAL_OAUTH_TYPE = AZURE
  EXTERNAL_OAUTH_ISSUER = 'https://sts.windows.net/<tenant-id>/'
  EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM = 'upn'
  EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE = 'LOGIN_NAME'
  EXTERNAL_OAUTH_JWS_KEYS_URL = 'https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys'
  EXTERNAL_OAUTH_AUDIENCE_LIST = ('<application-id-uri>')
  EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE';

Replace:

  • <tenant-id> with your Entra ID tenant ID
  • <application-id-uri> with the Application ID URI from Step 1 (e.g., https://entropy-data.com/f5e3fa44-...)

Important: EXTERNAL_OAUTH_AUDIENCE_LIST must match the aud claim in the Entra ID token, which is the Application ID URI.

Configure User Mapping

Snowflake maps the upn claim from the Entra ID token to the Snowflake user's LOGIN_NAME. Ensure each Snowflake user's LOGIN_NAME matches their Entra ID UPN.

Grant Roles to Users

Users need the Snowflake role that corresponds to the scope in the token:

GRANT ROLE DATAPRODUCT_USER TO USER JOCHEN;

Step 3: Configure Entropy Data

Organization Settings

  1. Navigate to Organization SettingsIntegrations
  2. In the Data Access Configuration section, click Add ConfigurationSnowflake External OAuth
  3. Fill in the form:
FieldValueExample
NameDescriptive nameSnowflake External OAuth
Snowflake Account IdentifierYour Snowflake account identifierorgname-accountname
Snowflake Base URL (optional)Custom Snowflake base URL; leave empty to derive it from the account identifierhttps://orgname-accountname.snowflakecomputing.com
Authorization URLEntra ID authorize endpointhttps://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
Token URLEntra ID token endpointhttps://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
Client IDApplication (client) ID from Step 1
Client SecretClient secret value from Step 1
ScopesSpace-separated OAuth scopes, including offline_accessoffline_access https://<app-uri>/session:scope:{role}
Default RoleDefault Snowflake role (uppercase)DATAPRODUCT_USER

Tip: Find your account identifier in Snowsight via the account menu. Copy account identifier copies it as orgname.accountname; replace the dot with a hyphen. Alternatively, run SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME();. Case does not matter.

Important: The Scopes field is required. Always include offline_access — it is not added automatically, and without it Entra ID issues no refresh token, so users must reconnect every time the access token expires. The {role} placeholder is replaced at runtime with the user's role or the default role. When using session:role-any, set the field to offline_access <application-id-uri>/session:role-any instead.

Important: The Default Role must be uppercase to match the Snowflake role name exactly.

Entropy Data Organization Settings — Identity Provider Settings for Snowflake External OAuth

User Connection

Users can also connect directly from Entropy Intelligence when querying a Snowflake data product. A Sign in with SSO button appears automatically when External OAuth is configured.

Sign in with SSO prompt in Entropy Intelligence when querying a Snowflake data product

Once the organization configuration is in place, users can manually add an External OAuth connection to Snowflake to test the integration:

  1. Navigate to Your Datasource ConnectionsAdd
  2. Select SnowflakeExternal OAuth
  3. Select the organization's External OAuth configuration
  4. Optionally override the role and warehouse
  5. Click Save — you'll be redirected to Entra ID to sign in
  6. After sign-in, the connection is established

Your Datasource Connections page showing an active Snowflake External OAuth connection

Troubleshooting

Token validation

Use Snowflake's SYSTEM$VERIFY_EXTERNAL_OAUTH_TOKEN function to check if a token is valid. For login failure details, administrators with MONITOR privileges can call SYSTEM$GET_LOGIN_FAILURE_DETAILS with the error UUID from the Snowflake login history.

Decode the token at jwt.ms to inspect claims like aud, iss, and scp.

Error 390303: Invalid OAuth access token

The token is not trusted by Snowflake. Check:

  • EXTERNAL_OAUTH_AUDIENCE_LIST matches the aud claim in the token
  • EXTERNAL_OAUTH_ISSUER matches the iss claim in the token
  • The security integration is ENABLED = TRUE

Decode the token at jwt.ms to inspect the claims.

Error 390317: Role not listed in the Access Token

The token's scope doesn't include the requested role. Check:

  • The scope in Entropy Data includes the correct role (e.g., session:scope:DATAPRODUCT_USER)
  • The Entra ID app has the scope defined under Expose an API
  • EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE' is set on the security integration

Error 390186: Role not granted to this user

The Snowflake role exists but isn't assigned to the mapped user. Check:

  • The role is granted: GRANT ROLE <ROLE> TO USER <USERNAME>;
  • The role name case matches exactly (Snowflake roles are case-sensitive when quoted)

User mapping fails

The Entra ID upn claim doesn't map to a Snowflake user. Check:

  • The Snowflake user's LOGIN_NAME matches the upn claim: DESCRIBE USER <username>;
  • Case must match — update with ALTER USER <username> SET LOGIN_NAME = '<upn>';

Token refresh fails

Ensure:

  • The Scopes field in the Entropy Data configuration includes offline_access (it is not added automatically; the form shows a warning when it is missing)
  • The Entra ID app allows refresh tokens

Reference