返回

Snowflake External Volume 引入工作负载身份联合

RSS Snowflake Engineering (Medium) AI 逐段翻译 发布 2026-10-10 00:21
DataHot 速览

Snowflake 宣布 External Volumes 的工作负载身份联合(WIF)进入 Private Preview。WIF 用短时、联合身份替代存储凭证,为每个 external volume 使用唯一身份,不再依赖共享的 Snowflake 托管 IAM principal。访问云存储时,Snowflake 签署短时身份令牌,云厂商验证后授予仅限授权存储位置的临时凭证。该方案旨在提供更清晰的信任边界、隔离性、控制力与可审计性。

为什么值得关注:Snowflake 官方发布的数据平台存储访问安全机制更新,涉及 external volume、云存储、IAM 与审计,对数据平台架构和安全治理从业者有直接参考价值。

本文目录 20 节
  1. 为什么这很重要
  2. WIF 带来了哪些变化
  3. 为什么您(我们的客户)应该感到兴奋
  4. 更强的安全性,相同的用户体验
  5. 工作原理
  6. 分步设置(AWS)
  7. 先决条件
  8. 步骤 1:创建 S3 存储桶
  9. 步骤 2:在 AWS 中注册 IAM OIDC 提供商
  10. 步骤 3:创建 IAM 角色和策略
  11. 第 4 步:在 Snowflake 中创建 WIF 外部卷
  12. 第 5 步:使用主体更新信任策略
  13. 第 6 步:在 Snowflake 中验证外部卷
  14. 用例:为什么这对 Iceberg 很重要
  15. 1. Snowflake 管理的 Iceberg 表
  16. 2. 数据湖仓架构
  17. 3. 外部管理的 Iceberg 表
  18. 当前限制
  19. 总结
  20. 清理

译文

AI 逐段翻译

随着各组织采用开放且可互操作的数据架构,它们也在重新思考数据平台如何访问云存储。这种访问模型仅仅能正常工作已经不够了——它还需要在安全性、控制力和可审计性方面达到更高的标准。

这就是工作负载身份联合(WIF)用于外部卷背后的理念,现已进入私人预览阶段。WIF 为 Snowflake 客户提供了一种更现代的方式,通过使用短期、联合身份而非存储的凭据来连接云存储。

主要贡献者:

Bonny Mahajan,Snowflake 产品经理

James Sun,Snowflake 高级合作伙伴解决方案工程师

Bosco Albuquerque,AWS 高级合作伙伴解决方案架构师

为什么这很重要

许多客户正在构建专为开放性和互操作性而设计的架构。随着这些环境规模扩大,更多关键数据存放在客户管理的云存储中,而用于访问这些数据的路径也成为安全态势的一部分。

客户希望在谁能或什么能访问每个存储位置方面建立更强的边界。他们希望获得更严格的控制、更清晰的隔离,以及一种更符合不断演进的企业安全期望的访问模型。

WIF 带来了哪些变化

传统上,存储访问依赖于共享信任模型。在这种方法下,一个共享的 Snowflake 管理的 IAM 主体会对您指定的角色执行 sts:AssumeRole,依赖信任策略中的外部 ID 来缓解混淆代理风险。虽然这种模型使用临时的 AWS STS 凭据,但它依赖于一个共享的 Snowflake 主体。该模型经过验证,但它可能更难在存储位置和用例之间实现清晰的分离。

WIF 用短期、联合身份取代了这种方法。Snowflake 不再通过共享主体路由访问,而是为每个外部卷使用唯一身份。当 Snowflake 需要访问您的云存储时,它会签署一个短期身份令牌,您的云提供商对其进行验证,然后 Snowflake 收到仅限定于您授权存储位置的临时凭据。

结果是内置了更严格边界的更清晰信任模型。

WIF 还可以用于与 S3 的 Snowflake 存储集成,以扩展对其他数据湖数据格式和用例的能力。请参阅此博客了解更多信息。

为什么您(我们的客户)应该感到兴奋

WIF 让客户对存储访问的定义和治理方式拥有更多控制权。

  • 每个外部卷获得自己的身份,在角色的信任策略中限定范围以实现隔离
  • 跨团队、域和存储位置的访问可以更清晰地隔离
  • 一个新卷无法假定另一个卷的角色,并能够使用信任策略进行固定
  • 在客户自己的云环境中,访问更容易审查、撤销和审计
  • 客户保持对自己存储权限和最小权限设计的控制

