Elements Connect

How to configure Snowflake as a datasource (using Microsoft Entra)

This guide provides step-by-step instructions to configure Snowflake as a datasource in Elements Connect for Jira Cloud, using Microsoft Entra ID (Azure AD) authentication with the OAuth 2.0 Client Credentials flow.

By setting up this integration, you'll enable secure, password-less access to your Snowflake data within your Jira issues, so you can populate connected fields directly from your data warehouse.

Three systems work together in this setup:

  1. Microsoft Entra ID issues a signed access token

  2. Snowflake trusts that token and runs your query

  3. Elements Connect obtains the token and calls Snowflake on every request.

Prerequisites

  • A Jira Cloud instance with Elements Connect installed.

  • A Snowflake account, with a user holding the ACCOUNTADMIN role (or a role able to create security integrations and users).

  • A Microsoft Entra ID tenant, with permission to create an app registration and access to an administrator who can grant tenant-wide admin consent.

Configuration steps

Part 1 - Microsoft Entra ID

1.1 - Create the app registration

  • Go to the Azure portalMicrosoft Entra IDApp registrationsNew registration

  • Give it a name (for example, Snowflake-ElementsConnect), choose Single tenant only, and leave the Redirect URI empty

  • Click Register, then from the Overview page save the Application (client) ID and the Directory (tenant) ID:

    image-20260825-075246.png

1.2 Expose an API (the token audience)

  • Go to Expose an API and click Add next to Application ID URI.

  • Accept the default value api://YOUR_CLIENT_ID and save it -> this is your Application ID URI.

  • Click Add a scope, name it default, set consent to Admins only, and add it:

    image-20260821-142637.png

1.3 Create the app role (the roles claim)

  • Go to App rolesCreate app role

  • Configure it as follows:

    • Display name: snowflake_role

    • Allowed member types: Applications (this is an app-to-app flow)

    • Value: session:role:<ROLE> (e.g. session:role:PUBLIC) -> this exact value appears in the token's roles claim and tells Snowflake which role to use.

  • Enable the role and click Apply:

    image-20260825-075811.png

1.4 Grant the app role to the application

  • Go to API permissionsAdd a permissionMy APIs, and select your own application.

  • Choose Application permissions (not Delegated), check snowflake_role, and click Add permissions.

  • Click Grant admin consent for your organization. The permission status should turn to a green Granted state:

    image-20260821-142841.png

If Grant admin consent is greyed out, ask an administrator (Global Admin, Privileged Role Admin, or Cloud Application Admin) to click on it.

1.5 Create the client secret

  • Go to Certificates & secretsNew client secret, add a description and expiry, then click Add.

  • Copy the secret's Value immediately and save it -> this is your Client secret:

    image-20260821-142941.png

1.6 Get a token and decode it

Before configuring Snowflake, confirm the token works and note the values Snowflake will need.

Run the following curl query in any terminal or command-line interface:

curl -s -X POST "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=<CLIENT_ID>" \
  -d "client_secret=<CLIENT_SECRET>" \
  -d "scope=<APP_ID_URI>/.default"

Copy the access_token from the response, paste it into jwt.ms, and note the following values:

Claim

What it is

What to check

iss

Who issued the token. The address of the Microsoft service that signed it. Snowflake uses this to know it can trust the token.

Copy it exactly. Looks like https://sts.windows.net/YOUR_TENANT_ID/ (v1) or .../v2.0 (v2).

aud

Who the token is meant for. It names the application the token was created to access. Snowflake checks this matches the app you registered.

