Integrations

Snowflake (Native API)

Preliminary documentation.

This plugin will be available as a patch for 26.1. Check the GA (general availability) date

This page documents the integration of Anjana Data Platform with Snowflake through the tot-plugin-snowflake plugin, based on the Snowflake SQL API (REST access) and External OAuth authentication with Microsoft Entra ID. Unlike the integration via the JDBC connector (documented on the Snowflake page), this plugin operates on Snowflake's native APIs and extends the scope with access permission management. It covers three functional blocks: metadata extraction, data sampling, and permission management.

Integration model

The tot-plugin-snowflake plugin integrates with Snowflake through the Snowflake SQL API, a REST-based access mechanism that allows SQL statements to be executed via HTTP requests, without the need for a persistent JDBC connection. The user starts an operation from Anjana Data, which is sent to the plugin; the plugin first requests an access token from the identity provider (Entra ID) via OAuth2, includes it in the Authorization header, and invokes the Snowflake SQL API, which executes the query and returns the result for processing in Anjana.

Metadata extraction

The plugin discovers the objects available in Snowflake and extracts the technical information of the selected assets (tables, views, and other tabular objects). This block includes:

  • Discovery of databases and schemas.

  • Listing of available tabular objects.

  • Metadata extraction of the object and its columns.

  • Contextual metadata for database and schema.

  • Native Snowflake tags, including those inherited from ancestor assets.

The plugin extracts the following attributes, which must be named the same in the attribute_definition table, name field, for them to appear in the template:

  • catalog, with the catalog value in the database.

  • schema, with the schema value in the database.

  • physicalName and name with the same value, the table name.

  • path, with the concatenation of the catalog, schema, and table values.

  • infrastructure, technology, and zone, with the selected value.

  • tags, for tags explicitly created on the asset.

  • inheritedTags, for tags inherited from ancestor assets (Account > Database > Schema).

The following attributes related to the dataset_fields of the requested resource are also sent:

  • name and physicalName, with the field value.

  • defaultValue, default value of the field.

  • fieldDataType, data type of the field.

  • length, size of the field.

  • incrementalField, indicates whether it is an incremental field.

  • position, position occupied by the field.

  • precision, precision of the field.

  • nullable, indicates whether the field accepts null values.

  • pk, indicates whether the field is a primary key.

  • description, description of the field.

  • tags and inheritedTags, explicit and inherited tags (Account > Database > Schema > Table/View).

The attributes to be created in Anjana must have the following types:

Attribute name (name)

Attribute type (type)

catalog

INPUT_TEXT

schema

INPUT_TEXT

physicalName

INPUT_TEXT

path

INPUT_TEXT

infrastructure

SELECT

technology

SELECT

zone

SELECT

name

INPUT_TEXT

defaulValue

INPUT_TEXT

fieldDataType

INPUT_TEXT

length

INPUT_NUMBER

incrementalField

INPUT_CHECKBOX

position

INPUT_NUMBER

precision

INPUT_NUMBER

nullable

INPUT_CHECKBOX

pk

INPUT_CHECKBOX

description

ENRICHED_TEXT_AREA_INTERNATIONAL

tags

ARRAY_ALPHANUMERICAL

inheritedTags

ARRAY_ALPHANUMERICAL

The plugin is able to extract metadata from Snowflake tables, views, and materialized views.

Data sampling

The plugin allows obtaining a limited sample of records from a Snowflake object (tables, views, and materialized views) to preview and validate the content of assets governed from Anjana. Sampling is performed using SELECT queries on the object, applying a configurable row limit via the sampleRows parameter. The values of sensitive fields (pi = true) are replaced with the string defined in obfuscation-string.

Permission management