对于注重安全的组织来说,这是一个有意义的转变。它降低了广泛共享访问带来的风险,并使安全边界更加明确。

更强的安全性,相同的用户体验

WIF 最大的好处之一是它在不改变最终用户体验的情况下改进了安全模型。客户在其云环境中建立一次性信任关系,运行时 Snowflake 获取短期凭据,仅访问已授权的数据。

换句话说,客户获得了更强的治理、更强的隔离以及更现代的访问模型——而不会给使用 Snowflake 的人员增加摩擦。

工作原理

以下是每次 Snowflake 通过启用 WIF 的外部卷访问 S3 时发生的情况:

  1. Snowflake 为外部卷签发一个短期、签名的 OIDC 身份令牌——Iceberg 表操作会触发此操作(INSERT、SELECT、MERGE 等)。
  2. Snowflake 调用 AWS 安全令牌服务(STS),出示该令牌
  3. AWS STS 验证该令牌
  4. AWS STS 返回 IAM 角色的临时会话凭据
  5. Snowflake 使用有时限的凭据读取/写入 S3
  6. 结果返回给用户

这用 OIDC 令牌声明(aud、sub)取代了 IAM 主体加外部 ID 的信任。这提供了可限定到单个卷的混淆代理保护,您不再需要交换 IAM 用户 ARN 和外部 ID。

分步设置(AWS)

先决条件

  • 具有 IAM 管理员权限的 AWS 账户
  • 用于 Snowflake Iceberg 数据的 S3 存储桶
  • 已启用 WIF 私人预览的 Snowflake 账户
  • ACCOUNTADMIN 角色(或 CREATE EXTERNAL VOLUME 权限)

重要提示:用于外部卷的 WIF 目前处于私人预览阶段。在您能够使用 AUTH_TYPE = ‘WORKLOAD_IDENTITY_FEDERATION’ 之前,您的 Snowflake 账户必须为此功能启用。请联系您的客户团队申请访问权限。

步骤 1:创建 S3 存储桶

创建一个或多个 S3 存储桶(或使用现有存储桶)来存储您的 Iceberg 表数据。外部卷需要写入权限,因为 Snowflake 管理完整的 Iceberg 表生命周期。

通过 AWS CLI 的示例:

aws s3 mb s3://my-iceberg-bucket --region us-west-2

步骤 2:在 AWS 中注册 IAM OIDC 提供商

要获取您 Snowflake 账户的 OIDC 颁发者 URL,请使用系统函数:

SELECT SYSTEM$GET_WORKLOAD_IDENTITY_ISSUER_URL();

示例输出:https://identity.snowflake.com/oauth2/3130xxxx/3130xxxx/56504238333xxxx

现在,您可以在 AWS 账户中将 Snowflake 的颁发者注册为 OIDC 提供商。

在 AWS 管理控制台中: IAM → 身份提供商 → 添加提供商

  • 提供商类型:OpenID Connect
  • 提供商 URL:颁发者 URL(来自上述步骤)
  • 受众:sts.amazonaws.com

或通过 AWS CLI:

aws iam create-open-id-connect-provider \   
--url "https://identity.snowflake.com/oauth2/..." \   
--client-id-list "sts.amazonaws.com"

注意:每个 Snowflake 账户只需一个 OIDC 提供商,无论您创建多少个外部卷或存储集成。

步骤 3:创建 IAM 角色和策略

创建一个具有Web 身份信任策略的角色:

{
 "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"
     }
   }
 }]
}

注意:此初始信任策略仅检查aud(受众)声明,这意味着您 Snowflake 账户中的任何 WIF 外部卷都可以假定此角色。sub(主体)值唯一标识特定外部卷,它是在步骤 4 中创建卷后生成的。您应该使用sub在生产环境中使用该卷之前,请先完成第 5 步中的条件。

现在附加一个 S3 权限策略,授予 Snowflake 进行 Iceberg 表管理所需的访问权限:

{
 "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>/*"]
       }
     }
   }
 ]
}

或通过 AWS CLI:

# Create the role with the trust policy
aws iam create-role \
 --role-name my-iceberg-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-iceberg-role \
 --policy-name iceberg-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>/*"]
         }
       }
     }
   ]
 }'

第 4 步:在 Snowflake 中创建 WIF 外部卷

使用以下命令创建外部卷 CREATE EXTERNAL VOLUME。在外部卷上设置 AUTH_TYPE = ‘WORKLOAD_IDENTITY_FEDERATION’,并在每个 S3 存储位置上设置 STORAGE_AWS_ROLE_ARN,使用上面第 3 步中的角色 ARN。

CREATE EXTERNAL VOLUME my_s3_wif_ev
  STORAGE_LOCATIONS =
    (
      (
        NAME = 's3-loc-1'
        STORAGE_PROVIDER = 'S3'
        STORAGE_BASE_URL = 's3://my-iceberg-bucket/'
        STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/my-iceberg-role'
      )
    )
ALLOW_WRITES = TRUE 
AUTH_TYPE = 'WORKLOAD_IDENTITY_FEDERATION';

这里的关键区别是 AUTH_TYPE = ‘WORKLOAD_IDENTITY_FEDERATION’。这会告诉 Snowflake 使用 OIDC 而不是传统的 IAM 用户方式。请注意,AUTH_TYPE 在创建卷时设置,之后无法更改。

第 5 步:使用主体更新信任策略

此步骤通过添加主体条件来完成您在第 3 步中创建的信任策略。如果没有它,您 Snowflake 账户中的任何 WIF 外部卷都可以担任此 IAM 角色——这直接破坏了 WIF 旨在提供的按卷隔离。

创建后,DESCRIBE EXTERNAL VOLUME 会显示自动生成的主体:

DESCRIBE EXTERNAL VOLUME my_s3_wif_ev;

查找 WORKLOAD_IDENTITY_FEDERATION_SUBJECT 属性:

WORKLOAD_IDENTITY_FEDERATION_SUBJECT = identity_external_volume_<UPPERCASE_HEX>

如果您是通过 AWS 控制台在 第 3 步中创建该角色,AWS 已经为您填充了该角色的信任策略:它信任您的身份提供者(Federated 主体),并将 aud 声明限制为您在那里选择的受众。您无需重建任何这些内容。唯一缺少的是一个同时限制 sub 声明的条件,以便只有此外部卷(而不是您账户的颁发者签署的每一个身份)才能担任该角色。

  1. 在 IAM 控制面板中,打开您创建的角色,选择 信任关系,然后选择 编辑信任策略。
  2. 在现有的 Condition > StringEquals 块中,添加一个新的键,其提供者主机和路径前缀与已存在的 aud 键相同,但以 :sub 结尾,而不是 :aud。请从现有键中复制该前缀,而不要从头输入。将新键的值设置为上面的 WORKLOAD_IDENTITY_FEDERATION_SUBJECT 值。重要提示:主体中的十六进制部分是大写的,而 IAM StringEquals 比较区分大小写。请直接从 DESCRIBE EXTERNAL VOLUME 输出中复制粘贴该值,而不要重新输入——小写的副本将无法通过验证。

添加后,信任策略如下所示。Principal 和 aud 条件是 AWS 在第 2 步中自动生成的;sub 条件是您添加的那一行:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<aws_account_id>:oidc-provider/<issuer_host_and_path>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "<issuer_host_and_path>:aud": "sts.amazonaws.com",
          "<issuer_host_and_path>:sub": "<workload_identity_federation_subject>"
        }
      }
    }
  ]
}

其中:

  • <aws_account_id> 和 aud 键上的 <issuer_host_and_path> 前缀已在第 3 步中填写。
  • <workload_identity_federation_subject> 是来自 上面的主体值,例如 identity_external_volume_9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08。

或通过 AWS CLI:

aws iam update-assume-role-policy \
 --role-name my-iceberg-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_volume_<hex>"
       }
     }
   }]
 }'

第 6 步:在 Snowflake 中验证外部卷

SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('my_s3_wif_ev');

如果验证失败,并出现来自 AWS 的令牌交换或权限错误,请检查以下各项:

  • 信任策略中的 sub 条件与 WORKLOAD_IDENTITY_FEDERATION_SUBJECT 值完全匹配,包括 identity_external_volume_ 前缀和大写的十六进制字符。IAM StringEquals 区分大小写,因此小写的主体将失败并显示同样的通用配置错误,且不表示大小写是原因。
  • aud 条件、身份提供者上的受众以及 Snowflake 为此存储位置发送的受众全部匹配。除非该位置设置了 WORKLOAD_IDENTITY_FEDERATION_AUDIENCE,否则 Snowflake 会发送 sts.amazonaws.com。
  • 身份提供者上的提供者 URL 与来自获取 Snowflake 颁发者 URL的颁发者 URL 匹配。
  • 该角色的权限策略授予对 STORAGE_BASE_URL 中桶路径的访问权限。

如果您收到访问被拒绝错误,请等待一两分钟再试。AWS OIDC 提供者传播最多可能需要 60 秒。

您现在可以将该外部卷用于 Snowflake 管理的 Iceberg 表。当无法使用来自外部目录的 Iceberg 目录凭证分发来获取对 S3 存储的访问权限时,这些步骤也可用于此类场景。

用例:为什么这对 Iceberg 很重要

组织越来越多地采用 Apache Iceberg 作为其数据湖仓的开放表格式。数据保留在客户自己的 S3 桶中,这意味着存储访问路径的安全性至关重要。WIF 通过允许客户为每个外部卷创建单独的联合身份和 IAM 边界,改变了这一局面。

1. Snowflake 管理的 Iceberg 表

WIF 外部卷的主要用例是 Snowflake 管理的 Iceberg 表。Snowflake 处理完整的表生命周期——写入、压缩、快照管理和元数据——同时数据以开放 Parquet 格式保留在客户的 S3 桶中。

每个卷映射到自己的 IAM 角色和 S3 桶或前缀——通过 OIDC 主体条件在 IAM 层强制执行。

2. 数据湖仓架构

对于构建数据湖仓的客户,WIF 外部卷支持一种模式,其中不同区域(原始、精选、发布)各自拥有自己的卷,并具有单独的 IAM 边界。

每个区域都有自己的 IAM 角色、信任边界和 S3 权限。

3. 外部管理的 Iceberg 表

在某些情况下,另一个目录将管理存储在 S3 上的 Iceberg 表。如果这些目录不支持凭证分发来为 Snowflake 提供对 S3 存储的访问权限,则可以使用带 WIF 的外部卷。

同样,每个卷映射到自己的 IAM 角色和 S3 桶或前缀——通过 OIDC 主体条件在 IAM 层强制执行。

当前限制

此功能处于私有预览阶段,需要您的 Snowflake 账户团队启用账户。关键注意事项:

  • AUTH_TYPE 在创建卷时设置,之后无法更改。
  • STORAGE_AWS_ROLE_ARN 无法就地更改。要轮换角色,请添加新的存储位置并移除旧位置。

总结

外部卷的 Workload Identity Federation 使 Snowflake 的 Iceberg 存储访问模型与现代零信任原则保持一致。短时效、经加密签名的 OIDC 令牌以按卷的联合身份取代了共享主体模型。安全态势更强,因为每个外部卷都使用其自身作用域内的身份和短时效 OIDC 令牌运行,从而更易于在卷级别进行审计和撤销访问。

如果你已经在 AWS 中为其他服务管理 OIDC 提供程序,那么将 Snowflake 外部卷添加到该信任模型中是顺理成章的。结合 Apache Iceberg 的开放格式,WIF 为客户提供了所需的安全隔离,同时保持与更广泛的数据湖仓生态系统的完全互操作性。

清理

如果你跟着操作并想要移除这些资源:

Snowflake

DROP EXTERNAL VOLUME IF EXISTS my_s3_wif_ev;

AWS

# AWS - delete the IAM policy, then the role 
aws iam delete-role-policy --role-name my-iceberg-role --policy-name iceberg-s3-access aws iam delete-role --role-name my-iceberg-role 


# Keep the OIDC provider if you plan to create more WIF volumes or 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/…

注意:删除并重新创建外部卷会生成新的 subject,即使卷名相同也是如此。在任何重新创建后,你必须使用新的 subject 值更新 IAM 信任策略。

此功能目前处于 Private Preview 阶段。请联系你的 Snowflake 客户团队以申请访问权限。

使用 Workload Identity Federation 实现外部卷访问的现代化 最初发表于 Snowflake Builders Blog: Data Engineers, App Developers, AI, & Data Science 在 Medium 上,人们通过高亮并回应此故事来继续对话。

这篇内容对你有用吗?

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

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