跳转到内容

AWS Workload Identity(OIDC Federation)

本指南通过 Workload Identity Federation 配置 AWS Secrets Manager 作为密钥 provider:CrewAI Platform 会生成短期 OIDC tokens,通过 STS 换取 AWS 凭据,然后读取你的密钥 - 全程不会在任何地方存放长期 AWS access key。

  1. 部署 worker 从 CrewAI Platform 请求一个新的 OIDC JWT。
  2. worker 使用你下方设置的 IAM role 调用 sts:AssumeRoleWithWebIdentity,并提交这个 JWT。
  3. AWS STS 会根据 CrewAI Platform 的公开 OIDC issuer 验证 JWT(因此你的 platform 安装必须能被 AWS 访问),然后返回短期 AWS credentials。
  4. worker 使用这些 credentials 调用 secretsmanager:GetSecretValue
  5. 获取到的值会在本次 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 字段就是 AWS 会注册为受信任 OIDC provider 的 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 步 - 将 CrewAI Platform 注册为 IAM OIDC Identity Provider

Section titled “第 2 步 - 将 CrewAI Platform 注册为 IAM OIDC Identity Provider”

打开 IAM → Identity providers console,然后点击 Add provider

  • Provider type: OpenID Connect。
  • Provider URL: 第 1 步中的 issuer 值(例如 https://app.crewai.com)。
  • Audience: sts.amazonaws.com

点击 Add provider

或者使用 CLI:

Terminal window
aws iam create-open-id-connect-provider \
--url "https://<your-platform-host>" \
--client-id-list "sts.amazonaws.com" \
--thumbprint-list "$(echo | openssl s_client -servername <your-platform-host> -connect <your-platform-host>:443 2>/dev/null | openssl x509 -fingerprint -noout -sha1 | cut -d= -f2 | tr -d ':')"

从输出中复制 OpenIDConnectProviderArn(或者在控制台中复制 provider 的 ARN)。第 3 步会用到它。

将下面内容保存为 trust-policy.json,并替换 <YOUR_ACCOUNT_ID><your-platform-host>(issuer host,不要https://http://,例如 app.crewai.com)以及 <YOUR_CREWAI_ORG_UUID>(来自前提条件):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<YOUR_ACCOUNT_ID>:oidc-provider/<your-platform-host>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<your-platform-host>:aud": "sts.amazonaws.com",
"<your-platform-host>:sub": "organization:<YOUR_CREWAI_ORG_UUID>"
}
}
}
]
}

创建 role:

Terminal window
aws iam create-role \
--role-name crewai-secrets-reader \
--assume-role-policy-document file://trust-policy.json

从输出中复制 Role Arn - 这就是你的 aws_role_arn。你会在第 6 步把它填入 CrewAI Platform。

第 4 步 - 创建并附加用于 Secrets Manager + KMS 访问的 IAM policy

Section titled “第 4 步 - 创建并附加用于 Secrets Manager + KMS 访问的 IAM policy”

将下面内容保存为 secrets-policy.json,并把占位符替换成你的 account ID、region、secret-name prefix 以及用于加密这些密钥的 KMS key ARN:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SecretsManagerListForUI",
"Effect": "Allow",
"Action": "secretsmanager:ListSecrets",
"Resource": "*"
},
{
"Sid": "SecretsManagerRead",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:<REGION>:<YOUR_ACCOUNT_ID>:secret:<SECRET_NAME_PREFIX>-*"
},
{
"Sid": "KMSDecrypt",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:<REGION>:<YOUR_ACCOUNT_ID>:key/<KMS_KEY_ID>"
}
]
}

SecretsManagerListForUI 为 Environment Variables 表单中的 Secret Name autocomplete 和凭据上的 Test Connection 按钮提供支持。secretsmanager:ListSecrets 只接受 Resource: "*" - 在 IAM 层面它是 account-scoped。

你可以用 CLI(最简单的是 inline policy)或者控制台 UI 将 policy 附加到 role;如果你想在多个 role 之间复用同一套权限,请使用 Managed policy 标签页创建可复用的命名 policy。

Inline policy (CLI)
Terminal window
aws iam put-role-policy \
--role-name crewai-secrets-reader \
--policy-name SecretsManagerRead \
--policy-document file://secrets-policy.json

这会把 policy 内联附加到 role 上。Inline policy 与 role 绑定,不能复用到其他 role。

Managed policy (CLI, reusable)
Terminal window
POLICY_ARN=$(aws iam create-policy \
--policy-name CrewAISecretsReader \
--policy-document file://secrets-policy.json \
--query 'Policy.Arn' --output text)
aws iam attach-role-policy \
--role-name crewai-secrets-reader \
--policy-arn "$POLICY_ARN"

Managed policy 是一个独立的 IAM resource,可以附加到多个 role 上。

Console (UI)
  1. 打开 IAM → Roles console 并选择 crewai-secrets-reader
  2. Permissions 标签页,点击 Add permissionsCreate inline policy
  3. 切换到 JSON 编辑器并粘贴 secrets-policy.json 的内容。
  4. 点击 Next,给 policy 起一个名字(例如 SecretsManagerRead),然后点击 Create policy

如果你想创建可复用的 managed policy,请改用 IAM → Policies → Create policy,然后从 role 的 Permissions 标签页把它附加到 role。

第 5 步 - 在 AWS 中至少创建一个 Secret

Section titled “第 5 步 - 在 AWS 中至少创建一个 Secret”

如果你还没有要测试的 secret,现在创建一个:

Terminal window
aws secretsmanager create-secret \
--region <REGION> \
--name crewai-test-keyword \
--secret-string "hello from aws"

或者通过 AWS Secrets Manager consoleStore a new secret

第 6 步 - 在 CrewAI Platform 中添加 Workload Identity Configuration

Section titled “第 6 步 - 在 CrewAI Platform 中添加 Workload Identity Configuration”

在 CrewAI Platform 中,进入 SettingsWorkload Identity 并点击 Add Workload Identity Config

填写表单:

  • Name: 描述性名称,例如 aws-prod
  • Cloud Provider: AWS
  • AWS Role ARN: 第 3 步中的 Role Arn
  • AWS Region: 密钥所在 region,例如 us-east-1。 -(可选)勾选 Set as default for AWS,这样当你创建 AWS-backed secret credential 时就会默认选中这个 WI config。

点击 Create

第 7 步 - 添加绑定到 WI Config 的 Secret Provider Credential

Section titled “第 7 步 - 添加绑定到 WI Config 的 Secret Provider Credential”

进入 SettingsSecret Provider Credentials 并点击 Add Credential

填写表单:

  • Name: 描述性名称,例如 aws-prod-wi
  • Provider: AWS Secrets Manager
  • Authentication Method: Workload Identity(而不是 static keys / AssumeRole)。
  • Workload Identity Configuration: 选择你在第 6 步创建的 config(例如 aws-prod)。 -(可选)勾选 Set as default credential for this provider

在 Workload Identity 下方,表单只会要求填写 AWS Region - static-credential 字段(Access Key ID、Secret Access Key、Role ARN、External ID)会被刻意隐藏,因为它们不适用于这条路径;role ARN 来自关联的 WI config。

点击 Create

保存凭据后,点击 Test Connection。对于 workload-identity 凭据,这会验证 OIDC handshake:CrewAI Platform 会生成一个 JWT,通过 sts:AssumeRoleWithWebIdentity 与 AWS STS 交换它,并确认返回的 credentials 能对假设的 role 调用 sts:GetCallerIdentity。绿色结果表示 federation binding 正常。

成功的 Test Connection 说明 trust policy、OIDC provider 注册以及 audience 条件都正确连接好了。它不能证明每个 secret 的 IAM 都正确 - 对特定 secret ARN 的 secretsmanager:GetSecretValue 会在环境变量解析 kickoff 时单独执行。参见 Troubleshooting 了解 handshake 失败模式。

第 9 步 - 在环境变量中引用密钥

Section titled “第 9 步 - 在环境变量中引用密钥”

现在你可以在 automation 上引用这个 secret,就像引用其他 Secrets Manager-backed env var 一样。有关表单字段和行为,请参见 Using the Secrets Manager

WI-backed 与 static-keys-backed env vars 的唯一差异是读取密钥的时间

  • WI-backed: 每次 automation kickoff 都会重新读取 secret value。
  • Static-keys-backed: secret value 会在部署时读取并写入部署镜像。

部署运行起来后,轮换 AWS 中的 secret:

Terminal window
aws secretsmanager update-secret \
--region <REGION> \
--secret-id crewai-test-keyword \
--secret-string "rotated value"

触发一次新的 automation kickoff。该 kickoff 的环境会看到 "rotated value" - 无需重新部署、无需 worker restart、也不必等待 TTL。

若要在日志中确认(如果你能访问 worker),请查找:

Workload identity config '<id>' (aws): N secret(s) resolved

这行会在每次 kickoff 时出现,并表明对 AWS 进行了新的 GetSecretValue 调用。

症状可能原因
Test Connection 在 handshake error 处失败sts:AssumeRoleWithWebIdentity 调用被拒绝。验证 trust policy 中的 federated principal ARN 是否引用了 oidc-provider/<your-platform-host>(host 不要https://http://,也不要结尾斜杠),audience condition 是否严格等于 sts.amazonaws.comsub condition 是否匹配你的 CrewAI organization UUID,并确认平台的 OIDC discovery URL 可从 AWS 通过公网访问。
InvalidIdentityToken: Couldn't retrieve verification key from your identity providerAWS STS 无法访问你的 CrewAI Platform host 以获取 JWKS。确认该 host 可以从 AWS 互联网访问、OIDC discovery URL 返回 200,并且 JWKS endpoint 可达。
AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentitytrust policy 不匹配。重新检查第 3 步:federated principal ARN 必须包含 oidc-provider/<your-platform-host>(host 不要https://http://,也不要结尾斜杠),audience condition 必须严格等于 sts.amazonaws.com,并且 sub condition 必须等于 organization:<YOUR_CREWAI_ORG_UUID>
Secret Name autocomplete 显示 AccessDenied: secretsmanager:ListSecretsrole 缺少带有 Resource: "*"secretsmanager:ListSecrets。请添加第 4 步中的 SecretsManagerListForUI statement。
明明 Test Connection 通过了,kickoff 仍无法解析 secretWI binding 正常,但失败的 secret 上缺少资源范围 IAM。请检查该特定 secret ARN 和 KMS key 上的 secretsmanager:GetSecretValuekms:Decrypt 权限。
RegionDisabledException / no secrets foundWorkload Identity Config 中的 region 与 secret 所在 region 不一致。重新检查第 6 步。
轮换后的值没有在下一次 kickoff 中生效确认 automation 上的 env var 引用的是 Workload Identity-backed credential(而不是 static-keys credential)。静态路径会把值写入 deploy image。