跳转到内容

Vertex AI 与工作负载身份

组件所需版本说明
CrewAI AMP早期访问版(按组织启用功能开关)联系 CrewAI 支持为你的组织启用 Workload Identity ConfigsLLM workload identity
CrewAI Python SDK (crewai)1.14.3 或更高从该版本开始构建的 crew 会包含 Vertex 工作负载身份所需的 OIDC 令牌获取和 GCP 凭据配置。
LLM 提供商Google Gen AI SDKgoogle/ 模型前缀)必需。LiteLLM 的 vertex_ai/* 提供商 支持工作负载身份。请在 LLM 连接的模型字段中使用 google/ 前缀,例如 google/gemini-2.5-progoogle/gemini-2.5-flashgoogle/gemini-2.0-flash
Google Cloud APIsiam.googleapis.com, iamcredentials.googleapis.com, sts.googleapis.com, aiplatform.googleapis.com目标项目必须启用这四个 API(参见 第 1 部分,第 1 步)。

CrewAI AMP 可以使用 GCP Workload Identity Federation 连接到 Google Vertex AI,而不是依赖长期有效的服务账号密钥。在 kickoff 时,你的 crew 执行会从 AMP 获取一个短期 OIDC 令牌,该令牌仅限于你的组织,并写入一个指向它的 Google Application Default Credentials (ADC) external_account 配置。随后,Google Gen AI SDK(通过 CrewAI 的 google/ 模型前缀调用)会透明地在 GCP STS 交换该 OIDC 令牌,必要时模拟服务账号,然后调用 Vertex AI。整个过程都在运行中的 crew 进程内完成。

结果是:

  • CrewAI AMP 中不存储任何 Google 凭据 - 没有服务账号 JSON 密钥,也没有 API 密钥。AMP 只保存它用于签发令牌的 OIDC 签名密钥。
  • 信任锚定在你的 GCP 项目中。 你决定哪个 CrewAI 组织可以模拟哪个服务账号。
  • STS 交换发生在 crew 执行内部,而不是 AMP 的控制平面。AMP 只签发 OIDC 令牌;GCP 签发的 Google 凭据不会被 AMP 看到或持久化,它们只存在于请求它们的单次执行中。
  • 访问令牌会自动刷新,底层 OIDC subject token 会在到期前轮换,因此支持长时间运行的 crew(下文会说明一个边界情况)。
sequenceDiagram
participant Crew as Crew 执行
participant AMP as CrewAI AMP
participant STS as GCP STS
participant IAM as IAM Credentials API
participant Vertex as Vertex AI
Crew->>AMP: 请求 OIDC JWT (aud = WI provider)
AMP-->>Crew: OIDC JWT
Note over Crew: 写入 GOOGLE_APPLICATION_CREDENTIALS<br/>external_account ADC 文件
Crew->>STS: 交换 JWT(通过 google-auth)
Note right of STS: 通过 JWKS 验证<br/>+ attribute condition
STS-->>Crew: 联合令牌
Crew->>IAM: generateAccessToken(模拟 SA)
IAM-->>Crew: SA access token
Crew->>Vertex: generateContent / predict

GCP 会从标准 OIDC discovery endpoint 获取 AMP 的公钥签名密钥,并在交换前验证每个令牌。AMP 不会看到你的 GCP 服务账号密钥,而 GCP 签发的联合/SA 令牌会留在请求它们的 crew 执行内部,不会返回给 AMP 的控制平面,也不会在那里持久化。


  • 已启用 Vertex AI(aiplatform.googleapis.com)的 GCP 项目。
  • 已通过 gcloud CLI 使用在该项目上具有 IAM 管理权限的用户进行身份验证。有关所需具体角色,请参见 附录:最小 IAM
  • 你的 CrewAI 组织 UUID。可在 CrewAI AMP 的 Settings → Organization 中找到(使用 UUID,不要使用数字 ID)。
  • 已在你的 AMP 组织上为 LLM 连接启用工作负载身份 - 联系 CrewAI 支持。

CrewAI AMP 的 OIDC issuer URL 为:

https://app.crewai.com

  1. 启用所需 API
    Terminal window
    gcloud services enable \
    iam.googleapis.com \
    iamcredentials.googleapis.com \
    sts.googleapis.com \
    aiplatform.googleapis.com \
    --project=PROJECT_ID
  2. 创建工作负载身份池
    Terminal window
    gcloud iam workload-identity-pools create crewai-amp \
    --project=PROJECT_ID \
    --location=global \
    --display-name="CrewAI AMP"
  3. 在池中创建 OIDC 提供商

    attribute-condition关键安全边界 - 它限制了哪个 CrewAI 组织可以从此池中假冒任意身份。将 YOUR_ORG_UUID 替换为你的 AMP 组织 UUID。

    Terminal window
    gcloud iam workload-identity-pools providers create-oidc crewai-amp-oidc \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=crewai-amp \
    --issuer-uri="https://app.crewai.com" \
    --attribute-mapping="google.subject=assertion.sub,attribute.organization=assertion.organization_id" \
    --attribute-condition="assertion.organization_id == 'YOUR_ORG_UUID'"

    记录完整的 provider 资源名称 - 在第 2 部分会用到:

    Terminal window
    gcloud iam workload-identity-pools providers describe crewai-amp-oidc \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=crewai-amp \
    --format="value(name)"
    # projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/crewai-amp/providers/crewai-amp-oidc
  4. 创建 Vertex AI 服务账号

    crewai-vertex 只是示例名称 - 你可以使用任何符合命名规范的名称,但请在 impersonation binding(下一步)和 LLM 连接(第 2 部分)中使用同一个值。

    Terminal window
    gcloud iam service-accounts create crewai-vertex \
    --project=PROJECT_ID \
    --display-name="CrewAI AMP — Vertex AI"
    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:crewai-vertex@PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/aiplatform.user"

    roles/aiplatform.usergenerateContentpredict 所需的最低角色。如果你的安全策略要求更严格的权限,请使用自定义角色进一步收紧。

  5. 允许该池模拟服务账号

    这是第二道安全边界:只有 organization 属性与你组织 UUID 匹配的联合身份才可以模拟这个 SA。

    Terminal window
    gcloud iam service-accounts add-iam-policy-binding \
    crewai-vertex@PROJECT_ID.iam.gserviceaccount.com \
    --project=PROJECT_ID \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/crewai-amp/attribute.organization/YOUR_ORG_UUID"

  1. 创建 Workload Identity Config

    在 AMP 中,进入 Settings → Workload Identity Configs → New 并填写:

    字段
    Name一个容易记住的标签,例如 vertex-ai-prod
    Cloud providerGCP
    GCP Workload Identity Provider第 1 部分第 3 步中的完整资源名称(projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/crewai-amp/providers/crewai-amp-oidc
    Default for GCP可选 - 将其标记为新连接的默认 GCP 配置

    创建工作负载身份配置需要拥有 LLM 连接 manage 权限的角色(参见 RBAC)。

  2. 将配置附加到 Vertex LLM 连接

    进入 LLM Connections → New(或编辑现有连接),并选择:

    • Provider: Vertex
    • Workload Identity Config: 上一步创建的配置
    • GCP Service Account Email: 你在第 1 部分创建的 SA,例如 crewai-vertex@PROJECT_ID.iam.gserviceaccount.com

    不需要设置 GOOGLE_API_KEY 环境变量 - 保持为空。对于区域,请添加一个连接级环境变量:

    • GOOGLE_CLOUD_LOCATION=global - 推荐默认值。Vertex 的 global endpoint 提供更高可用性,并受当前 Gemini 2.x 和 3.x 模型支持。如果你需要数据驻留(global 端点保证在区域内处理),或者计划使用不在 global 上运行的 Vertex 功能(特别是 tuning、Anthropic / OpenMaaS 模型的 batch prediction,以及 RAG corpus management - 但 RAG 请求 仍可在 global 上运行),则可以设置为特定区域,例如 us-central1europe-west4。对于聊天/补全型 crews,global 是正确选择。
  3. 将连接绑定到 crew 或部署

    像绑定其他 LLM 连接一样,将该 LLM 连接附加到 crew、Studio 项目或部署。kickoff 时,运行中的 crew 会为此连接的工作负载身份提供商向 AMP 请求一个 OIDC 令牌,并在进程内将其交换为 Vertex 凭据 - AMP 不会存储或推送任何 Google 凭据。


对于由工作负载身份支持的 Vertex 连接,crew 不会收到静态部署时环境变量形式的 GOOGLE_API_KEY 或服务账号 JSON。相反,在 kickoff 时,运行中的 crew 会:

  1. 从 AMP 获取一个 OIDC 令牌,该令牌由 AMP 的私钥签名,并限定到你的组织(audience = 你的工作负载身份提供商)。

  2. 将 JWT 写入执行环境中的临时文件。

  3. 写入一个类型为 external_account 的 Google Application Default Credentials (ADC) 配置,该配置引用 JWT 文件、你的 STS audience,以及(可选的)服务账号 impersonation URL。

  4. 为 crew 进程设置以下环境变量:

    环境变量
    GOOGLE_APPLICATION_CREDENTIALS指向临时 ADC external_account 配置文件的路径
    GOOGLE_CLOUD_PROJECT从工作负载身份提供商资源名称解析出的 GCP 项目编号(Google Gen AI SDK 接受项目 ID 或项目编号)

    不会自动设置 GOOGLE_API_KEYGOOGLE_CLOUD_LOCATION。请在 AMP 的 LLM 连接中配置 GOOGLE_CLOUD_LOCATION(推荐默认值:global)。

  5. 从此开始,google-auth(由 Google Gen AI SDK 使用)会在首次 Vertex API 调用时透明地完成 STS 交换和 SA impersonation,并自动缓存/刷新生成的 access token。

crew SDK 会像读取其他环境变量一样读取这些值 - 只要你的 crew 是基于 crewai>=1.14.3 部署的,就无需代码更改(参见 版本要求)。

访问令牌会自动刷新

  • Vertex access token(1 小时 TTL)由 google-auth 在进程内刷新,对你的 crew 代码透明。
  • 底层 OIDC subject token(同样为 1 小时 TTL)会在每次 kickoff 入口点进入前过期前轮换。crew 会从 AMP 获取新的 OIDC JWT,并重写 ADC token 文件;后续 STS 交换会使用新的 JWT。

实际效果是:

  • 运行时间少于 1 小时的 crew 不会触发刷新 - 初始令牌足以覆盖整个执行。
  • 运行时间超过数小时的 crew 只要在执行过程中有 kickoff 入口点(同步 hop、agent step 等)触发,就可以继续工作;刷新缓冲区会确保 OIDC 令牌在 STS 拒绝之前被轮换。
  • 如果单次 Vertex API 调用持续超过 1 小时(非常少见 - 通常 Gemini 响应会在数秒内返回),OIDC 令牌可能在请求进行中失效,从而导致调用失败。这是刷新无法帮助的唯一场景。

运行一个使用 Vertex 连接的 crew,并在 AMP 中查看执行日志。成功的 generateContentpredict 调用可以确认整条链路 - OIDC 签发 → STS 交换 → SA impersonation → Vertex - 已正确配置。

如果 crew 失败,请参见下方的 故障排查。大多数问题都来自 GCP 侧配置 - 例如 OIDC provider 的 attribute-condition 或服务账号的 principalSet 绑定。

你可以通过查看 GCP 项目中的 Cloud Audit Logs 来确认令牌是否已交换:

  • Service: sts.googleapis.com → method google.identity.sts.v1.SecurityTokenService.ExchangeToken
  • Service: iamcredentials.googleapis.com → method GenerateAccessToken

一次短执行会产生一条 ExchangeToken 和一条 GenerateAccessToken 记录;更长的执行会在每次 OIDC 令牌轮换时产生额外记录。protoPayload.authenticationInfo 包含 suborganization_id claims,适合审计和事件响应。


症状可能原因
AMP UI 不显示 Workload Identity Configs你的组织尚未启用该功能 - 联系 CrewAI 支持。
AMP UI 拒绝将配置附加到 LLM 连接连接的 provider 必须是 Vertex(GCP)。
GCP STS 返回 PERMISSION_DENIED: The given credential is rejected by the attribute condition组织 UUID 不匹配 - 通常是使用了数字组织 ID 而不是 UUID,或者 attribute condition 中的 UUID 错误。
GCP STS 返回 INVALID_ARGUMENT: Invalid JWTprovider 中的 issuer URL 与 https://app.crewai.com 不一致,或者 GCP 的 JWKS 缓存过期(最多等待 1 小时,或重新创建 provider)。
generateAccessToken 返回 PERMISSION_DENIED该池成员缺少服务账号上的 roles/iam.workloadIdentityUser,或者绑定中的 principalSet 使用了错误的属性路径。
Vertex 在 generateContent 时返回 PERMISSION_DENIED该服务账号在项目上缺少 roles/aiplatform.user(或等效的自定义角色)。
crew 立即失败并报 DefaultCredentialsError: File <path> was not foundADC token 文件被清理了 - 通常是因为凭据初始化后进程被 fork。重新 kickoff crew。如果问题持续,请在 pyproject.toml 中提升到 crewai>=1.14.3 并重新部署。
crew 失败并报 DefaultCredentialsError,且执行环境中未设置 GOOGLE_APPLICATION_CREDENTIALS你的 crew 是基于 crewai 1.14.3 之前的版本部署的,因此没有写入 ADC 文件,也没有用于工作负载身份连接的 API key 回退。请在 pyproject.toml 中提升到 crewai>=1.14.3 并重新部署。
crew 在约 1 小时后因 STS 返回 invalid_grant 而失败OIDC subject token 已过期且刷新未触发 - 通常是因为单个进程内调用将执行拖过了刷新缓冲区。如果可以复现,请将失败的执行 ID 提供给 CrewAI 支持。
Vertex 调用失败并提示 Unable to locate projectGOOGLE_CLOUD_PROJECT 未被解析 - 你在 AMP 中的工作负载身份提供商资源名称不符合 projects/PROJECT_NUMBER/... 格式。请重新检查从 gcloud iam workload-identity-pools providers describe 复制的 provider 值。
Vertex 调用失败并提示 region/location 错误LLM 连接上未设置 GOOGLE_CLOUD_LOCATION。请将其作为连接级环境变量添加(推荐默认值:global)。
Vertex 返回 model not foundnot available in location所选区域没有托管该模型。将连接的 GOOGLE_CLOUD_LOCATION 切换为 global,或选择已知托管该模型的区域。
即使 WI 配置正常,Vertex 调用仍然认证失败模型标识使用的是 vertex_ai/(LiteLLM)前缀,而不是 google/。工作负载身份只通过 Google Gen AI SDK 路径工作 - 请将模型改为 google/<model-name>

  • organization_id claim 是你的安全边界。 你的 GCP attribute condition 必须 限制到你的组织 UUID。如果不这样做,任何 CrewAI AMP 组织都可能通过你的池交换令牌。sub claim 包含相同的 UUID,并以前缀 organization: 形式出现 - 二者都可使用,但 organization_idattribute.organization 映射和 principalSet 绑定中使用的裸 UUID 形式一致。
  • 服务账号 impersonation 是第二道边界。 principalSet 绑定将 impersonation 限定为 organization 属性与你 UUID 匹配的身份。即使已经设置了 attribute condition,也应该保留它 - 这是纵深防御。
  • Issuer 信任是单向的。 GCP 通过 HTTPS 获取 AMP 的公钥 JWKS。AMP 不会收到任何 GCP 凭据。

运行上面 gcloud 命令的用户需要在目标项目上拥有:

  • roles/iam.workloadIdentityPoolAdmin - 创建池和 provider
  • roles/iam.serviceAccountAdmin - 创建服务账号
  • roles/resourcemanager.projectIamAdmin - 绑定项目级角色
  • roles/serviceusage.serviceUsageAdmin - 启用所需 API

或者等效的项目级 roles/owner