返回
RSS Snowflake Engineering (Medium) 原文 · 未翻译 精选 发布 2026-09-03 06:38

Snowflake 用 Workload Identity Federation 强化 S3 存储集成隔离

DataHot 速览

Snowflake 推出基于 OIDC 的 Workload Identity Federation(WIF),目前处于 Private Preview,用于连接 Amazon S3。WIF 为每个存储集成提供独立的联合身份,取代传统单一 AWS IAM 角色共享模型。该机制旨在改善最小权限隔离、降低跨集成越权风险,并增强云审计可观测性与细粒度撤销能力。

为什么值得关注:数据平台安全隔离与细粒度权限管理是平台工程的关键问题,WIF 提供了一种不改变用户 SQL 工作流的强化方案,值得数据平台负责人关注。

本文目录 22 节
  1. Introduction
  2. The Challenge with Traditional Storage Integrations
  3. WIF: OIDC-Based Authentication
  4. How It Works
  5. Benefits: WIF vs Traditional
  6. Step-by-Step Setup (AWS)
  7. Prerequisites
  8. Step 1: Get Snowflake’s OIDC Issuer URL
  9. Step 2: Register the OIDC Provider in AWS
  10. Step 3: Create an IAM Role
  11. Step 4: Create the Storage Integration in Snowflake
  12. Step 5: Update the Trust Policy with the Subject
  13. Step 6: Create a Stage and Verify
  14. Use Cases: Why This Matters Now
  15. 1. AI Document Processing (Unstructured Data on S3)
  16. 2. Cortex Search & RAG (AI Agents over S3 Data)
  17. 3. Data Loading & Ingestion
  18. 4. Data Unloading & Export
  19. 5. External Tables & Data Lake Query
  20. Current Limitations
  21. Summary
  22. Cleanup

原文

Snowflake storage integrations with Amazon S3 is used by many customers for a wide variety of use cases. Learn how to strengthen per-integration isolation between Snowflake and Amazon S3 using Workload Identity Federation (WIF) — a new simplified OIDC-based authentication model for storage integrations.

Key Contributors:

Bonny Mahajan, Product Manager, Snowflake

Andries Engelbrecht, Principal Partner Solution Engineer, Snowflake

Doug Mbaya, Senior Partner Solutions Architect, AWS

Introduction

Are you a security-conscious customer trying to isolate storage access by workload, data domain, or tenant? WIF gives each storage integration its own federated identity, so you can strengthen those boundaries without changing how users work with Snowflake stages and SQL.

The Challenge with Traditional Storage Integrations

The traditional model uses a single AWS Identity and Access Management (IAM) role shared across all storage integrations in a Snowflake account. While this uses temporary credentials via AssumeRole, the shared principal can make it harder to enforce per-integration boundaries:

Least privilege: A finance integration and a marketing integration may need completely different access, but the shared identity can make those boundaries harder to enforce.

Isolation: A new integration can benefit from permissions already granted to the shared identity, without a new cloud-side authorization checkpoint. This creates the risk that one integration can access a location approved for another.

Observability: Cloud audit records attribute activity to the same principal, making it harder to understand which storage integration was responsible for an action.

Compliance: Security teams increasingly require short-lived credentials, explicit authorization boundaries, and the ability to revoke access at a more granular level.

WIF: OIDC-Based Authentication

Workload Identity Federation (WIF), currently in Private Preview, gives customers a different way to connect Snowflake to S3.

With WIF, Snowflake acts as an OpenID Connect (OIDC) workload identity provider. Instead of routing all integrations through a single IAM role, Snowflake issues a signed identity token scoped to each storage integration, Snowflake issues a signed identity token. AWS validates that token and returns temporary credentials for the IAM role the customer has configured.

The identity is scoped to the storage integration:

  • The issuer identifies the customer’s Snowflake account.
  • The subject identifies a specific storage integration within that account.
  • The IAM role defines which S3 buckets and prefixes that integration can access.

This gives customers a practical way to create separate trust boundaries for separate workloads. For example, an organization can bind one integration to a finance bucket and another to a marketing bucket, without granting both integrations access through one shared cloud principal.

WIF also preserves the customer experience people already have with Snowflake stages. The trust configuration changes on the cloud side, but customers continue to use stages, COPY INTO, directory tables, external tables, and other storage workflows in the same way.

