Configure private connectivity to storage for catalog-vended credentials

When you use catalog-vended credentials for Apache Iceberg™ tables, Snowflake accesses your cloud storage using temporary credentials provided by the catalog. By default, this storage traffic traverses the public internet. For increased security, you can configure private connectivity so that Snowflake accesses your storage through a private endpoint instead.

The following diagram shows how Snowflake reads data from cloud storage using catalog-vended credentials.

How Iceberg tables that use a catalog integration work with vended credentials. Snowflake sends metadata requests to the external catalog, receives vended credentials, and reads data files from cloud storage.

Three network paths are involved in this architecture:

  • Snowflake to catalog: Snowflake sends metadata requests to the external catalog. You can configure this path to use private connectivity. See Step 4.
  • Catalog to storage: The catalog reads metadata from cloud storage. You configure this on the catalog side. See Step 1.
  • Snowflake to storage: Snowflake reads data and metadata files from cloud storage using vended credentials. You enable this by setting USE_PRIVATELINK_ENDPOINT = TRUE in the DEFAULT_STORAGE_CONFIG parameter of your catalog integration. This is the primary focus of this guide.

Note

If you use an external volume instead of vended credentials, outbound private connectivity to storage is already supported. See Private connectivity for outbound network traffic.

For general information about outbound private connectivity in Snowflake, including outbound private connectivity costs, see Private connectivity for outbound network traffic.

Considerations and limitations

  • Private connectivity to storage with vended credentials is supported on AWS (using AWS PrivateLink) and Azure (using Azure Private Link). Google Cloud Platform (GCP) isn’t supported.
  • AWS Glue Data Catalog isn’t supported because Glue doesn’t support outbound private connectivity to storage.
  • On AWS, your Snowflake account and storage buckets must be in the same region.
  • This feature is supported for catalog integrations with CATALOG_SOURCE = ICEBERG_REST or CATALOG_SOURCE = POLARIS. POLARIS can refer to Snowflake Open Catalog or a self-hosted Polaris catalog.

Step 1: Set up private storage access on the catalog side

Before you block public access to your storage, ensure that your catalog server can access storage through private connectivity. This step is your responsibility to configure on the catalog side. The specific steps depend on your catalog vendor.

If your catalog is self-hosted or provided by a vendor that complies with the Apache Iceberg REST catalog specification, you’re responsible for configuring private connectivity from your catalog to your storage. The setup depends on your deployment environment and cloud provider.

Step 2: Block public access to your storage

After your catalog has private access to storage (Step 1), restrict your storage so that only authorized private traffic is allowed.

Configure an S3 bucket policy that denies access except from approved VPC endpoints and VPCs. Use the StringNotEqualsIfExists condition with both aws:SourceVpce and aws:SourceVpc keys to allowlist multiple sources. This NOR logic ensures that a request is denied only if it doesn’t come from any of the listed VPC endpoints or VPCs.

In the bucket policy, include:

  • Your catalog’s VPC endpoint IDs or VPC IDs (see Step 3 for catalog-specific details).
  • Snowflake’s VPC endpoint IDs, which you obtain later in Step 6. You can add them to the policy later.

The following example shows a bucket policy that allowlists both VPC endpoints (aws:SourceVpce) and VPCs (aws:SourceVpc):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyIfNotFromApprovedVpcsOrVpces",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::<your-bucket-name>",
        "arn:aws:s3:::<your-bucket-name>/*"
      ],
      "Condition": {
        "StringNotEqualsIfExists": {
          "aws:SourceVpce": [
            "<snowflake-vpce-id>",
            "<additional-vpce-ids>"
          ],
          "aws:SourceVpc": [
            "<catalog-vpc-id-1>",
            "<catalog-vpc-id-2>"
          ]
        }
      }
    }
  ]
}

For more information about S3 bucket policies with VPC endpoints, see Private connectivity to external stages for Amazon Web Services and Restricting access to a specific VPC endpoint in the AWS documentation.

Step 3: Verify the catalog can still access storage

After you block public access, confirm that your catalog can still read and write data. If access is broken, update your storage access policy to allowlist the catalog’s network identity.

Verify that your catalog can still read and write data to storage after the firewall changes. The verification method depends on your catalog deployment.

For full end-to-end private connectivity, configure the connection from Snowflake to the catalog’s API endpoint over PrivateLink. This covers the metadata path from Snowflake to the catalog server.

For complete instructions, see Configure an Apache Iceberg™ REST catalog integration with outbound private connectivity.

