Skip to content

Integrate with Snowflake

info

This feature is not enabled on accounts by default. Contact Technical Support or your Customer Success representative to enable it.

This guide explains how to integrate the Treasure AI-managed Glue HMS catalog and Iceberg tables with Snowflake using a catalog-linked database backed by the AWS Glue Iceberg REST catalog.

Overview

After provisioning Iceberg catalog resources for your Treasure AI account, you can link the Glue HMS catalog into Snowflake as a catalog-linked database. This allows you to query Treasure AI-managed Iceberg tables directly from Snowflake without copying data.

The integration uses:

  • A catalog integration that connects Snowflake to the Treasure AI catalog through the AWS Glue Iceberg REST endpoint, authenticated with the Treasure AI reader IAM role via AWS Signature Version 4 (SigV4)
  • A catalog-linked database that exposes the Treasure AI Glue database and its Iceberg tables in Snowflake

For access to the underlying table data, this guide uses catalog-vended credentials: Snowflake requests scoped, short-lived credentials from the catalog through AWS Lake Formation for each table it reads. This is the recommended method — you do not configure a Snowflake external volume or manage storage access on the Snowflake side.

Prerequisites

  • Iceberg catalog resources provisioned and active for your account (see Provision Resources)
  • A Snowflake account with privileges to create catalog integrations and databases (ACCOUNTADMIN, or a role granted CREATE INTEGRATION and CREATE DATABASE)

Authentication

For authentication details and API endpoints by site, see Use Iceberg Catalog Management API.

Required Information

Retrieve these values from the Get Resource Status endpoint:

curl "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/resources" \
  -H "Authorization: TD1 <admin_api_key>" \
  -H "Accept: application/json"
Response FieldUsed AsExample
aws_regionGlue region in CATALOG_URI and the SigV4 signing regionus-east-1
aws_account_idGlue catalog name (CATALOG_NAME)123456789012
iam_role_arnSigV4 IAM role (SIGV4_IAM_ROLE)arn:aws:iam::123456789012:role/zcpo-hms-tenant-us01_td10000
db_nameAllowed namespace in the catalog-linked database (ALLOWED_NAMESPACES)td10000_us01_export

The Glue catalog name is the AWS account ID (aws_account_id), because the default Glue catalog for an account is named after the account.

Setup

Steps 1–4 correspond to Configure a catalog integration for AWS Glue Iceberg REST, and step 5 corresponds to Create a catalog-linked database.

Step 1 (Snowflake): Create a Catalog Integration

Create a catalog integration that points at the Treasure AI Glue Iceberg REST endpoint and uses catalog-vended credentials. Follow CREATE CATALOG INTEGRATION (Apache Iceberg REST), and set ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS.

Substitute the values from the Treasure AI resource response:

CREATE CATALOG INTEGRATION my_glue_rest_integration
  CATALOG_SOURCE = ICEBERG_REST
  TABLE_FORMAT = ICEBERG
  REST_CONFIG = (
    CATALOG_URI = 'https://glue.<aws_region>.amazonaws.com/iceberg'
    CATALOG_API_TYPE = AWS_GLUE
    CATALOG_NAME = '<aws_account_id>'
    ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS
  )
  REST_AUTHENTICATION = (
    TYPE = SIGV4
    SIGV4_IAM_ROLE = '<iam_role_arn>'
    SIGV4_SIGNING_REGION = '<aws_region>'
  )
  ENABLED = TRUE;

Step 2 (Snowflake): Retrieve the IAM User and External ID

Describe the catalog integration to retrieve the AWS IAM user and external ID that Snowflake generated for it:

DESCRIBE CATALOG INTEGRATION my_glue_rest_integration
  ->> SELECT * FROM $1 WHERE "property" LIKE 'API_AWS_%';

Record the values of API_AWS_IAM_USER_ARN and API_AWS_EXTERNAL_ID. Use them in the next step.

Step 3 (Treasure AI): Update Trust Policy of IAM Role for Reading Tables

Update the trust policy of the IAM role for reading tables so Snowflake can assume it.

Call the trust policy update endpoint with service set to snowflake, the API_AWS_IAM_USER_ARN from Step 2 as iam_principal_arns, and the API_AWS_EXTERNAL_ID from Step 2 as external_id:

curl -X POST "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/resources/reader_role/trust_policy" \
  -H "Authorization: TD1 <admin_api_key>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "entries": [
      {
        "service": "snowflake",
        "iam_principal_arns": ["<API_AWS_IAM_USER_ARN>"],
        "external_id": "<API_AWS_EXTERNAL_ID>"
      }
    ]
  }'

The external ID is matched against the sts:ExternalId condition in the IAM role trust policy, so only the specified Snowflake catalog integration can assume the role. This value is generated by Snowflake and is only known after creating the integration.

Important

The catalog integration will not work until this step is completed. Poll the Get Resource Status endpoint and wait for the status to return to active before proceeding.

Step 4 (Snowflake): Verify the Catalog Integration

Confirm that Snowflake can reach the catalog and assume the reader role. Follow Check the catalog integration configuration:

SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('my_glue_rest_integration');

The integration is configured correctly when the result reports success:

{
  "success": true,
  "errorCode": "",
  "errorMessage": ""
}

If success is false, verify the IAM user ARN and external ID registered in Step 3 and that the resource status returned to active.

Step 5 (Snowflake): Create a Catalog-Linked Database

Create a catalog-linked database that exposes the Treasure AI Glue database. Follow CREATE DATABASE (catalog-linked), and set ALLOWED_NAMESPACES to the Treasure AI db_name:

CREATE DATABASE my_linked_db
  LINKED_CATALOG = (
    CATALOG = 'my_glue_rest_integration'
    ALLOWED_NAMESPACES = ('<db_name>')
    ALLOWED_WRITE_OPERATIONS = NONE
  );

Set ALLOWED_WRITE_OPERATIONS = NONE because the Treasure AI reader role is read-only.

ALLOWED_NAMESPACES accepts more than one namespace. In addition to the default export database, you can link any databases you created via the Database Management API by adding their names to the list:

CREATE DATABASE my_linked_db
  LINKED_CATALOG = (
    CATALOG = 'my_glue_rest_integration'
    ALLOWED_NAMESPACES = ('<db_name>', '<another_db_name>')
    ALLOWED_WRITE_OPERATIONS = NONE
  );

Only databases listed in ALLOWED_NAMESPACES are linked. To expose a database created later, update the catalog-linked database to include its name.

Alternatively, you can expose a database through its own catalog-linked database by running CREATE DATABASE again with a different Snowflake database name against the same catalog integration. Reuse the integration from Step 1 — you do not create a new one.

Validation

Check that Snowflake has successfully linked the catalog with SYSTEM$CATALOG_LINK_STATUS:

SELECT SYSTEM$CATALOG_LINK_STATUS('my_linked_db');

Linking is working when executionState is RUNNING and failureDetails is empty:

{ "failureDetails": [], "executionState": "RUNNING", "lastLinkAttemptStartTime": "2026-07-15T04:40:49.001Z" }

After linking completes, the Treasure AI Glue database and its Iceberg tables appear in the catalog-linked database and you can query them from Snowflake.

Troubleshooting

SymptomPossible Cause
SYSTEM$VERIFY_CATALOG_INTEGRATION returns success: falseIAM user ARN or external ID mismatch — verify the values registered in Step 3
Access denied when querying table dataVended credentials could not be issued — confirm the resource status returned to active after Step 3
SYSTEM$CATALOG_LINK_STATUS shows failureDetailsNamespace mismatch — confirm ALLOWED_NAMESPACES matches the Treasure AI db_name
Region or signing errorCATALOG_URI and SIGV4_SIGNING_REGION must both use the Treasure AI aws_region

Important Notes

  • The trust policy update in Step 3 is a full replacement. To add another integration later without dropping Snowflake, use the read-modify-write flow in Manage the Reader Role Trust Policy.
  • The reader IAM role is read-only. Snowflake can query tables but cannot modify data in the Treasure AI-managed S3 bucket, which is why ALLOWED_WRITE_OPERATIONS is set to NONE.
  • Catalog-vended credentials are the recommended access method. Configuring a Snowflake external volume is an alternative if you prefer to manage storage access on the Snowflake side, but it is not required for this integration.
  • A single catalog integration can expose the default export database and any created via the Database Management API. List them together in one catalog-linked database's ALLOWED_NAMESPACES, or give each its own catalog-linked database — both reuse the same integration (see Step 5).