How It Works

Here is what happens each time Snowflake accesses S3 through a WIF-enabled storage integration:

  1. Request signed JWT — A stage operation triggers (LIST, COPY INTO, SELECT FROM @stage). Snowflake’s internal OIDC provider prepares a token request.
  2. Signed JWT returned — The OIDC provider generates a signed JWT containing iss (issuer URL unique to your account), sub (subject unique to the storage integration), and aud (sts.amazonaws.com). The token is returned to the Snowflake engine.
  3. AssumeRoleWithWebIdentity — Snowflake sends the JWT to AWS Security Token Service (AWS STS) along with the IAM role ARN, calling AssumeRoleWithWebIdentity.
  4. Fetch JWKS + validate — AWS STS fetches Snowflake’s public signing keys from the JWKS endpoint and verifies the JWT signature. It checks that iss, sub, and aud claims match the IAM role's trust policy conditions.
  5. Public keys returned — Snowflake’s JWKS endpoint returns the public keys used to verify the token signature.
  6. Temporary credentials issued — After validation, STS returns an AccessKeyId, SecretAccessKey, and SessionToken scoped to the IAM role's permissions.
  7. GET/PUT objects — Snowflake uses the temporary credentials to perform the actual S3 operations (GetObject, PutObject, ListBucket, DeleteObject).
  8. Data returned — S3 returns the requested data (or confirms the write). When credentials expire, the next request repeats the cycle automatically.

This replaces the external-ID-based trust model with OIDC subject claims, providing equivalent confused-deputy protection while simplifying the initial setup.

Benefits: WIF vs Traditional

The value of WIF is not simply that it uses OIDC. It gives customers more control over how storage access is separated, reviewed, and governed.

For customers running multi-tenant platforms or managing separate business data domains, the difference is meaningful. A new integration can no longer inherit access simply because another integration caused the shared principal to receive that permission. The cloud-side IAM policy becomes an explicit authorization checkpoint again.

WIF also addresses a common compliance concern: access that is static, broad, and difficult to attribute. Customers can revoke or change the IAM role and its permissions in their own cloud environment, while Snowflake uses short-lived credentials at runtime.

Step-by-Step Setup (AWS)

Prerequisites

  • AWS account with IAM admin permissions
  • S3 bucket for Snowflake to access
  • Snowflake account with WIF Private Preview enabled
  • ACCOUNTADMIN role (or CREATE INTEGRATION privilege)
Important: WIF for storage integrations is currently in Private Preview. Your Snowflake account must be enabled for this feature before you can use AUTH_TYPE = WORKLOAD_IDENTITY_FEDERATION. Contact your account team to request access.

Step 1: Get Snowflake’s OIDC Issuer URL

SELECT SYSTEM$GET_WORKLOAD_IDENTITY_ISSUER_URL();
-- Example output: https://identity.snowflake.com/oauth2/3130xxxx/3130xxxx/56504238333xxxx

Step 2: Register the OIDC Provider in AWS

In the AWS Management Console: IAM → Identity providers → Add provider

  • Provider type: OpenID Connect
  • Provider URL: the issuer URL from Step 1
  • Audience: sts.amazonaws.com

Or via CLI:

aws iam create-open-id-connect-provider \
  --url "https://identity.snowflake.com/oauth2/..." \
  --client-id-list "sts.amazonaws.com" \
  --thumbprint-list "0000000000000000000000000000000000000000"
The thumbprint value is a placeholder — AWS no longer validates OIDC provider thumbprints (since June 2023), so any 40-character hex string works.
Note: You only need one OIDC provider per Snowflake account, regardless of how many integrations you create.

Step 3: Create an IAM Role

Create a role with a web identity trust policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::<ACCOUNT>:oidc-provider/identity.snowflake.com/oauth2/..."
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "identity.snowflake.com/oauth2/...:aud": "sts.amazonaws.com"
      }
    }
  }]
}
Note: This initial trust policy only checks the aud (audience) claim, which means any storage integration in your Snowflake account could assume this role. The sub (subject) value that uniquely identifies a specific integration is generated after the integration is created in Step 4. You should update this trust policy with the sub condition in Step 5 before using the integration in production. This ensures each integration maps to exactly one IAM role — the per-integration isolation that makes WIF valuable.

