docs/en/enterprise/features/sso.mdx
CrewAI Platform supports enterprise Single Sign-On (SSO) across both SaaS (AMP) and Factory (self-hosted) deployments. SSO enables your team to authenticate using your organization's existing identity provider, enforcing centralized access control, MFA policies, and user lifecycle management.
| Provider | SaaS | Factory | Protocol | CLI Support |
|---|---|---|---|---|
| WorkOS | ✅ (default) | ✅ | OAuth 2.0 / OIDC | ✅ |
| Microsoft Entra ID (Azure AD) | ✅ (enterprise) | ✅ | OAuth 2.0 / SAML 2.0 | ✅ |
| Okta | ✅ (enterprise) | ✅ | OAuth 2.0 / OIDC | ✅ |
| Auth0 | ✅ (enterprise) | ✅ | OAuth 2.0 / OIDC | ✅ |
| Keycloak | — | ✅ | OAuth 2.0 / OIDC | ✅ |
CrewAI's managed SaaS platform (AMP) uses WorkOS as the default authentication provider. When you sign up at app.crewai.com, authentication is handled through login.crewai.com — no additional SSO configuration is required.
Enterprise SaaS customers can configure SSO with their own identity provider (Entra ID, Okta, Auth0). Contact your CrewAI account team to enable custom SSO for your organization. Once configured:
crewai enterprise configure| Setting | Default Value |
|---|---|
enterprise_base_url | https://app.crewai.com |
oauth2_provider | workos |
oauth2_domain | login.crewai.com |
Factory (self-hosted) deployments require you to configure SSO by setting environment variables in your Helm values.yaml and registering an application in your identity provider.
| Display Name | Value | Allowed Member Types |
|---|---|---|
| Member | `member` | Users/Groups |
| Factory Admin | `factory-admin` | Users/Groups |
<Note>
The `member` role grants login access. The `factory-admin` role grants admin panel access. Roles are included in the JWT automatically.
</Note>
secrets:
ENTRA_ID_CLIENT_ID: "<Application (client) ID>"
ENTRA_ID_CLIENT_SECRET: "<Client Secret>"
ENTRA_ID_TENANT_ID: "<Directory (tenant) ID>"
```
1. Under **Authentication** → **Advanced settings**, enable **Allow public client flows**
2. Under **Expose an API**, add an Application ID URI (e.g., `api://crewai-cli`)
3. Add a scope (e.g., `read`) with **Admins and users** consent
4. Under **Manifest**, set `accessTokenAcceptedVersion` to `2`
5. Add environment variables:
```yaml
secrets:
ENTRA_ID_DEVICE_AUTHORIZATION_CLIENT_ID: "<Application (client) ID>"
ENTRA_ID_CUSTOM_OPENID_SCOPE: "<scope URI, e.g. api://crewai-cli/read>"
```
<Warning>
The authorization server name and audience must match `OKTA_AUTHORIZATION_SERVER` and `OKTA_AUDIENCE` exactly. Mismatches cause `401 Unauthorized` or `Invalid token: Signature verification failed` errors.
</Warning>
secrets:
OKTA_CLIENT_ID: "<Okta app client ID>"
OKTA_CLIENT_SECRET: "<Okta client secret>"
OKTA_SITE: "https://your-domain.okta.com"
OKTA_AUTHORIZATION_SERVER: "default"
OKTA_AUDIENCE: "api://default"
```
```yaml
secrets:
OKTA_DEVICE_AUTHORIZATION_CLIENT_ID: "<Native app client ID>"
```
<Note>
Device Authorization requires a **Native Application** — it cannot use the Web Application created for browser-based SSO.
</Note>
secrets:
KEYCLOAK_CLIENT_ID: "<client ID>"
KEYCLOAK_CLIENT_SECRET: "<client secret>"
KEYCLOAK_SITE: "https://keycloak.yourdomain.com"
KEYCLOAK_REALM: "<realm name>"
KEYCLOAK_AUDIENCE: "account"
# Only set if using a custom base path (pre-v17 migrations):
# KEYCLOAK_BASE_URL: "/auth"
```
<Note>
Keycloak includes `account` as the default audience in access tokens. For most installations, `KEYCLOAK_AUDIENCE=account` works without additional configuration. See [Keycloak audience documentation](https://www.keycloak.org/docs/latest/authorization_services/index.html) if you need a custom audience.
</Note>
```yaml
secrets:
KEYCLOAK_DEVICE_AUTHORIZATION_CLIENT_ID: "<CLI client ID>"
```
secrets:
WORKOS_CLIENT_ID: "<WorkOS client ID>"
WORKOS_AUTHKIT_DOMAIN: "<your-authkit-domain.authkit.com>"
```
secrets:
AUTH0_CLIENT_ID: "<Auth0 client ID>"
AUTH0_CLIENT_SECRET: "<Auth0 client secret>"
AUTH0_DOMAIN: "<your-tenant.auth0.com>"
```
The CrewAI CLI supports SSO authentication via the Device Authorization Grant flow. This allows developers to authenticate from their terminal without exposing credentials.
For Factory installations, the CLI can auto-configure all OAuth2 settings:
crewai enterprise configure https://your-factory-url.app
This command fetches the SSO configuration from your Factory instance and sets all required CLI parameters automatically.
Then authenticate:
crewai login
If you need to configure the CLI manually, use crewai config set:
# Set the provider
crewai config set oauth2_provider okta
# Set provider-specific values
crewai config set oauth2_domain your-domain.okta.com
crewai config set oauth2_client_id your-client-id
crewai config set oauth2_audience api://default
# Set the enterprise base URL
crewai config set enterprise_base_url https://your-factory-url.app
| Setting | Description | Example |
|---|---|---|
enterprise_base_url | Your CrewAI instance URL | https://crewai.yourcompany.com |
oauth2_provider | Provider name | workos, okta, auth0, entra_id, keycloak |
oauth2_domain | Provider domain | your-domain.okta.com |
oauth2_client_id | OAuth2 client ID | 0oaqnwji7pGW7VT6T697 |
oauth2_audience | API audience identifier | api://default |
View current configuration:
crewai config list
crewai login — the CLI requests a device code from your IdPCrewAI Platform provides granular RBAC that integrates with your SSO provider.
| Permission | Description |
|---|---|
| Read | View resources (dashboards, automations, logs) |
| Write | Create and modify resources |
| Manage | Full control including deletion and configuration |
Permissions can be scoped to individual resources:
For Factory deployments using Entra ID, admin access is controlled via App Roles:
factory-admin role to users who need admin panel accessmember role for standard platform accessSymptom: Authentication fails with a redirect URI mismatch error.
Fix: Ensure the redirect URI in your IdP exactly matches the expected callback URL:
| Provider | Callback URL |
|---|---|
| Entra ID | https://<domain>/auth/entra_id/callback |
| Okta | https://<domain>/auth/okta/callback |
| Keycloak | https://<domain>/auth/keycloak/callback |
| WorkOS | https://<domain>/auth/workos/callback |
| Auth0 | https://<domain>/auth/auth0/callback |
Symptom: crewai login returns an error or times out.
Fix:
*_DEVICE_AUTHORIZATION_CLIENT_ID environment variable is set on the serverSymptom: Invalid token: Signature verification failed or 401 Unauthorized after login.
Fix:
OKTA_AUTHORIZATION_SERVER and OKTA_AUDIENCE match the authorization server's Name and Audience exactlyaccessTokenAcceptedVersion is set to 2 in the app manifestKEYCLOAK_AUDIENCE matches the audience in your access tokens (default: account)Symptom: Users can't log in, see "needs admin approval" message.
Fix: Go to Enterprise applications → your app → Permissions → Grant admin consent. Ensure User.Read is granted for Microsoft Graph.
Symptom: User authenticates successfully but gets 403 errors.
Fix:
Symptom: crewai enterprise configure fails to connect.
Fix:
enterprise_base_url is set correctly: crewai config list| Variable | Description |
|---|---|
AUTH_PROVIDER | Authentication provider: entra_id, okta, workos, auth0, keycloak, local |
| Variable | Required | Description |
|---|---|---|
ENTRA_ID_CLIENT_ID | ✅ | Application (client) ID from Azure |
ENTRA_ID_CLIENT_SECRET | ✅ | Client secret from Azure |
ENTRA_ID_TENANT_ID | ✅ | Directory (tenant) ID from Azure |
ENTRA_ID_DEVICE_AUTHORIZATION_CLIENT_ID | CLI only | Client ID for Device Authorization Grant |
ENTRA_ID_CUSTOM_OPENID_SCOPE | CLI only | Custom scope from "Expose an API" (e.g., api://crewai-cli/read) |
| Variable | Required | Description |
|---|---|---|
OKTA_CLIENT_ID | ✅ | Okta application client ID |
OKTA_CLIENT_SECRET | ✅ | Okta client secret |
OKTA_SITE | ✅ | Okta organization URL (e.g., https://your-domain.okta.com) |
OKTA_AUTHORIZATION_SERVER | ✅ | Authorization server name (e.g., default) |
OKTA_AUDIENCE | ✅ | Authorization server audience (e.g., api://default) |
OKTA_DEVICE_AUTHORIZATION_CLIENT_ID | CLI only | Native app client ID for Device Authorization |
| Variable | Required | Description |
|---|---|---|
WORKOS_CLIENT_ID | ✅ | WorkOS application client ID |
WORKOS_AUTHKIT_DOMAIN | ✅ | AuthKit domain (e.g., your-domain.authkit.com) |
| Variable | Required | Description |
|---|---|---|
AUTH0_CLIENT_ID | ✅ | Auth0 application client ID |
AUTH0_CLIENT_SECRET | ✅ | Auth0 client secret |
AUTH0_DOMAIN | ✅ | Auth0 tenant domain (e.g., your-tenant.auth0.com) |
| Variable | Required | Description |
|---|---|---|
KEYCLOAK_CLIENT_ID | ✅ | Keycloak client ID |
KEYCLOAK_CLIENT_SECRET | ✅ | Keycloak client secret |
KEYCLOAK_SITE | ✅ | Keycloak server URL |
KEYCLOAK_REALM | ✅ | Keycloak realm name |
KEYCLOAK_AUDIENCE | ✅ | Token audience (default: account) |
KEYCLOAK_BASE_URL | Optional | Base URL path (e.g., /auth for pre-v17 migrations) |
KEYCLOAK_DEVICE_AUTHORIZATION_CLIENT_ID | CLI only | Public client ID for Device Authorization |