Enabling Workload Identity Federation on AKS and EKS

You are currently viewing version 1.14 of the Apigee hybrid documentation. For more information, seeSupported versions.

This topic explains how to enable Workload Identity Federation for Apigee hybrid installations onAKS andEKS platforms.

For installations onGKE, follow the instructions inEnabling Workload Identity on GKE.

Overview

Workload identity federation lets applications running outside Google Cloud impersonate a Google Cloud Platform service account by using credentials from an external identity provider.

Using workload identity federation can help you improve security by letting applications use the authentication mechanisms that the external environment provides and can helpreplace service account keys.

For an overview, seeBest practices for using Workload Identity Federation.

Note: Theapigee-logger component does not support Workload Identity Federation. See theknown issue.

Set up Workload Identity Federation

To use Workload Identity Federation with Apigee hybrid, first configure your cluster and then apply the feature to your Apigee hybrid installation.

Before you begin

These instructions assume you have already set up your Apigee hybrid installation. The IAM service accounts and Kubernetes service accounts are created during initial installation. SeeThe Big Picture for an overview of installing Apigee hybrid.

For installations onAKS, Make sure you have enabled theOpenID Connect (OIDC) issuer. You must enable this feature so that Workload Identity Federation can access the OpenID Connect metadata and the JSON Web Key Set (JWKS) for the cluster.

Note: If the cluster gets deleted for any reason, the IAM provider will need to be recreated.

Configure your cluster to use Workload Identity Federation.

  1. Check that the currentgcloud configuration is set to your Google Cloud project ID with the following command:
    gcloud config get project
  2. If needed, set the currentgcloud configuration:

    gcloud config set projectPROJECT_ID
  3. Enable the Security Token Service API:

    Check that the Security Token Service API is enabled with the following command:

    gcloud services list --enabled --projectPROJECT_ID | grep sts.googleapis.com

    If the API is not enabled:

    Console

    Enable the Security Token Service API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    Enable the API

    Command line

    Enable the API with the following command:

    gcloud services enable sts.googleapis.com --projectPROJECT_ID
  4. Create the workload identity pool and provider.

    Required roles

    To get the permissions that you need to configure Workload Identity Federation, ask your administrator to grant you the following IAM roles on the project:

    For more information about granting roles, seeManage access to projects, folders, and organizations.

    You might also be able to get the required permissions throughcustom roles or otherpredefined roles.

    Alternatively, the IAM Owner (roles/owner) basic role also includes permissions to configure identity federation. You should not grant basic roles in a production environment, but you can grant them in a development or test environment.

    To create a workload identity pool and provider, do the following:

    1. Determine the issuer URL of your AKS cluster:

      AKS

      az aks show -nNAME -gRESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv

      Replace the following:

      • NAME: The name of the cluster.
      • RESOURCE_GROUP: The resource group of the cluster.

      The command outputs the issuer URL. You will need the issuer URL in one of the following steps.

      If the command doesn't return an issuer URL, verify that you've enabled theOIDC issuer feature.

      EKS

      aws eks describe-cluster --nameNAME --query "cluster.identity.oidc.issuer" --output text

      ReplaceNAME with the name of the cluster.

      The command outputs the issuer URL. You need the issuer URL in one of the following steps.

      Other Kubernetes

      1. Connect to your Kubernetes cluster and use `kubectl` to determine your cluster's issuer URL:
        kubectl get --raw /.well-known/openid-configuration | jq -r .issuer

        You need the issuer URL in one of the following steps.

    2. Optional: If your OIDC issuer is not publicly accessible, download the cluster's JSON Web Key Set (JWKS):Note: This step requires kubectl access to your cluster.Tip: When using the JWKS file, you will need to upload a new JWKS file whenever you rotate the signing keys for the cluster.
      kubectl get --raw /openid/v1/jwks > cluster-jwks.json

      To check if your OIDC provider is publicly available, you should be able to access your provider URL with a CURL command and receive a 200 response.

    3. Create a new workload identity pool:
      gcloud iam workload-identity-pools createPOOL_ID \  --location="global" \  --description="DESCRIPTION" \  --display-name="DISPLAY_NAME"

      Replace the following:

      • POOL_ID: The unique ID for the pool.
      • DISPLAY_NAME: (Optional) The name of the pool.
      • DESCRIPTION: (Optional) A description of the pool that you choose. This description appears when you grant access to pool identities.

      For example:

      gcloudiamworkload-identity-poolscreatemy-wi-pool--display-name="My workload pool"--description="My workload pool description"
    4. Add the cluster as a workload identity pool provider. Choose the command to create the provider depending on whether your OIDC issuer ispublicly accessible ornot publicly accessible:

      Publicly accessible

      If your OIDC issuer is publicly accessible, create the provider with the following command:

      gcloud iam workload-identity-pools providers create-oidcWORKLOAD_PROVIDER_ID \  --location="global" \  --workload-identity-pool="POOL_ID" \  --issuer-uri="ISSUER" \  --attribute-mapping="google.subject=assertion.sub"

      Not publicly accessible

      If your OIDC issuer is not publicly accessible, create the provider with the following command:

        gcloud iam workload-identity-pools providers create-oidcWORKLOAD_PROVIDER_ID \  --location="global" \  --workload-identity-pool="POOL_ID" \  --issuer-uri="ISSUER" \  --jwks-file="cluster-jwks.json" \  --attribute-mapping="google.subject=assertion.sub"
      Note: If you rotate your keys, you mustupload the new JWKS with each key rotation.

      The command doesn't validate the cluster's JWKS. If the JWKS is malformed or expired, subsequent authentication attempts might fail with an error messageError connecting to the given credential's issuer.

      Replace the following:

      • WORKLOAD_PROVIDER_ID: A unique workload identity pool provider ID of your choice.
      • POOL_ID: The workload identity pool ID that you created earlier.
      • ISSUER: Use the issuer URL you determined earlier for the issuer URI .

      attribute-mapping="google.subject=assertion.sub" maps the Kubernetes subject to the IAM subject.