Now attach an S3 permissions policy (inline or managed) granting the access Snowflake needs:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion"],
      "Resource": "arn:aws:s3:::<BUCKET>/<PATH>/*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:GetBucketLocation"],
      "Resource": "arn:aws:s3:::<BUCKET>",
      "Condition": {
        "StringLike": {
          "s3:prefix": ["<PATH>/*"]
        }
      }
    }
  ]
}

Or via the CLI:

# Create the role with the trust policy
aws iam create-role \
  --role-name my-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<ACCOUNT>:oidc-provider/identity.snowflake.com/oauth2/..."
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "identity.snowflake.com/oauth2/...:aud": "sts.amazonaws.com"
        }
      }
    }]
  }'

# Attach an inline S3 policy
aws iam put-role-policy \
  --role-name my-role \
  --policy-name s3-access \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": ["s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion"],
        "Resource": "arn:aws:s3:::<BUCKET>/<PATH>/*"
      },
      {
        "Effect": "Allow",
        "Action": ["s3:ListBucket", "s3:GetBucketLocation"],
        "Resource": "arn:aws:s3:::<BUCKET>",
        "Condition": {
          "StringLike": {
            "s3:prefix": ["<PATH>/*"]
          }
        }
      }
    ]
  }'

Step 4: Create the Storage Integration in Snowflake

CREATE OR REPLACE STORAGE INTEGRATION my_s3_wif
    TYPE = EXTERNAL_STAGE
    STORAGE_PROVIDER = 'S3'
    STORAGE_ALLOWED_LOCATIONS = ('s3://my-bucket/path/')
    STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::<ACCOUNT>:role/my-role'
    AUTH_TYPE = WORKLOAD_IDENTITY_FEDERATION
    ENABLED = TRUE;

The key difference here is AUTH_TYPE = WORKLOAD_IDENTITY_FEDERATION. This tells Snowflake to use OIDC instead of the traditional IAM user approach.

Step 5: Update the Trust Policy with the Subject

This step completes the trust policy you created in Step 3 by adding the subject condition. Without it, any storage integration in your Snowflake account could assume this IAM role — which directly undermines the per-integration isolation that WIF is designed to provide.

WIF will function without the sub condition, but we strongly recommend adding it before using the integration in production. The sub condition is what binds one IAM role to one specific integration.

After creation, DESC INTEGRATION my_s3_wif reveals the auto-generated subject:

WORKLOAD_IDENTITY_FEDERATION_SUBJECT = identity_external_stage_integration_<hex>

You should add a subject condition to the IAM trust policy for tighter security, so that each integration maps to exactly one role. You can do this by updating the role’s trust policy in the AWS Management Console (IAM → Roles → select the role → Trust relationships → Edit trust policy) or via the CLI:

aws iam update-assume-role-policy \
  --role-name my-role \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<ACCOUNT>:oidc-provider/identity.snowflake.com/oauth2/..."
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "identity.snowflake.com/oauth2/...:aud": "sts.amazonaws.com",
          "identity.snowflake.com/oauth2/...:sub": "identity_external_stage_integration_<hex>"
        }
      }
    }]
  }'

The updated condition block with both aud and sub looks like this:

"Condition": {
  "StringEquals": {
    "identity.snowflake.com/oauth2/...:aud": "sts.amazonaws.com",
    "identity.snowflake.com/oauth2/...:sub": "identity_external_stage_integration_<hex>"
  }
}

Step 6: Create a Stage and Verify

CREATE OR REPLACE STAGE my_wif_stage
    STORAGE_INTEGRATION = my_s3_wif
    URL = 's3://my-bucket/path/';

LIST @my_wif_stage;  -- Should return empty (no files) with no error

If you get an access denied error, wait a minute or two and try again. AWS OIDC provider propagation can take up to 60 seconds.

Use Cases: Why This Matters Now

Organizations have contracts, invoices, claims, images, and other unstructured data sitting in S3. The challenge is often not whether Snowflake can process those files — it is whether security and compliance teams will approve the access model. A single shared cloud identity can make it difficult to isolate repositories by business unit, tenant, or data domain, which can keep high-value workloads outside Snowflake.

WIF changes that equation. Customers can create a separate federated identity and IAM boundary for each integration — for example, one for finance documents, one for legal records, and one for a tenant-specific repository. They can then use those files for document parsing, extraction, classification, search, and RAG while keeping access scoped to the bucket and path they authorize.

