Note: You will need: GCP project owner / editor access, and Azure subscription access to the App Service(s). Steps are split into GCP Admin and Azure Client.
GCP Console → APIs & Services → Library → search each name → EnableGCP Console → IAM & Admin → Workload Identity Federation → Create Pool| Field | Value |
|---|---|
| Name | e.g. wif-azure-prod |
| Pool ID | Automatically derived from name (lowercase, hyphens). Note this down — used later. |
| Description | Optional. e.g. "Azure App Service WIF for [your project]" |
| Enabled | Checked (ON) |
| Field | Value |
|---|---|
| Select a provider | OpenID Connect (OIDC) |
| Provider Name | e.g. Azure Provider (display name only) |
| Provider ID | e.g. azure-provider (URL-safe, lowercase — note this down) |
| Issuer (URL) | https://login.microsoftonline.com/{TENANT_ID}/v2.0 |
| Allowed Audiences | fb60f99c-7a34-4190-8149-302f77469936 |
{TENANT_ID}.https://login.microsoftonline.com/<tenant_id>/v2.0Warning: The issuer URL must end in /v2.0. Azure App Service Managed Identity issues v2.0 tokens. Without/v2.0the token exchange will fail withinvalid_grant: issuer mismatch.
fb60f99c-7a34-4190-8149-302f77469936google.subject = assertion.subgoogle.subject mapping is mandatory — it becomes the value used in principal-set bindings (the Object ID / sub claim from Azure).GCP Console → IAM & Admin → Service Accounts → + Create Service Account| Field | Value |
|---|---|
| Service Account Name | e.g. ejento-service-account |
| Service Account ID | Auto-filled. Note the full email — format: {id}@{project}.iam.gserviceaccount.com |
| Description | Optional. e.g. "Used by ejento for Vertex AI calls via WIF" |
GCP Console → IAM & Admin → IAM → + Grant Accessroles/aiplatform.user)Note: Vertex AI User is the minimum required role. Do not grant broader roles (e.g. Editor) unless your use case requires it.
IAM & Admin → Service Accounts → select your Service Account → Permissions → Grant AccessprincipalSet://iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL_ID}/*roles/iam.workloadIdentityUser)principalSet://iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL_ID}/*roles/iam.workloadIdentityUser)Note: This option is broader than Option A since it trusts every identity in the pool, not just one specific App Service. Use Option A when possible for tighter scoping.
| Value / Placeholder | Where to Find / Example | Notes |
|---|---|---|
{PROJECT_NUMBER} | GCP Console → Home → Project info → Project number | Numeric, not the Project ID string |
{POOL_ID} | IAM & Admin → Workload Identity Federation → select pool → copy Pool ID e.g. azure-pool-dev | Exact ID, not display name |
{PROVIDER_ID} | Same pool page → Providers tab → Provider ID column e.g. ejento-azure | Exact ID, not display name |
{SERVICE_ACCOUNT_EMAIL} | IAM & Admin → Service Accounts → email column | Full email including @project.iam.gserviceaccount.com |