The key steps are:

  1. Gather private connectivity information for your catalog (endpoint service ID, host name, and similar details).
  2. Provision a private connectivity endpoint for the catalog server in Snowflake using SYSTEM$PROVISION_PRIVATELINK_ENDPOINT.
  3. Verify the endpoint status using SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO.
  4. Complete any catalog-side approval (for example, register the VPC endpoint in Databricks or approve the private endpoint in the Azure portal).
  5. Use CATALOG_API_TYPE = PRIVATE when creating or altering the catalog integration.

Note

This step is independent of the storage private connectivity configuration in Step 5 through Step 9. You can configure catalog-server private connectivity, storage private connectivity, or both.

Step 5: Provision a private connectivity endpoint for storage

Call the SYSTEM$PROVISION_PRIVATELINK_ENDPOINT system function to provision a private connectivity endpoint for S3:

USE ROLE ACCOUNTADMIN;

SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
  'com.amazonaws.<region>.s3',
  '*.<region>.s3.amazonaws.com'
);

Replace <region> with your AWS region (for example, us-west-2).

One endpoint covers all S3 buckets in the same region. The wildcard (*) doesn’t mean all S3 buckets are accessed over a private connection. Only buckets used by catalog integrations configured with USE_PRIVATELINK_ENDPOINT = TRUE in the DEFAULT_STORAGE_CONFIG parameter are accessed through the VPC endpoint.

Step 6: Allowlist Snowflake’s access on the storage side

After you provision the endpoint, allowlist Snowflake’s private endpoint on the storage side so that your storage accepts traffic from Snowflake.

  1. In Snowflake, call the SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO system function to get the VPC endpoint ID for Snowflake:

    SELECT SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO();

    Copy the value for snowflake_endpoint_name from the response (for example, vpce-01c31eb5f4a1e817d).

  2. In AWS, add this VPC endpoint ID to the aws:SourceVpce list in the S3 bucket policy that you configured in Step 2.

    For more information about configuring a bucket policy for private connectivity, see Private connectivity to external stages for Amazon Web Services.

Step 7: Verify the endpoint status

Call the SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO system function to verify the endpoint status:

SELECT SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO();

The endpoint is ready to use when the status changes from pending to available.

You can continue with the next steps while waiting for the endpoint to be ready.

Step 8: Configure the catalog integration

Configure a catalog integration with USE_PRIVATELINK_ENDPOINT = TRUE in the DEFAULT_STORAGE_CONFIG parameter to enable private connectivity for storage access with vended credentials.

This example applies to any catalog that complies with the Apache Iceberg REST catalog specification, whether self-hosted or provided by a catalog vendor.

Create a new catalog integration:

CREATE OR REPLACE CATALOG INTEGRATION rest_catalog_int_vended_creds_pl
  CATALOG_SOURCE = ICEBERG_REST
  TABLE_FORMAT = ICEBERG
  REST_CONFIG = (
    CATALOG_URI = '<rest_api_endpoint_url>'
    CATALOG_API_TYPE = PRIVATE
    CATALOG_NAME = '<catalog_name>'
    ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS
  )
  REST_AUTHENTICATION = (
    TYPE = OAUTH
    OAUTH_TOKEN_URI = '<token_server_uri>'
    OAUTH_CLIENT_ID = '<oauth_client_id>'
    OAUTH_CLIENT_SECRET = '<oauth_client_secret>'
    OAUTH_ALLOWED_SCOPES = ('all-apis', 'sql')
  )
  DEFAULT_STORAGE_CONFIG = (
    USE_PRIVATELINK_ENDPOINT = TRUE
  )
  ENABLED = TRUE;

Note

If you didn’t configure private connectivity to the catalog server in Step 4, omit CATALOG_API_TYPE = PRIVATE from the REST_CONFIG parameters.

Enable private storage access for an existing catalog integration:

ALTER CATALOG INTEGRATION <name>
  SET DEFAULT_STORAGE_CONFIG = (USE_PRIVATELINK_ENDPOINT = TRUE);

Step 9: Create Iceberg tables

After you configure the catalog integration, you can create Iceberg tables or a catalog-linked database. Snowflake uses the vended credentials from the catalog and accesses storage through the private connectivity endpoint.

Create an Iceberg table:

Don’t specify an EXTERNAL_VOLUME parameter when you use vended credentials.

CREATE ICEBERG TABLE my_iceberg_table
  CATALOG = '<catalog_integration_name>'
  CATALOG_TABLE_NAME = 'my_table'
  AUTO_REFRESH = TRUE;

Create a catalog-linked database:

You can also create a catalog-linked database to automatically discover and sync multiple Iceberg tables from your external catalog.

CREATE DATABASE my_catalog_linked_db
  LINKED_CATALOG = (
    CATALOG = '<catalog_integration_name>'
  );

For more information, see CREATE DATABASE (catalog-linked).

Next steps

Monitor your private connectivity endpoints