Skip to main content
Workload identity for LLM connections is currently available to enterprise SaaS customers on CrewAI AMP. Contact your CrewAI account team to enable it for your organization before starting this guide.

Version requirements

Use the google/ model prefix, not vertex_ai/. Workload identity requires the native Google Gen AI SDK route, which uses Application Default Credentials. The LiteLLM vertex_ai/* provider does not consume the ADC config the runtime writes, so calls will fail to authenticate.

Overview

CrewAI AMP can authenticate to Google Vertex AI using GCP Workload Identity Federation instead of long-lived service account keys. At kickoff, your crew execution fetches a short-lived OIDC token from AMP scoped to your organization and writes a Google Application Default Credentials (ADC) external_account configuration that points at it. The Google Gen AI SDK (invoked via CrewAI’s google/ model prefix) then transparently exchanges that OIDC token at GCP STS, optionally impersonates a service account, and calls Vertex AI — all in-process inside the running crew. The result:
  • No Google credentials stored in CrewAI AMP — no service account JSON keys, no API keys. AMP holds only the OIDC signing key it uses to mint tokens.
  • Trust is anchored in your GCP project. You decide which CrewAI organization can impersonate which service account.
  • The STS exchange happens inside the crew execution, not in AMP’s control plane. AMP only mints OIDC tokens; the Google credentials returned by GCP are never seen or persisted by AMP — they live and die inside a single execution.
  • Access tokens are refreshed automatically, and the underlying OIDC subject token is rotated before expiry — long-running crews are supported (with one edge case noted below).

How it works

GCP fetches AMP’s public signing keys from a standard OIDC discovery endpoint and validates each token before exchanging it. AMP never sees your GCP service account key, and the federated/SA tokens minted by GCP stay inside the crew execution that requested them — they are not returned to or persisted by AMP’s control plane.

Prerequisites

  • A GCP project with Vertex AI enabled (aiplatform.googleapis.com).
  • The gcloud CLI authenticated as a user with IAM admin on that project. See Appendix: minimum IAM for the specific roles required.
  • Your CrewAI organization UUID. Find it in CrewAI AMP at Settings → Organization (use the UUID, not the numeric ID).
  • Workload identity for LLM connections enabled on your AMP organization — contact CrewAI support.
The CrewAI AMP OIDC issuer URL is:

Part 1 — GCP setup

1

Enable required APIs

2

Create a workload identity pool

3

Create the OIDC provider inside the pool

The attribute-condition is the critical security boundary — it restricts which CrewAI organization can assume any identity from this pool. Replace YOUR_ORG_UUID with your AMP organization UUID.
YOUR_ORG_UUID must be your organization UUID (the same value used by attribute.organization in the principalSet binding below). A wrong value here is the most common cause of PERMISSION_DENIED failures during STS exchange.
Record the full provider resource name — you’ll need it in Part 2:
4

Create a Vertex AI service account

crewai-vertex is an example name — pick anything that fits your naming conventions, but use the same value in the impersonation binding (next step) and on the LLM connection (Part 2).
roles/aiplatform.user is the minimum role needed for generateContent and predict. Tighten further with custom roles if your security policy requires it.
5

Allow the pool to impersonate the service account

This is the second security boundary: only federated identities whose organization attribute matches your org UUID can impersonate this SA.

Part 2 — CrewAI AMP setup

1

Create a Workload Identity Config

In AMP, go to Settings → Workload Identity Configs → New and fill in:Creating workload identity configs requires a role with manage access to LLM connections (see RBAC).
2

Attach the config to a Vertex LLM connection

Go to LLM Connections → New (or edit an existing one) and select:
  • Provider: Vertex
  • Workload Identity Config: the config from the previous step
  • GCP Service Account Email: the SA you created in Part 1 (e.g., crewai-vertex@PROJECT_ID.iam.gserviceaccount.com)
No GOOGLE_API_KEY environment variable is required — leave that empty. For region, add a single connection-scoped env var:
  • GOOGLE_CLOUD_LOCATION=global — recommended default. Vertex’s global endpoint provides higher availability and is supported by current Gemini 2.x and 3.x models. Set a specific region (e.g. us-central1, europe-west4) if you need data residency (the global endpoint does not guarantee in-region processing) or if you plan to use Vertex features that don’t run on global (notably tuning, batch prediction for Anthropic / OpenMaaS models, and RAG corpus management — RAG requests still work on global). For chat/completion crews, global is the right choice.
Service account impersonation is configured per-connection (not per-config) so a single workload identity pool can be reused for multiple service accounts with different Vertex permissions.
3

Bind the connection to a crew or deployment

Attach the LLM connection to a crew, Studio project, or deployment exactly as you would any other LLM connection. At kickoff, the running crew will request an OIDC token from AMP for this connection’s workload identity provider and exchange it for Vertex credentials in-process — no Google credentials are stored or pushed by AMP.

Runtime behavior

For Vertex connections backed by workload identity, the crew does not receive a GOOGLE_API_KEY or service account JSON as a static deploy-time env var. Instead, at kickoff, the running crew:
  1. Fetches an OIDC token from AMP, signed with AMP’s private key and scoped to your organization (audience = your workload identity provider).
  2. Writes the JWT to a temporary file in the execution environment.
  3. Writes a Google Application Default Credentials (ADC) config of type external_account that references the JWT file, your STS audience, and (optionally) the service account impersonation URL.
  4. Sets the following environment variables for the crew process: No GOOGLE_API_KEY and no GOOGLE_CLOUD_LOCATION are set automatically. Configure GOOGLE_CLOUD_LOCATION on your LLM connection in AMP (recommended default: global).
  5. From this point on, google-auth (used by the Google Gen AI SDK) does the STS exchange and SA impersonation transparently on the first Vertex API call, and caches/refreshes the resulting access token automatically.
The crew SDK reads these like any other env var — no code changes required, provided your crew was deployed against crewai>=1.14.3 (see Version requirements).

Long-running crews

Access tokens are automatically refreshed:
  • Vertex access tokens (1-hour TTL) are refreshed by google-auth in-process, transparently to your crew code.
  • The underlying OIDC subject token (also 1-hour TTL) is rotated before expiry on every kickoff entry point. The crew fetches a fresh OIDC JWT from AMP and rewrites the ADC token file; subsequent STS exchanges pick up the new JWT.
In practice this means:
  • Crews that run for less than 1 hour never trigger a refresh — the initial token covers the whole execution.
  • Crews that run for multiple hours continue to function as long as kickoff entry points (sync hops, agent steps, etc.) fire during the execution; the refresh buffer ensures the OIDC token is rotated before STS rejects it.
  • If a single Vertex API call runs for more than 1 hour (very unusual — typical Gemini responses return in seconds), the OIDC token can expire mid-request and the call will fail. This is the one scenario where token refresh cannot help.

Verification

Run a crew that uses the Vertex connection and tail the execution logs in AMP. A successful generateContent or predict call confirms the full chain — OIDC mint → STS exchange → SA impersonation → Vertex — is wired correctly. If the crew fails, see Troubleshooting below. Most issues trace back to the GCP-side configuration — the OIDC provider’s attribute-condition or the service account’s principalSet binding.

Inspecting on the GCP side

You can confirm tokens are being exchanged by looking at Cloud Audit Logs in your GCP project:
  • Service: sts.googleapis.com → method google.identity.sts.v1.SecurityTokenService.ExchangeToken
  • Service: iamcredentials.googleapis.com → method GenerateAccessToken
A short crew execution produces one ExchangeToken and one GenerateAccessToken entry; longer executions produce additional entries each time the OIDC token is rotated. The protoPayload.authenticationInfo includes the sub and organization_id claims, useful for audit and incident response.

Troubleshooting


Security notes

  • The organization_id claim is your security boundary. Your GCP attribute condition must restrict to your organization UUID. Without it, any CrewAI AMP organization could exchange a token through your pool. The sub claim contains the same UUID prefixed with organization: — either could be used, but organization_id matches the bare-UUID form used in the attribute.organization mapping and principalSet binding.
  • Service account impersonation is the second boundary. The principalSet binding restricts impersonation to identities whose organization attribute matches your UUID. Use it even when the attribute condition is set — defense in depth.
  • Issuer trust is one-way. GCP fetches AMP’s public JWKS over HTTPS. AMP never receives any GCP credential.

Appendix: minimum IAM for setup

The user running the gcloud commands above needs, on the target project:
  • roles/iam.workloadIdentityPoolAdmin — create pools and providers
  • roles/iam.serviceAccountAdmin — create service accounts
  • roles/resourcemanager.projectIamAdmin — bind project-level roles
  • roles/serviceusage.serviceUsageAdmin — enable required APIs
Or, equivalently, roles/owner on the project.