This new approach is enabling customers to connect more of their data to Snowflake with the isolation and governance their security teams require.

1. AI Document Processing (Unstructured Data on S3)

Enterprises are bringing contracts, invoices, forms, and other unstructured files into Snowflake for processing. Those files often sit in business-unit or tenant-specific S3 locations with strict access requirements.

WIF lets a customer create a separate integration for each data domain and scope the IAM role to only the required bucket and prefix. The Snowflake workflow remains familiar. Here is an example to demonstrate this use case.

-- Parse PDFs on S3 into structured text with layout preservation
SELECT
    relative_path,
    AI_PARSE_DOCUMENT(
        TO_FILE('@my_wif_stage', relative_path),
        {'mode': 'LAYOUT'}
    ) AS parsed
FROM DIRECTORY(@my_wif_stage)
WHERE relative_path LIKE '%.pdf';

-- Extract structured fields from invoices
SELECT
    relative_path,
    AI_EXTRACT(
        file => TO_FILE('@my_wif_stage', relative_path),
        responseFormat => {
            'vendor_name': 'What is the vendor name?',
            'invoice_date': 'What is the invoice date?',
            'total_amount': 'What is the total amount?'
        }
    ) AS extracted
FROM DIRECTORY(@my_wif_stage)
WHERE relative_path LIKE 'invoices/%.pdf';

-- Classify documents by type
SELECT
    relative_path,
    AI_CLASSIFY(
        AI_PARSE_DOCUMENT(
            TO_FILE('@my_wif_stage', relative_path),
            {'mode': 'LAYOUT'}
        ),
        ['invoice', 'contract', 'receipt', 'resume']
    ) AS doc_type
FROM DIRECTORY(@my_wif_stage);

The value is not a new way to call AI_PARSE_DOCUMENT. It is the ability to process sensitive files without expanding a shared cloud principal’s permissions across unrelated document repositories.

2. Cortex Search & RAG (AI Agents over S3 Data)

Customers building search and RAG experiences often combine documents from multiple teams or tenants. That makes it important to keep source data separated while still giving Snowflake a consistent way to process and index it.

A WIF-enabled stage can be scoped to the source location for one knowledge base or data domain. Customers can then parse and chunk the files before indexing them in Cortex Search.

WIF secures access to the source files. Parsing, chunking, indexing, and retrieval remain the same Snowflake operations customers already use. Here is an example to demonstrate this use case.

-- Create a chunked table from S3 documents for RAG
CREATE OR REPLACE TABLE doc_chunks AS
SELECT
    relative_path AS source,
    c.value::STRING AS chunk
FROM DIRECTORY(@my_wif_stage),
    LATERAL FLATTEN(input =>
        SPLIT(
            AI_PARSE_DOCUMENT(
                TO_FILE('@my_wif_stage', relative_path),
                {'mode': 'LAYOUT'}
            ):content,
            '\n\n'
        )
    ) c
WHERE relative_path LIKE '%.pdf';

-- Create a Cortex Search Service over the chunks
CREATE OR REPLACE CORTEX SEARCH SERVICE my_knowledge_base
    ON chunk
    ATTRIBUTES source
    WAREHOUSE = my_wh
    TARGET_LAG = '1 hour'
    AS (SELECT chunk, source FROM doc_chunks);

-- Query it using SEARCH_PREVIEW
SELECT PARSE_JSON(
    SNOWFLAKE.CORTEX.SEARCH_PREVIEW(
        'my_knowledge_base',
        '{
            "query": "What is the cancellation policy?",
            "columns": ["chunk", "source"],
            "limit": 5
        }'
    )
)['results'] AS results;

3. Data Loading & Ingestion

For batch and continuous ingestion, customers want the convenience of Snowflake pipelines without broadening the shared principal’s permissions across additional storage locations.

A WIF-enabled stage can be used for common file formats, including CSV, Parquet, JSON, Avro, and ORC. Here is an example to demonstrate this use case.

-- Bulk load Parquet from S3
CREATE OR REPLACE TABLE my_table (id INT, name STRING, amount NUMBER);

COPY INTO my_table
    FROM @my_wif_stage/data/
    FILE_FORMAT = (TYPE = PARQUET)
    MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;

