mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-02 21:58:11 +00:00
322 lines
17 KiB
Plaintext
322 lines
17 KiB
Plaintext
---
|
|
title: AWS Workload Identity (OIDC Federation)
|
|
description: Configure AWS Secrets Manager via Workload Identity for rotation-aware, credential-free secret access
|
|
sidebarTitle: With Workload Identity
|
|
icon: "id-badge"
|
|
---
|
|
|
|
## Overview
|
|
|
|
This guide configures AWS Secrets Manager as a secret provider using **Workload Identity Federation**: CrewAI Platform mints short-lived OIDC tokens, exchanges them for AWS credentials via STS, and reads your secrets — without a long-lived AWS access key being stored anywhere.
|
|
|
|
<Note>
|
|
**Why this path:** secrets are resolved at automation execution time, so **rotated values propagate to the next kickoff with no re-deploy**. If you only need static credentials and don't care about rotation propagation, see the simpler [AWS — static keys / AssumeRole](/en/enterprise/features/secrets-manager/aws) guide.
|
|
</Note>
|
|
|
|
### How it works at runtime
|
|
|
|
1. The deployment worker requests a fresh OIDC JWT from CrewAI Platform.
|
|
2. The worker calls `sts:AssumeRoleWithWebIdentity` on the IAM role you set up below, presenting the JWT.
|
|
3. AWS STS validates the JWT against CrewAI Platform's public OIDC issuer (so your platform installation must be reachable from AWS), then returns short-lived AWS credentials.
|
|
4. The worker uses those credentials to call `secretsmanager:GetSecretValue`.
|
|
5. The fetched value is injected as the environment variable's value for that automation kickoff.
|
|
|
|
OIDC subject tokens are cached for ~1 hour to avoid re-issuing on every kickoff. Secret values are fetched fresh on every kickoff regardless of OIDC cache state, which is what makes this path rotation-aware.
|
|
|
|
## Prerequisites
|
|
|
|
<Note>
|
|
Before starting, make sure you have:
|
|
|
|
- The automation pod image must include CrewAI runtime version `1.14.5` or later.
|
|
- An AWS account with permission to create IAM OIDC providers, IAM roles, and IAM policies.
|
|
- The AWS region where your secrets live (or will live), e.g. `us-east-1`.
|
|
- A CrewAI Platform organization where your user has the `workload_identity_configs: manage` and `secret_providers: manage` permissions. See [Permissions (RBAC)](/en/enterprise/features/secrets-manager/usage#permissions-rbac).
|
|
- **Your CrewAI organization UUID.** Find it on the organization's settings page in CrewAI Platform — the trust policy in Step 3 binds the IAM role to this specific organization.
|
|
- **Your CrewAI Platform installation must be reachable from AWS over HTTPS** so that AWS STS can fetch the OIDC discovery document and JWKS during token validation. Confirm with your platform administrator that the host is internet-accessible (or that AWS has network reach to it via VPC peering / equivalent).
|
|
</Note>
|
|
|
|
## Step 1 — Find Your CrewAI Platform OIDC Issuer URL
|
|
|
|
Your CrewAI Platform installation publishes an OpenID Connect discovery document at `https://<your-platform-host>/.well-known/openid-configuration`. The `issuer` field in that document is the URL AWS will register as a trusted OIDC provider.
|
|
|
|
Open the URL in a browser (replacing `<your-platform-host>` with your actual hostname, e.g. `app.crewai.com`):
|
|
|
|
```
|
|
https://<your-platform-host>/.well-known/openid-configuration
|
|
```
|
|
|
|
You should see JSON containing:
|
|
|
|
```json
|
|
{
|
|
"issuer": "https://<your-platform-host>",
|
|
"jwks_uri": "https://<your-platform-host>/oauth2/jwks",
|
|
...
|
|
}
|
|
```
|
|
|
|
Note the exact value of `issuer` — you'll use it in Step 3.
|
|
|
|
<Tip>
|
|
If the URL returns 404 or 503, contact your platform administrator. The OIDC issuer requires a private signing key to be configured at install time. See the platform's installation guide for the `OIDC_PRIVATE_KEY` and `OIDC_ISSUER` configuration.
|
|
</Tip>
|
|
|
|
## Step 2 — Register CrewAI Platform as an IAM OIDC Identity Provider
|
|
|
|
Open the [IAM → Identity providers console](https://console.aws.amazon.com/iam/home#/identity_providers) and click **Add provider**.
|
|
|
|
- **Provider type:** OpenID Connect.
|
|
- **Provider URL:** the `issuer` value from Step 1 (e.g. `https://app.crewai.com`).
|
|
- **Audience:** `sts.amazonaws.com`
|
|
|
|
Click **Add provider**.
|
|
|
|
Or via CLI:
|
|
|
|
```bash
|
|
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 ':')"
|
|
```
|
|
|
|
Copy the **OpenIDConnectProviderArn** from the output (or the provider's ARN from the console). You'll use it in Step 3.
|
|
|
|
<Note>
|
|
AWS does not actually validate the thumbprint for STS WebIdentity calls — it always re-fetches the JWKS at validation time — but the API requires the field to be present.
|
|
</Note>
|
|
|
|
{/* SCREENSHOT: AWS IAM "Add identity provider" form filled with the Platform issuer URL and audience sts.amazonaws.com → /images/secrets-manager/aws-wi/01-add-oidc-provider.png */}
|
|
{/* SCREENSHOT: Provider detail page showing the provider's ARN → /images/secrets-manager/aws-wi/02-oidc-provider-arn.png */}
|
|
|
|
## Step 3 — Create the IAM Role
|
|
|
|
Save as `trust-policy.json`, replacing `<YOUR_ACCOUNT_ID>`, `<your-platform-host>` (the issuer host **without** `https://` or `http://`, e.g. `app.crewai.com`), and `<YOUR_CREWAI_ORG_UUID>` (from the Prerequisites):
|
|
|
|
```json
|
|
{
|
|
"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>"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Create the role:
|
|
|
|
```bash
|
|
aws iam create-role \
|
|
--role-name crewai-secrets-reader \
|
|
--assume-role-policy-document file://trust-policy.json
|
|
```
|
|
|
|
Copy the **Role Arn** from the output — that's your `aws_role_arn`. You'll paste it into CrewAI Platform in Step 6.
|
|
|
|
<Tip>
|
|
The two conditions scope the trust precisely: `aud` restricts assumption to tokens with the AWS STS audience, and `sub` scopes federation to a specific CrewAI organization — only tokens minted for that org's automations are accepted. CrewAI Platform always sets both claims on AWS workload identity tokens.
|
|
</Tip>
|
|
|
|
{/* SCREENSHOT: IAM "Create role" with Web Identity trust type, federated provider selector pointing at the CrewAI Platform OIDC provider → /images/secrets-manager/aws-wi/03-create-role-trust.png */}
|
|
|
|
## Step 4 — Create and attach the IAM policy for Secrets Manager + KMS access
|
|
|
|
Save as `secrets-policy.json`, replacing the placeholders with your account ID, region, secret-name prefix, and the KMS key ARN(s) that encrypt those secrets:
|
|
|
|
```json
|
|
{
|
|
"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` powers the **Secret Name autocomplete** in the Environment Variables form and the **Test Connection** button on the credential. `secretsmanager:ListSecrets` only accepts `Resource: "*"` — it is account-scoped at the IAM layer.
|
|
|
|
Attach the policy to the role using either the CLI (inline policy, simplest) or the console UI; for environments that reuse the same permissions across many roles, use the **Managed policy** tab for a reusable, named policy.
|
|
|
|
<Tabs>
|
|
<Tab title="Inline policy (CLI)">
|
|
```bash
|
|
aws iam put-role-policy \
|
|
--role-name crewai-secrets-reader \
|
|
--policy-name SecretsManagerRead \
|
|
--policy-document file://secrets-policy.json
|
|
```
|
|
|
|
This attaches the policy **inline** to the role. Inline policies are tied to the role and cannot be reused on other roles.
|
|
</Tab>
|
|
|
|
<Tab title="Managed policy (CLI, reusable)">
|
|
```bash
|
|
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"
|
|
```
|
|
|
|
A managed policy is a standalone IAM resource you can attach to multiple roles.
|
|
</Tab>
|
|
|
|
<Tab title="Console (UI)">
|
|
1. Open the [IAM → Roles console](https://console.aws.amazon.com/iam/home#/roles) and select **crewai-secrets-reader**.
|
|
2. On the **Permissions** tab, click **Add permissions** → **Create inline policy**.
|
|
3. Switch to the **JSON** editor and paste the contents of `secrets-policy.json`.
|
|
4. Click **Next**, give the policy a name (e.g. `SecretsManagerRead`), and click **Create policy**.
|
|
|
|
To create a reusable managed policy instead, use **IAM → Policies → Create policy** and then attach it to the role from the role's **Permissions** tab.
|
|
|
|
{/* SCREENSHOT: IAM Role detail → Permissions → Create inline policy with JSON editor → /images/secrets-manager/aws-wi/03b-attach-inline-policy.png */}
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Step 5 — Create at Least One Secret in AWS
|
|
|
|
If you don't already have a secret to test against, create one now:
|
|
|
|
```bash
|
|
aws secretsmanager create-secret \
|
|
--region <REGION> \
|
|
--name crewai-test-keyword \
|
|
--secret-string "hello from aws"
|
|
```
|
|
|
|
Or via the [AWS Secrets Manager console](https://console.aws.amazon.com/secretsmanager/) → **Store a new secret**.
|
|
|
|
{/* SCREENSHOT: AWS Secrets Manager "Store a new secret" page with a sample value → /images/secrets-manager/aws-wi/04-create-secret.png */}
|
|
|
|
## Step 6 — Add a Workload Identity Configuration in CrewAI Platform
|
|
|
|
In CrewAI Platform, navigate to **Settings** → **Workload Identity** and click **Add Workload Identity Config**.
|
|
|
|
{/* SCREENSHOT: Sidebar highlighting Settings → Workload Identity → /images/secrets-manager/aws-wi/05-amp-settings-wi-nav.png */}
|
|
{/* SCREENSHOT: Empty state of Workload Identity page with "Add Workload Identity Config" button → /images/secrets-manager/aws-wi/06-amp-wi-empty-state.png */}
|
|
|
|
Fill the form:
|
|
|
|
- **Name:** A descriptive name, e.g. `aws-prod`.
|
|
- **Cloud Provider:** `AWS`.
|
|
- **AWS Role ARN:** the **Role Arn** from Step 3.
|
|
- **AWS Region:** the region where your secrets live, e.g. `us-east-1`.
|
|
- (Optional) Check **Set as default for AWS** if you'd like this WI config to be the default selected when creating an AWS-backed secret credential.
|
|
|
|
Click **Create**.
|
|
|
|
{/* SCREENSHOT: "Add Workload Identity Config" form with AWS, role ARN, and region filled in → /images/secrets-manager/aws-wi/07-amp-add-wi-config-aws.png */}
|
|
{/* SCREENSHOT: Workload Identity list showing the new AWS row with "(default)" badge if applicable → /images/secrets-manager/aws-wi/08-amp-wi-list-with-aws.png */}
|
|
|
|
## Step 7 — Add a Secret Provider Credential Bound to the WI Config
|
|
|
|
Navigate to **Settings** → **Secret Provider Credentials** and click **Add Credential**.
|
|
|
|
Fill the form:
|
|
|
|
- **Name:** A descriptive name, e.g. `aws-prod-wi`.
|
|
- **Provider:** `AWS Secrets Manager`.
|
|
- **Authentication Method:** `Workload Identity` (instead of static keys / AssumeRole).
|
|
- **Workload Identity Configuration:** select the config you created in Step 6 (e.g. `aws-prod`).
|
|
- (Optional) Check **Set as default credential for this provider**.
|
|
|
|
The form will only ask for **AWS Region** under Workload Identity — the static-credential fields (Access Key ID, Secret Access Key, Role ARN, External ID) are intentionally hidden because they don't apply to this path; the role ARN comes from the linked WI config.
|
|
|
|
Click **Create**.
|
|
|
|
{/* SCREENSHOT: "Add Secret Provider Credential" form with AWS + Workload Identity + WI config dropdown selected → /images/secrets-manager/aws-wi/09-amp-add-credential-aws-wi.png */}
|
|
|
|
## Step 8 — Test the Connection
|
|
|
|
After saving the credential, click **Test Connection**. For workload-identity credentials this verifies the OIDC handshake: CrewAI Platform mints a JWT, exchanges it with AWS STS via `sts:AssumeRoleWithWebIdentity`, and confirms the resulting credentials can call `sts:GetCallerIdentity` against the assumed role. A green result means the federation binding is healthy.
|
|
|
|
A successful Test Connection proves the trust policy, OIDC provider registration, and audience condition are all wired correctly. It does **not** prove per-secret IAM is correct — `secretsmanager:GetSecretValue` on a specific secret ARN is exercised separately when an environment variable resolves at kickoff. See [Troubleshooting](#troubleshooting) for handshake failure modes.
|
|
|
|
## Step 9 — Reference the Secret in an Environment Variable
|
|
|
|
Now reference the secret on an automation, exactly as you would for any other Secrets Manager-backed env var. See [Using the Secrets Manager](/en/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables) for the form fields and behavior.
|
|
|
|
The only difference between WI-backed and static-keys-backed env vars is **when** the secret is read:
|
|
|
|
- **WI-backed:** secret value is read fresh on every automation kickoff.
|
|
- **Static-keys-backed:** secret value is read at deploy time and baked into the deployment image.
|
|
|
|
## Step 10 — Verify Rotation
|
|
|
|
After the deployment is running, rotate the secret in AWS:
|
|
|
|
```bash
|
|
aws secretsmanager update-secret \
|
|
--region <REGION> \
|
|
--secret-id crewai-test-keyword \
|
|
--secret-string "rotated value"
|
|
```
|
|
|
|
Trigger a new automation kickoff. The kickoff's environment will see `"rotated value"` — no re-deploy, no worker restart, no waiting on a TTL.
|
|
|
|
To confirm in logs (if you have access to the worker), look for:
|
|
|
|
```
|
|
Workload identity config '<id>' (aws): N secret(s) resolved
|
|
```
|
|
|
|
This line appears for every kickoff and indicates a fresh `GetSecretValue` call against AWS.
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | Likely cause |
|
|
|---|---|
|
|
| Test Connection fails with a handshake error | The `sts:AssumeRoleWithWebIdentity` call was rejected. Verify the trust policy's federated principal ARN references `oidc-provider/<your-platform-host>` (host **without** `https://` or `http://`, no trailing slash), the audience condition is exactly `sts.amazonaws.com`, the `sub` condition matches your CrewAI organization UUID, and the platform's OIDC discovery URL is reachable from AWS over the public internet. |
|
|
| `InvalidIdentityToken: Couldn't retrieve verification key from your identity provider` | AWS STS can't reach your CrewAI Platform host to fetch JWKS. Confirm the host is internet-accessible from AWS, the OIDC discovery URL returns 200, and the JWKS endpoint is reachable. |
|
|
| `AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity` | Trust policy mismatch. Re-check Step 3: the federated principal ARN must include `oidc-provider/<your-platform-host>` (host **without** `https://` or `http://`, no trailing slash), the audience condition must be exactly `sts.amazonaws.com`, and the `sub` condition must equal `organization:<YOUR_CREWAI_ORG_UUID>`. |
|
|
| Secret Name autocomplete shows `AccessDenied: secretsmanager:ListSecrets` | The role is missing `secretsmanager:ListSecrets` with `Resource: "*"`. Add the `SecretsManagerListForUI` statement from Step 4. |
|
|
| Kickoff fails to resolve a secret even though Test Connection passes | The WI binding is healthy, but resource-scoped IAM is missing on the failing secret. Audit the role's `secretsmanager:GetSecretValue` and `kms:Decrypt` permissions for that specific secret's ARN and KMS key. |
|
|
| `RegionDisabledException` / no secrets found | The region in the Workload Identity Config doesn't match where the secret lives. Re-check Step 6. |
|
|
| Rotated value isn't picked up on the next kickoff | Confirm the env var on the automation is referencing a Workload Identity-backed credential (not a static-keys credential). The static path bakes values into the deploy image. |
|
|
|
|
### Reference Links
|
|
|
|
- AWS: [Creating OpenID Connect (OIDC) identity providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)
|
|
- AWS: [Configuring a role for OpenID Connect federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_relying-party.html)
|
|
- AWS: [STS:AssumeRoleWithWebIdentity API reference](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)
|
|
|
|
## Next Steps
|
|
|
|
- [Use secrets in environment variables and manage permissions](/en/enterprise/features/secrets-manager/usage)
|
|
- For multi-cloud, see also [GCP Workload Identity Federation](/en/enterprise/features/secrets-manager/gcp-workload-identity) and [Azure Workload Identity Federation](/en/enterprise/features/secrets-manager/azure-workload-identity).
|