Create the credential configuration files

To deploy a Kubernetes workload that can access Google Cloud resources, do the You first need to create a credential configuration file for each IAM service account:

  1. List theIAM service accounts (also called "Google service accounts") with the following command:
    gcloud iam service-accounts list --projectPROJECT_ID
    Note: You most likely have already created the IAM service accounts (also called "Google service accounts") during initial installation of Apigee hybrid with thecreate-service-account tool. SeeAbout service accounts for a list of IAM service accounts needed by Apigee hybrid. SeeStep 4: Create service accounts for the installation guide procedure to create the IAM service accounts.

    You will need to create the credential configuration files for the following IAM service accounts:

    Prod

    For production environments:

    DISPLAY NAME                 EMAIL                                                              DISABLEDapigee-cassandra             apigee-cassandra@my_project_id.iam.gserviceaccount.com             Falseapigee-mart                  apigee-mart@my_project_id.iam.gserviceaccount.com                  Falseapigee-metrics               apigee-metrics@my_project_id.iam.gserviceaccount.com               Falseapigee-runtime               apigee-runtime@my_project_id.iam.gserviceaccount.com               Falseapigee-synchronizer          apigee-synchronizer@my_project_id.iam.gserviceaccount.com          Falseapigee-udca                  apigee-udca@my_project_id.iam.gserviceaccount.com                  Falseapigee-watcher               apigee-watcher@my_project_id.iam.gserviceaccount.com               False

    If you are usingMonetization for Apigee hybrid onv1.14.3 and later, you will also need to create the credential configuration file for theapigee-mint-task-scheduler service account.

    DISPLAY NAME                 EMAIL                                                              DISABLED...apigee-mint-task-scheduler   apigee-mint-task-scheduler@my_project_id.iam.gserviceaccount.com   False...

    Non-prod

    For non-production environments:

    DISPLAY NAME         EMAIL                                                      DISABLEDapigee-non-prod      apigee-non-prod@my_project_id.iam.gserviceaccount.com      False
    Tip: If you have custom names for your service accounts that do not correspond easily with the names of the Apigee components, you can determine the role of each service account by checking the roles assigned to it and comparing the roles with the roles recommended inAbout service accounts.

    Use the following command to check the roles assigned to a service account:

    gcloud projects get-iam-policyPROJECT_ID  \  --flatten="bindings[].members" \  --format='table(bindings.role)' \  --filter="SERVICE_ACCOUNT_NAME"

    Note which custom service account corresponds to each IAM SA listed in the previous list.

  2. Create a credential configuration file for each IAM service account in the previous list. You will need these credential configuration files to configure Apigee hybrid to use Workload Identity Federation:

    Code

    gcloud iam workload-identity-pools create-cred-config \  projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID \  --service-account=SERVICE_ACCOUNT_EMAIL \  --credential-source-file=/var/run/service-account/token \  --credential-source-type=text \  --output-file=SERVICE_ACCOUNT_NAME-credential-configuration.json

    Example

    gcloud iam workload-identity-pools create-cred-config \  projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider \  --service-account=apigee-cassandra@myhybridporg.iam.gserviceaccount.com \  --credential-source-file=/var/run/service-account/token \  --credential-source-type=text \  --output-file=apigee-cassandra-credential-configuration.json

    Where:

    • PROJECT_NUMBER: The project number of the project containing the workload identity pool. This must be the project number instead of the project ID.
    • POOL_ID: The ID of the workload identity pool
    • WORKLOAD_PROVIDER_ID: The ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: Email address of the service account, if you configured your Kubernetes ServiceAccount to use IAM service account impersonation.
    Important:credential-source-type must be set totext.Note: Do not create a credential configuration file for theapigee-logger service account.

    The credential configuration file lets the [Cloud Client Libraries](/apis/docs/cloud-client-libraries), the gcloud CLI, and Terraform determine the following:

    • Where to obtain external credentials from
    • Which workload identity pool and provider to use
    • Which service account to impersonate
    Note: Unlike aservice account key, a credential configuration file doesn't contain a private key and doesn't need to be kept confidential. Details about the credential configuration file are available athttps://google.aip.dev/auth/4117.

    Configure Apigee hybrid to use Workload Identity Federation

    Tip: You can configure your hybrid installation to use Workload Identity Federation for any or all components. For example UDCA can use Workload Identity Federation while Synchronizer uses Google IAM service accounts or vice versa.
    1. Copy or move each output file (SERVICE_ACCOUNT_NAME-credential-configuration.json) into the following chart directories (or subdirectories thereof). These were the files you created in theCreate the credential configuration files step.

      Prod

      Service accountApigee Helm chart directory
      apigee-cassandraapigee-datastore/
      apigee-martapigee-org/
      apigee-metricsapigee-telemetry/
      apigee-mint-task-scheduler
      (If usingMonetization for Apigee hybrid)
      apigee-org/
      apigee-runtimeapigee-env/
      apigee-synchronizerapigee-env/
      apigee-udcaapigee-org/
      apigee-env/
      apigee-watcherapigee-org/

      Non-prod

      Service accountApigee Helm chart
      apigee-non-prodapigee-datastore/
      apigee-telemetry/
      apigee-org/
      apigee-env/
    2. Make the following global changes to your cluster's overrides file:

      Code

      gcp:  workloadIdentity:    enabled:false # must be set to false to use Workload Identity Federation  federatedWorkloadIdentity:    enabled:true    audience: "AUDIENCE"    credentialSourceFile: "/var/run/service-account/token"

      Example

      gcp:  workloadIdentity:    enabled: false  federatedWorkloadIdentity:    enabled: true    audience: "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider"    credentialSourceFile: "/var/run/service-account/token"
      Note: See

      Where:AUDIENCE is the allowed audience of the Workload Identity Provider. You can find the value by searching any of the credential configuration files for the termaudience:. The audience value is the same in each credential configuration file.

      For example, in the following sampleapigee-udca-credential-configuration.json file:

      {  "universe_domain": "googleapis.com",  "type": "external_account:,"  "audience": "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider",  "subject_token_type": "urn:ietf:params:oauth: token-type:jwt",  "token_url": "https://sts.googleapis.com/v1/token",  "service  "impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/apigee-udca@myhybridproject.iam.gserviceaccount.com:generateAccessToken",  "credential_source": {    "file": "/var/run/service-account/token",    "format": {      "type": "text"    }  }}

      The audience value is//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider.

    3. Configure the overrides for each component using Workload Identity Federation. Select the instructions for cert files, Kubernetes secrets, or Vault as appropriate for your installation.

      Cert file

      Replace the value ofserviceAccountPath with the credential source file for the corresponding IAM service account. This must be the path relative to the chart directory. For example:

      envs:- name:ENVIRONMENT_NAME  serviceAccountPaths:    synchronizer:apigee-synchronizer-credential-configuration.json    runtime:apigee-runtime-credential-configuration.json    udca:apigee-udca-credential-configuration.jsonmart:  serviceAccountPath:apigee-mart-credential-configuration.jsonconnectAgent:  serviceAccountPath:apigee-mart-credential-configuration.jsonmetrics:  serviceAccountPath:apigee-metrics-credential-configuration.jsonmintTaskScheduler: # Required forMonetization for Apigee hybrid (v1.14.3 and later)  serviceAccountPath:apigee-mint-task-scheduler-credential-configuration.jsonudca:  serviceAccountPath:apigee-udca-credential-configuration.jsonwatcher:  serviceAccountPath:apigee-watcher-credential-configuration.json

      K8s Secret

      1. Create a new Kubernetes secret using the credential source file for each credential configuration file.
        kubectl create secret -nAPIGEE_NAMESPACE genericSECRET_NAME --from-file="client_secret.json=CREDENTIAL_CONFIGURATION_FILE"

        For example:

        kubectl create secret -n apigee generic udca-workoad-identity-secret --from-file="client_secret.json=./apigee-udca-credential-configuration.json"
      2. Replace the value ofserviceAccountRef with the new secret. For example:
        udca:  serviceAccountRef: udca-workoad-identity-secret

      Vault

      Update the service account key,SAKEY for each service account in Vault with the corresponding credential source file. The procedure is similar for all components. For example, for UDCA:

      SAKEY=$(cat .apigee-udca-credential-configuration.json); kubectl -nAPIGEE_NAMESPACE exec vault-0 -- vault kv patch secret/apigee/orgsakeys udca="$SAKEY"

      SeeStoring service account keys in Hashicorp Vault for more information.

    4. Apply the changes to each affected component with thehelm upgrade command:

      If you updated the Vault service account keys, update theapigee-operator chart.

      helm upgrade operator apigee-operator/ \  --namespaceAPIGEE_NAMESPACE \  --atomic \  -foverrides.yaml

      Update the rest of the affected charts in the following order:

      helm upgrade datastore apigee-datastore/ \  --namespaceAPIGEE_NAMESPACE \  --atomic \  -foverrides.yaml
      helm upgrade telemetry apigee-telemetry/ \  --namespaceAPIGEE_NAMESPACE \  --atomic \  -foverrides.yaml
      helm upgrade$ORG_NAME apigee-org/ \  --namespaceAPIGEE_NAMESPACE \  --atomic \  -foverrides.yaml

      Update theapigee-env chart for each env, replacing$ENV_RELEASE_NAME abdENV_NAME each time:

      helm upgrade$ENV_RELEASE_NAME apigee-env/ \  --namespaceAPIGEE_NAMESPACE \  --atomic \  --set env=$ENV_NAME \  -foverrides.yaml

      See theApigee hybrid Helm reference for a list of components and their corresponding charts.

    Grant the access to the Kubernetes service accounts

    1. List theKubernetes service accounts with the following command:
      kubectl get sa -nAPIGEE_NAMESPACE
      Note: The Apigee hybrid charts created the necessary Kubernetes service accounts for each component when you ran thehelm upgrade commands.Important: You will not be using every Kubernetes service account that is listed by this command.
    2. Grant the Kubernetes service accounts access to impersonate the associated IAM service accounts as shown in the following table. The table shows the default Apigee IAM service account names. If you are using custom service account names, use the corresponding IAM service accounts:
      Kubernetes service accountsIAM service account
      Org-level Kubernetes service accounts
      apigee-connect-agent-ORG_NAME-ORG_HASH_IDapigee-mart
      apigee-mart-ORG_NAME-ORG_HASH_IDapigee-mart
      apigee-metrics-apigee-telemetryapigee-metrics
      apigee-open-telemetry-collector-apigee-telemetryapigee-metrics
      apigee-mint-task-scheduler-ORG_NAME-ORG_HASH_ID
      (If usingMonetization for Apigee hybrid onv1.14.3 and later)
      apigee-mint-task-scheduler
      apigee-udca-ORG_NAME-ORG_HASH_IDapigee-udca
      apigee-watcher-ORG_NAME-ORG_HASH_IDapigee-watcher
      Env-level Kubernetes service accounts
      apigee-runtime-ORG_NAME-ENV_NAME-ENV_HASH_IDapigee-runtime
      apigee-synchronizer-ORG_NAME-ENV_NAME-ENV_HASH_IDapigee-synchronizer
      Cassandra backup and restore (if enabled)
      apigee-cassandra-backup-saapigee-cassandra
      apigee-cassandra-restore-saapigee-cassandra

      Where:

      • ORG_NAME: The first 15 characters of the name of your organization.
      • ORG_HASH_ID: A unique hash ID of your full organization name.
      • ENV_NAME: The first 15 characters of the name of your environment.
      • ENV_HASH_ID: A unique hash ID of your organization and environment names.

      For example:

      • apigee-connect-agent-myhybridorg-123abcd
      • apigee-runtime-myhybridorg-prodenv-234bcde
      Important: You will need to repeat this step for each environment.

      Grant each Kubernetes service account access to impersonate the appropriate IAM service account with the following command:

      gcloud iam service-accounts add-iam-policy-binding \IAM_SA_NAME@PROJECT_ID.iam.gserviceaccount.com \    --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \    --role=roles/iam.workloadIdentityUser

      Where:

      Note: You must use theproject number in the member identifier. Using the project ID is not supported.

    For more information about Workload Identity Federation and best practices, seeBest practices for using workload identity federation.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.