-- Set up Snowpipe for continuous auto-ingest
CREATE OR REPLACE TABLE my_events (event_id STRING, event_type STRING, ts TIMESTAMP);

CREATE OR REPLACE PIPE my_pipe
    AUTO_INGEST = TRUE
    AS COPY INTO my_events
    FROM @my_wif_stage/incoming/
    FILE_FORMAT = (TYPE = JSON)
    MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;

Snowpipe can continue to support continuous ingestion. WIF secures the Snowflake-to-S3 access path; the normal event-notification configuration for auto-ingest still applies.

4. Data Unloading & Export

Some customers need Snowflake to write results back to S3 for downstream applications, data lake processing, or archival. The same per-integration boundary applies to writes: the IAM role can allow access only to the export location required by that workflow. Here is an example to demonstrate this use case.

-- Export query results as Parquet to S3
COPY INTO @my_wif_stage/exports/monthly_report/
    FROM (SELECT * FROM my_table)
    FILE_FORMAT = (TYPE = PARQUET)
    HEADER = TRUE
    OVERWRITE = TRUE;

This gives teams a clearer authorization boundary for outbound data as well as inbound data.

5. External Tables & Data Lake Query

External tables let customers query supported data in S3 without first loading it into Snowflake tables. This is useful for large or infrequently accessed data sets where customers want to preserve the existing data lake layout. Here is an example to demonstrate this use case.

-- Create an external table over Parquet files on S3
-- Columns are auto-inferred from the Parquet schema
CREATE OR REPLACE EXTERNAL TABLE events_ext
    WITH LOCATION = @my_wif_stage/events/
    FILE_FORMAT = (TYPE = PARQUET);

-- Query directly (no data loaded into Snowflake)
SELECT event_type, COUNT(*)
FROM events_ext
WHERE event_date > '2026-01-01'
GROUP BY event_type
ORDER BY 2 DESC;

With WIF, the external table inherits the stage’s per-integration trust and S3 permissions. Customers can keep access to one data lake area separate from access to another.

Current Limitations

This feature is in Private Preview and requires account enablement by your Snowflake account team. For the full list of limitations and considerations, see the official documentation.

Summary

Workload Identity Federation for storage integrations brings Snowflake’s S3 access model into alignment with modern zero-trust principles. Short-lived, cryptographically signed OIDC tokens replace the shared-principal model with per-integration federated identity. The setup is streamlined: a single OIDC provider registration replaces the manual exchange of IAM role ARNs and trust policy configuration. The security posture is stronger because each integration operates with its own scoped identity and short-lived OIDC tokens, making it easier to audit and revoke access at the integration level. And it integrates naturally with existing IAM OIDC identity providers that teams already use for Kubernetes, GitHub Actions, and other federated workloads.

If you are already managing OIDC providers in AWS for other services, adding Snowflake to that trust model is a natural fit.

Cleanup

If you followed along and want to remove the resources:

-- Snowflake (use case objects)
DROP EXTERNAL TABLE IF EXISTS events_ext;
DROP PIPE IF EXISTS my_pipe;
DROP TABLE IF EXISTS my_events;
DROP TABLE IF EXISTS my_table;
DROP TABLE IF EXISTS doc_chunks;
DROP CORTEX SEARCH SERVICE IF EXISTS my_knowledge_base;

-- Snowflake (core setup)
DROP STAGE IF EXISTS my_wif_stage;
DROP INTEGRATION IF EXISTS my_s3_wif;
# AWS — delete the IAM role policy, then the role
aws iam delete-role-policy --role-name my-role --policy-name s3-access
aws iam delete-role --role-name my-role
# Note: keep the OIDC provider if you plan to create more WIF integrations
# To remove it entirely:
# aws iam delete-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::<ACCOUNT>:oidc-provider/identity.snowflake.com/oauth2/...

This feature is currently in Private Preview. Contact your Snowflake account team to request access.

Snowflake’s Secure Way to Access Unstructured and Structured Data in Amazon S3 was originally published in Snowflake Builders Blog: Data Engineers, App Developers, AI, & Data Science on Medium, where people are continuing the conversation by highlighting and responding to this story.

这篇内容对你有用吗?

反馈只用于改善内容筛选,不等同于收藏

分享这条资讯
分享海报
保存图片
iOS 也可以长按图片保存