Azure Workload Identity Federation
本指南通过 Microsoft Entra Workload Identity Federation 配置 Azure Key Vault 作为密钥 provider:CrewAI Platform 会生成短期 OIDC tokens,通过 Microsoft identity platform 将其换成 Entra access token,然后读取你的密钥 - 全程不会存放任何 client secret。
运行时如何工作
Section titled “运行时如何工作”- 部署 worker 从 CrewAI Platform 请求一个新的 OIDC JWT。
- worker 将 JWT 作为
client_assertion(urn:ietf:params:oauth:client-assertion-type:jwt-bearer)提交给 Microsoft Entra 的https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token,引用其 Federated Identity Credential 与 JWT 的 issuer + subject 匹配的 App Registration。 - Entra 根据你平台的 OIDC discovery document 和 JWKS 验证 JWT,然后返回一个 scope 为
https://vault.azure.net/.default的短期 access token。 - worker 调用 Azure Key Vault 读取 secret。
- 获取到的值会在本次 automation kickoff 中被注入为环境变量值。
OIDC subject tokens 会缓存大约 1 小时,以避免每次 kickoff 都重新签发。无论 OIDC 缓存状态如何,secret values 都会在每次 kickoff 时刷新获取,这也是这条路径具备 rotation awareness 的原因。
第 1 步 - 找到 CrewAI Platform 的 OIDC Issuer URL
Section titled “第 1 步 - 找到 CrewAI Platform 的 OIDC Issuer URL”你的 CrewAI Platform 安装会在 https://<your-platform-host>/.well-known/openid-configuration 发布一个 OpenID Connect discovery document。该文档中的 issuer 字段就是 Microsoft Entra 会注册为受信任 federation issuer 的 URL。
在浏览器中打开这个 URL:
https://<your-platform-host>/.well-known/openid-configuration你应该会看到 JSON,包含:
{ "issuer": "https://<your-platform-host>", "jwks_uri": "https://<your-platform-host>/oauth2/jwks", ...}记下 issuer 的准确值 - 第 3 步会用到它。
第 2 步 - 创建 App Registration
Section titled “第 2 步 - 创建 App Registration”在 Microsoft Entra portal 中,进入 App registrations 并点击 New registration。
- Name:
crewai-secrets-reader - Supported account types:
Accounts in this organizational directory only (Single tenant)。 - 保留 Redirect URI 为空。
点击 Register。记下 App overview blade 上的 Application (client) ID 和 Directory (tenant) ID - 第 6 步会用到它们。
第 3 步 - 添加 Federated Identity Credential
Section titled “第 3 步 - 添加 Federated Identity Credential”Federated Identity Credential 会告诉 Microsoft Entra:信任这个 issuer 签发的 JWT,只要 subject 也匹配,并且它们被当作这个 App Registration 的 client assertion 提交。
在 App Registration 上,进入 Certificates & secrets → Federated credentials → Add credential。
- Federated credential scenario:
Other issuer。 - Issuer: 第 1 步中的 CrewAI Platform issuer URL,例如
https://<your-platform-host>。 - Subject identifier:
organization:<YOUR_CREWAI_ORG_UUID>- 必须与 JWT 的subclaim 完全一致。请在 CrewAI Platform 的组织设置中找到 org UUID。这样 federation 就被限定到了一个特定 CrewAI organization - 只有为该组织 automations 签发的 token 才会被接受。 - Name: 任意描述性标签,例如
crewai-org-prod。 - Audience:
api://AzureADTokenExchange。这是 Microsoft Entra 对 federated credentials 要求的固定 audience,也是 CrewAI Platform 会放入 JWTaudclaim 的值。
点击 Add。
完整细节请参见 Microsoft 文档:Configure a federated identity credential on an app。
第 4 步 - 授予 App Registration 访问 Key Vault 的权限
Section titled “第 4 步 - 授予 App Registration 访问 Key Vault 的权限”在目标 vault 上为 App Registration 授予 Key Vault Secrets User - 与 static-credentials 路径使用的角色相同。你可以使用 vault-wide(更简单)或 per-secret(最小权限)两种方式。
az role assignment create \ --assignee <APPLICATION_CLIENT_ID> \ --role "Key Vault Secrets User" \ --scope $(az keyvault show --name <VAULT_NAME> --query id -o tsv)Vault-wide scope 会授予 secrets/list 权限,而 CrewAI Platform env-var form 中的 Secret Name autocomplete 依赖它。如果你希望 autocomplete 正常工作,请选择这个 tab。
az role assignment create \ --assignee <APPLICATION_CLIENT_ID> \ --role "Key Vault Secrets User" \ --scope $(az keyvault secret show --vault-name <VAULT_NAME> --name <SECRET_NAME> --query id -o tsv)Per-secret bindings 会禁用 CrewAI Platform env-var form 中的 Secret Name autocomplete(autocomplete 需要 secrets/list,而它只能在 vault scope 下授予)。请改为手动输入完整的 secret name。
对于 vault-wide assignment:
- 在 Azure portal 中打开你的 Key Vault。
- 点击 Access control (IAM) → Add → Add role assignment。
- 选择角色 Key Vault Secrets User → Next。
- 点击 Select members,搜索 App Registration
crewai-secrets-reader,然后点击 Select。 - 点击 Review + assign。
对于 per-secret assignment,请使用相同流程,但从 Objects → Secrets → 选择某个 secret → 它自己的 Access control (IAM) 面板开始。Per-secret bindings 会禁用 autocomplete(参见上面的 Per-secret tab)。
第 5 步 - 在 Key Vault 中至少创建一个 Secret
Section titled “第 5 步 - 在 Key Vault 中至少创建一个 Secret”如果你还没有可用于测试的 secret,可以通过 Azure CLI 创建:
az keyvault secret set \ --vault-name <VAULT_NAME> \ --name openai-api-key \ --value "sk-your-actual-key"或者通过 Azure portal:
- 打开你的 Key Vault,进入 Objects → Secrets。
- 点击 Generate/Import。
- Upload options:
Manual. Name: secret 名称(例如openai-api-key)。Secret value: 粘贴值。 - 点击 Create。
第 6 步 - 在 CrewAI Platform 中添加 Workload Identity Configuration
Section titled “第 6 步 - 在 CrewAI Platform 中添加 Workload Identity Configuration”在 CrewAI Platform 中,进入 Settings → Workload Identity 并点击 Add Workload Identity Config。
填写表单:
- Name: 描述性名称,例如
azure-prod。 - Cloud Provider:
Azure。 - Tenant ID: 第 2 步中的 Microsoft Entra Directory (tenant) ID。
- Client ID: 第 2 步中的 App Registration Application (client) ID。 -(可选)如果你希望它成为创建 Azure-backed secret credential 时默认选择的 WI config,请勾选 Set as default for Azure。
Audience 固定为 api://AzureADTokenExchange - Microsoft Entra 对 federated credentials 要求这个精确 audience,因此表单不会显示 Audience 字段。
点击 Create。
第 7 步 - 添加绑定到 WI Config 的 Secret Provider Credential
Section titled “第 7 步 - 添加绑定到 WI Config 的 Secret Provider Credential”进入 Settings → Secret Provider Credentials 并点击 Add Credential。
填写表单:
- Name: 描述性名称,例如
azure-prod-wi。 - Provider:
Azure Key Vault。 - Authentication Method:
Workload Identity。 - Workload Identity Configuration: 选择你在第 6 步创建的 config。
- Key Vault URL: vault 的 DNS hostname,例如
https://my-vault.vault.azure.net。 -(可选)勾选 Set as default credential for this provider。
在 Workload Identity 下方,表单只会要求填写 Key Vault URL - static-credential 字段(Tenant ID、Client ID、Client Secret)会被刻意隐藏,因为它们不适用于这条路径;tenant + client 来自关联的 WI config。
点击 Create。
第 8 步 - 测试连接
Section titled “第 8 步 - 测试连接”保存凭据后,点击 Test Connection。对于 workload-identity 凭据,这会验证 OIDC handshake:CrewAI Platform 会生成一个 JWT,把它作为 federated client_assertion 提交给 Microsoft Entra,并确认 Entra 返回一个 vault-scoped access token。绿色结果表示 federation binding 正常。
成功的 Test Connection 说明 Federated Identity Credential 的 issuer、subject 和 audience 都匹配,并且 App Registration 可达。它不能证明 per-secret Key Vault RBAC 正确 - 对特定 secret 的 getSecret 会在环境变量解析 kickoff 时单独执行。参见 Troubleshooting 了解 handshake 失败模式。
第 9 步 - 在环境变量中引用密钥
Section titled “第 9 步 - 在环境变量中引用密钥”就像引用其他 Secrets Manager-backed env var 一样,在 automation 上引用这个 secret。有关表单字段和行为,请参见 Using the Secrets Manager。
第 10 步 - 验证轮换
Section titled “第 10 步 - 验证轮换”部署运行起来后,轮换 Key Vault 中的 secret:
az keyvault secret set \ --vault-name <VAULT_NAME> \ --name openai-api-key \ --value "rotated value"触发一次新的 automation kickoff。该 kickoff 的环境会看到 "rotated value" - 无需重新部署、无需 worker restart、也不必等待 TTL。
若要在 worker logs 中确认,请查找:
Workload identity config '<id>' (azure): N secret(s) resolved这行会在每次 kickoff 时出现,并表明对 Azure Key Vault 进行了新的 getSecret 调用。
如需端到端的基于 fingerprint 的验证,请参见 Verify Rotation End-to-End。
| 症状 | 可能原因 |
|---|---|
| Test Connection 在 handshake error 处失败 | federated client_assertion 被 Microsoft Entra 拒绝。验证 Federated Identity Credential 的 Issuer 是否与平台的 issuer 值完全一致,Subject 是否为 organization:<your-org-uuid>(与 JWT 的 sub claim 一致),Audience 是否为 api://AzureADTokenExchange,并确认平台的 OIDC discovery URL 可从 Entra 通过公网访问。 |
AADSTS70021: No matching federated identity record found for presented assertion | Federated Identity Credential 的 Issuer + Subject + Audience 并未与 JWT 完全匹配。重新检查第 3 步:subject 必须是 organization:<your-org-uuid>(与 JWT 的 sub claim 一致),audience 必须是 api://AzureADTokenExchange。 |
AADSTS700024: Client assertion is not within its valid time range | CrewAI Platform host 的时钟与真实时间存在明显偏差。检查该 host 的 NTP。 |
AADSTS50013: Assertion failed signature validation | Microsoft Entra 无法验证 JWT 的签名。确认 https://<your-platform-host>/oauth2/jwks 可从公网访问并返回有效 JWKS。 |
Secret Name autocomplete 显示 Forbidden — does not have permission to perform action 'Microsoft.KeyVault/vaults/secrets/.../list' | App Registration 的 Key Vault Secrets User role 只作用于单个 secret。请在 vault scope 下授予该 role,以允许 list data-plane action。见第 4 步。 |
| 明明 Test Connection 通过了,kickoff 仍无法解析 secret | WI binding 正常,但失败的 secret 上缺少 per-secret Key Vault RBAC。请检查该特定 secret(或把 role assignment 扩展到 vault scope)上的 Key Vault Secrets User。 |
Forbidden — request was not authorized(vault 使用旧 access policies) | vault 尚未切换到 Azure RBAC。请在 vault 的 Access configuration 下把 permission model 设置为 Azure role-based access control,并重新授予第 4 步中的 role。 |
azure_vault_url is required for Azure secret resolution(worker logs) | Secret Provider Credential 缺少 Key Vault URL。重新检查第 7 步。 |
| 轮换后的值没有在下一次 kickoff 中生效 | 确认 automation 上的 env var 引用的是 Workload Identity-backed credential(而不是 static-keys credential)。静态路径会把值写入 deploy image。 |
- Microsoft: Microsoft Entra Workload Identity Federation overview
- Microsoft: Configure a federated identity credential on an app
- Microsoft: Azure Key Vault RBAC guide
- Use secrets in environment variables and manage permissions
- 对于 multi-cloud,AWS 对应设置在 AWS Workload Identity (OIDC Federation),GCP 对应设置在 GCP Workload Identity Federation。
Screenshot Reference
Section titled “Screenshot Reference”上面的占位图对应如下文件:
01-register-app.png- Azure portal 的 “Register an application” 表单,已填入crewai-secrets-reader。02-add-federated-credential.png- App Registration → Certificates & secrets → Federated credentials → Add credential,已选择 Other issuer,填写平台 issuer URL、subjectorganization:<uuid>、audienceapi://AzureADTokenExchange。03-grant-vault-rbac.png- Key Vault → Access control (IAM) → Add role assignment,已选择 Key Vault Secrets User 并将 App Registration 设为成员。04-per-secret-rbac.png- 同一表单,但作用范围是单个 secret 的 IAM scope(可选的最小权限路径)。05-amp-add-wi-config-azure.png- CrewAI Platform 的 “Add Workload Identity Config” 表单,Cloud Provider = Azure,已填入 Tenant ID 和 Client ID。06-amp-wi-list-with-azure.png- Workload Identity 列表页面,创建后显示 AWS、GCP 和新的 Azure config 行。07-amp-add-credential-azure-wi.png- “Add Secret Provider Credential” 表单,Provider = Azure Key Vault,Auth = Workload Identity,已选择 WI config 并填入 Key Vault URL。