The plugin manages read permissions on Snowflake objects through a role-based model: permissions are assigned to Snowflake roles (which represent the DSA's groups), not directly to users. Management is carried out through Data Sharing Agreements (DSA) and requires the Entra ID plugin (which controls groups and users) to be deployed, and Azure SSO to be enabled. This block includes:

  • Creation or reuse of roles associated with DSAs.

  • Granting of USAGE permissions on database and schema, and SELECT on tables, views, or tabular objects contained in an approved DSA.

  • Revocation of SELECT permissions on specific objects (when objects contained in a DSA are deleted or expire)

  • Deletion of roles when applicable (when a DSA is deleted or expires).

  • Idempotent handling of repeated operations.

Snowflake SQL API

API request

The Snowflake SQL API allows SQL statements to be executed via HTTP requests: the client sends the statement in the request body and Snowflake processes the operation and returns the response. Access is performed via OAuth: the application first obtains an access token and includes it in the Authorization header of each request, avoiding the need to send user credentials. External OAuth is used, so the token is not issued by Snowflake but by the external identity provider (Entra ID), and Snowflake validates it through the configured security integration.

Role-based permission model

Snowflake's access control is based on a role-oriented model. Roles are created associated with a set of privileges on objects (databases, schemas, tables) and are subsequently assigned to users, who automatically inherit those permissions. Any change to a role's privileges affects all its users, which facilitates consistent, scalable, and traceable management. For this reason, the system's groups are modeled as Snowflake roles.

Consumption permissions on assets

Consumption permissions are the minimum privileges required to access and query an asset without administrative capabilities. To access an object, permission on the object itself is not enough: access to the database and schema containing it is also required. The scope of the plugin covers:

Level

Privilege

Database

USAGE

Schema

USAGE

Table

SELECT

View

SELECT

Materialized view

SELECT

Thus, for a tabular asset the minimum granting pattern is: USAGE on the database, USAGE on the schema, and SELECT on the table or view, granting read access without modification or administration permissions.

Required credentials

Metadata extraction and sampling

  • User or role with USAGE permissions on the database and schema where the tables/views to be governed are located.

  • User or role with REFERENCE permissions on the tables or views from which the metadata is extracted.

  • User or role with SELECT permissions on the tables or views from which data sampling is obtained.

Permission management

The plugin's technical identity must have sufficient privileges to create roles and manage grants (for example, CREATE ROLE on the account and the necessary GRANT ... WITH GRANT OPTION on database, schemas, and tables, as well as USAGE on the warehouse).

Authentication and authorization

OAuth2 with Entra ID (External OAuth)

To connect securely to Snowflake, OAuth2 with Microsoft Entra ID is used as the identity provider, which allows obtaining an access token and authenticating without a username or password. The flow used is client_credentials, suitable for server-to-server processes: an application is registered in Entra ID, a client secret is generated, and permissions are configured; in Snowflake, the corresponding security integration is created and the technical identity is associated with a role with the necessary permissions.

SQL
CREATE SECURITY INTEGRATION anjana_oauth_azure_1
    TYPE = external_oauth
    ENABLED = true
    EXTERNAL_OAUTH_TYPE = azure
    EXTERNAL_OAUTH_ISSUER = 'https://sts.windows.net/{tenant}/'
    EXTERNAL_OAUTH_AUDIENCE_LIST = ('api://{app-id}')
    EXTERNAL_OAUTH_JWS_KEYS_URL = 'https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys'
    EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM = 'sub'
    EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE = 'login_name';

Once the configuration in Entra ID and Snowflake is complete, the OAuth data is added to the plugin's application.yaml file:

YAML
oauth:
  token-url: xxxx       # Entra ID endpoint where the token is requested
  client-id: xxxx       # application registered in Entra ID
  client-secret: xxxx   # application secret
  grant-type: client_credentials
  scope: xxxx           # scope requested to obtain a token valid for Snowflake

Entra ID SCIM with Snowflake

SCIM synchronizes identities from Entra ID to Snowflake: users and groups managed in Entra ID are automatically provisioned in Snowflake, where groups are represented as roles. In Snowflake, a SCIM integration is created with its provisioning role; in Entra ID, Snowflake's Enterprise Application is configured, provisioning is enabled, and the SCIM endpoint is set along with the token generated from Snowflake.

The plugin does not call the Snowflake SCIM endpoint directly; instead, it invokes the provisioning job of the Enterprise Application in Entra ID via Microsoft Graph. The SCIM configuration is added in application.yaml:

YAML
scim:
  enabled: true  # Enables or disables the use of SCIM in the plugin
  tenant-id: xxxx   # It corresponds to the Entra ID application that allows calling Microsoft Graph
  client-id: xxxx  # It corresponds to the Entra ID application that allows calling Microsoft Graph
  client-secret: xxxx   # It corresponds to the Entra ID application that allows calling Microsoft Graph
  scope: https://graph.microsoft.com/.default
  graph-base-url: https://graph.microsoft.com/v1.0
  snowflake-app-name: Snowflake
  service-principal-id: xxxx   # Snowflake Enterprise Application
  job-id: xxxx                 # provisioning job
  user-rule-id: xxxx
  group-rule-id: xxxx          # group synchronization rule
  role-sync-max-attempts: 60
  role-sync-backoff-ms: 5000

With SCIM enabled, createGroup does not create the role in Snowflake directly: the plugin waits for the group to exist in Entra ID, triggers on-demand provisioning via Microsoft Graph, and checks that the role appears in Snowflake. In addUser, if SCIM is available, it synchronizes the user's membership in the group in Entra ID and validates that the role has been granted to the user. If SCIM is not enabled, addUser performs the GRANT ROLE directly. Deprovisioning operations do not depend on SCIM: deleteGroup executes DROP ROLE and removeUser executes REVOKE ROLE, avoiding dependence on Entra ID's asynchronous deprovisioning.

On-demand provisioning is performed against the service principal's provisioning endpoint:

POST /servicePrincipals/{servicePrincipalId}/synchronization/jobs/{jobId}/provisionOnDemand

The plugin does not consider it sufficient for Microsoft Graph to accept the request: after each attempt, it validates the actual state in Snowflake (the ultimate source of truth). For createGroup it checks that the role exists (equivalent to SHOW ROLES), and for addUser that the role has been granted to the user. If Snowflake does not yet reflect the change, it waits and retries according to role-sync-max-attempts and role-sync-backoff-ms, covering eventual consistency between Entra ID, Microsoft Graph, and Snowflake. The RedundantExport state is considered valid.

Plugin operations

The plugin implements the following operations:

Operation

Description

metadataList

Discovers and lists the available databases, schemas, and tabular objects.

metadataExtract

Extracts the detailed technical metadata of an object and its columns.

sampleData

Returns a sample of records from the object (limited by sampleRows, with obfuscation of sensitive fields).

createGroup

Creates or reuses the Snowflake role associated with the DSA (via SCIM when enabled).

removeObject

Revokes the role's permissions on a specific DSA asset.

deleteGroup

Deletes the role using DROP ROLE when the DSA expires or is deleted.

addUser

Grants the role to the user (SCIM synchronization or direct GRANT ROLE).

removeUser

Revokes the user's role using REVOKE ROLE.

Configuration

Connectivity

Connectivity is established against the Snowflake SQL API on the Snowflake account, authenticated via the OAuth2 token obtained from Entra ID. The connection, OAuth, and SCIM parameters are defined in the plugin's application.yaml file (oauth and scim blocks).

The infrastructure/technology/zone triplet selected when importing objects into Anjana must match the one configured in the plugin's application.yaml for the connection to resolve correctly.

For all plugins there are common guidelines in the Technical configuration and Tot plugin deployment sections. In addition, for each plugin there is a sample YAML that facilitates its setup, with the description of each property and its default values.