Must equal your Application ID URI (api://YOUR_CLIENT_ID).

roles

The Snowflake role the token grants. The set of permissions the query will run with

Must contain session:role:<ROLE> (e.g. session:role:PUBLIC).

sub

Who the token represents. A unique ID for your application, like an identity card number. Snowflake uses it to match a user account.

Note this value. You will set it as the Snowflake user's LOGIN_NAME in step 2.3.

As follows:

image-20260821-143751.png

Part 2 - Snowflake

2.1 Get your account URL

  • Click your account name (bottom-left in Snowsight) → View Account Details:

    image-20260821-140051.png
  • Copy your Account/Server URL:

    image-20260821-135954.png

2.2 Create the External OAuth integration

Replace <ISSUER_FROM_TOKEN> with the iss value obtained in step 1.6:

CREATE OR REPLACE SECURITY INTEGRATION DEMO_EXTERNAL_OAUTH
  TYPE = EXTERNAL_OAUTH
  ENABLED = TRUE
  EXTERNAL_OAUTH_TYPE = AZURE
  EXTERNAL_OAUTH_ISSUER = '<ISSUER_FROM_TOKEN>'
  EXTERNAL_OAUTH_JWS_KEYS_URL = 'https://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys'
  EXTERNAL_OAUTH_AUDIENCE_LIST = ('<APP_ID_URI>')
  EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM = 'sub'
  EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE = 'login_name'
  EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE';

You can run this SQL query in a Snowsight worksheet, as shown below:

image-20260821-144024.png

2.3 Create the mapped user

Replace <SUB_FROM_TOKEN> with the sub value obtained in step 1.6:

CREATE OR REPLACE USER DEMO_SVC
  LOGIN_NAME = '<SUB_FROM_TOKEN>'
  DEFAULT_ROLE = <ROLE>;

To confirm the user was created correctly, run SHOW USERS LIKE 'DEMO_SVC';

The login_name column must exactly match the sub value from step 1.6. This is what lets Snowflake link an incoming token to this user. If they don't match, the connection will fail with a 401 error.

2.4 Grant privileges

Make sure <ROLE> can reach your existing objects (adjust names to your data). Run each of the following statements separately:

GRANT USAGE ON WAREHOUSE <YOUR_WAREHOUSE> TO ROLE PUBLIC;
GRANT USAGE ON DATABASE SALES_DB TO ROLE PUBLIC;
GRANT USAGE ON SCHEMA SALES_DB.ANALYTICS TO ROLE PUBLIC;
GRANT SELECT ON TABLE SALES_DB.ANALYTICS.customer_orders TO ROLE PUBLIC;

For a role other than PUBLIC, also run GRANT ROLE <ROLE> TO USER DEMO_SVC;

2.5 Validate the setup (optional)

To make sure the entire Snowflake configuration is correct, you can validate an actual token by running the following query:

SELECT SYSTEM$VERIFY_EXTERNAL_OAUTH_TOKEN('<PASTE_ACCESS_TOKEN>');

A Validation Result: Passed, showing your sub as the extracted user, confirms the Snowflake side is correctly configured:

image-20260821-141632.png

Part 3 - Verify the connection with a direct API call

Before configuring Elements Connect, confirm the token and Snowflake work together. This isolates any Snowflake-side issue from Elements Connect.

Tokens expire (~1 hour), so generate a new one (at step 1.6) if a test fails after some time.

Run the following curl queries in any terminal or command-line interface:

SQL
curl -X POST "<SNOWFLAKE_URL>/api/v2/statements" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "X-Snowflake-Authorization-Token-Type: OAUTH" \
  -H "Content-Type: application/json" \
  -d '{"statement":"SELECT * FROM SALES_DB.ANALYTICS.customer_orders LIMIT 10","warehouse":"<YOUR_WAREHOUSE>","role":"PUBLIC"}'

A response containing "message": "Statement executed successfully." and a data array means the entire Entra → Snowflake chain works.


Part 4 - Elements Connect

4.1 Create the REST API datasource

  • Access Elements Connect administration:

    • Click on "Apps" in the top bar menu, then select "Elements Connect".

    • Click on "Data sources" to manage your connections.

  • Create a new data source:

    • Click on "Create data source".

    • Select "REST API" as the data source type and click "Next".

    • Provide a unique name (for example, Snowflake API) and click "Create".

4.2 Configure the REST API datasource

Server Details:

  • API Base URL: <SNOWFLAKE_URL>/api/v2/

  • API Test URL: <SNOWFLAKE_URL>/api/v2/warehouses

Custom Headers:

Name

Value

Content-Type

application/json

X-Snowflake-Authorization-Token-Type

OAUTH

X-Snowflake-Role

<ROLE> (e.g. PUBLIC)

Do not add a custom Authorization header. Elements Connect adds Authorization: Bearer <token> automatically from the OAuth flow. Adding your own can result in a duplicate header, which the server may reject.

Authentication:

  • Mode: OAuth 2 — Grant type: Client credentials

  • Token URL: https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token

  • Client ID: <CLIENT_ID>

  • Client secret: <CLIENT_SECRET>

  • Credentials: Send in request body

  • Scopes: <APP_ID_URI>/.default

Click the "Test connection" button to ensure that everything is working properly.

Once the connection test is successful, save your datasource configuration. You're all set!


Going further

The Snowflake datasource allows you to populate connected fields directly from your data warehouse. Below are some use cases and example endpoints to help you make the most of the integration.

Field configuration example

Once the datasource is configured, you can create connected fields backed by SQL queries. For example, you can create a single-choice select list populated from your data warehouse.

Create a Select list (single choice) connected field and configure it as follows:

  • Query tab:

    • Data source: your Snowflake datasource

    • Method: POST

    • Path: statements

    • Request body:

      {"statement":"SELECT DISTINCT REGION FROM SALES_DB.ANALYTICS.customer_orders ORDER BY REGION","warehouse":"<YOUR_WAREHOUSE>","role":"PUBLIC"}
      
  • Filter tab:

    • Location of the Custom field options in the response/

      $.data
      
  • Display tab:

    • Template:

      ${row}
      

Then, run a test using the Configuration Tester and check that the values are returned correctly.

image-20260825-083729.png

Endpoints examples

Once your datasource is configured, you can create connected fields and retrieve various types of information from Snowflake. Here are some example API calls:

Name

Description

URL

Run a query (POST)

Execute a SQL statement and fetch its rows

YOUR_SNOWFLAKE_URL/api/v2/statements

Request body example: {"statement":"SELECT DISTINCT REGION FROM SALES_DB.ANALYTICS.customer_orders","warehouse":"YOUR_WAREHOUSE","role":"PUBLIC"}

List warehouses (GET)

List the warehouses available to the role

YOUR_SNOWFLAKE_URL/api/v2/warehouses
(add header X-Snowflake-Role: PUBLIC)

List databases (GET)

List the databases available to the role

YOUR_SNOWFLAKE_URL/api/v2/databases
(add header X-Snowflake-Role: PUBLIC)

You can find the full list of available endpoints in the Snowflake documentation here: https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference

Troubleshooting

Symptom

Where

Fix

Error while retrieving access token / invalid_client

Entra

Re-enter the client secret, and make sure Credentials is set to Send in request body (Entra rejects the secret when sent as Basic Auth).

401 Unauthorized / Invalid OAuth access token

Snowflake

The token was issued by Entra but rejected by Snowflake.

Check the following:

  • The issuer matches the token version (v1 vs v2)

  • The audience list contains your Application ID URI

  • sub matches the user's login_name

  • The token has not expired (regenerate it if in doubt).

390194 – No default role has been assigned

Snowflake

The role is not being passed. Add the X-Snowflake-Role header (for GET requests) or the "role" field in the body (for POST /statements).

Database/Warehouse does not exist or not authorized

Snowflake

Either the object does not exist, or the role lacks privileges on it. Confirm it exists (SHOW WAREHOUSES, SHOW DATABASES), then re-run the relevant GRANT statements.