Skip to content

# ADK 1.23.0 Bug Report: Incompatibility with Workload Identity Federation + Impersonation #4370

@mathewschristopher

Description

@mathewschristopher

"A unique identifier for the entire conversation session. Used"
" to group all events belonging to a single user interaction."
),
),
bigquery.SchemaField(
"invocation_id",
"STRING",
mode="NULLABLE",
description=(
"A unique identifier for a single turn or execution within a"
" session. Groups related events like LLM request and response."
),
),
bigquery.SchemaField(
"user_id",
"STRING",
mode="NULLABLE",
description=(
"The identifier of the end-user participating in the session,"
" if available."
),
),
bigquery.SchemaField(
"trace_id",
"STRING",
mode="NULLABLE",
description=(
"OpenTelemetry trace ID for distributed tracing across services."
),
),
bigquery.SchemaField(
"span_id",
"STRING",
mode="NULLABLE",
description="OpenTelemetry span ID for this specific operation.",
),

Describe the Bug:

ADK version 1.23.0 introduces a breaking change in BigQueryAgentAnalyticsPlugin that makes it incompatible with GCP Workload Identity Federation + Service Account Impersonation authentication patterns.

Root Cause: The plugin now enforces quota_project_id via ClientOptions on BigQueryWriteAsyncClient initialization (lines 1722-1745 in bigquery_agent_analytics_plugin.py). This setting cascades to ALL API calls made with those credentials, including the IAM Credentials API call to refresh the impersonation token itself. This creates a circular dependency where the federated identity principal needs roles/serviceusage.serviceUsageConsumer permission on the quota project just to authenticate, but authentication fails before permissions can be evaluated.

Steps to Reproduce:

  1. Set up Azure DevOps pipeline with GCP Workload Identity Federation configured
  2. Configure service account impersonation (Azure OIDC token → Workload Identity Pool → Service Account)
  3. Install ADK 1.23.0: pip install google-adk==1.23.0
  4. Enable BigQueryAgentAnalyticsPlugin in your ADK agent configuration:
    BigQueryAgentAnalyticsPlugin(
        project_id="your-project-id",
        dataset_id="analytics_dataset",
        table_id="analytics_table"
    )
  5. Run the pipeline from Azure DevOps
  6. Observe authentication failure with error stack trace below

Expected Behavior:

  • ADK 1.23.0 should work with Workload Identity Federation + Service Account Impersonation patterns
  • quota_project_id should only affect billing/quota tracking for BigQuery API calls, not authentication flows
  • The BigQuery plugin should successfully initialize and log analytics data without interfering with credential refresh

Observed Behavior:

Pipeline fails immediately during authentication with the following error:

google.auth.exceptions.RefreshError: Unable to acquire impersonated credentials: 
{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "errors": [
      {
        "message": "Request had insufficient authentication scopes.",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "USER_PROJECT_DENIED",
        "domain": "googleapis.com",
        "metadata": {
          "service": "iamcredentials.googleapis.com",
          "consumer": "projects/123456789"
        }
      },
      {
        "@type": "type.googleapis.com/google.rpc.Help",
        "links": [
          {
            "description": "Google developer console API key",
            "url": "https://console.developers.google.com/project/123456789/apiui/credential"
          }
        ]
      }
    ]
  }
}

Grant the caller the roles/serviceusage.serviceUsageConsumer role on the service or project.

Authentication Flow Breakdown:

1. Azure OIDC Token → GCP Workload Identity Federation
2. Federated Identity → Impersonate Service Account (IAM Credentials API call)
   └─> quota_project_id enforced by BigQueryWriteAsyncClient initialization
       └─> Requires serviceusage.services.use permission on quota project
           └─> FAILS: Federated identity doesn't have this permission

Environment Details:

  • ADK Library Version: 1.23.0 (broken) / 1.22.1 (working)
  • Desktop OS: Linux (Azure DevOps Ubuntu pipeline agent)
  • Python Version: 3.14.2
  • google-auth Version: 2.48.0
  • google-cloud-bigquery Version: 3.40.0
  • google-cloud-aiplatform Version: 1.135.0
  • Deployment Environment: Azure DevOps Pipeline with Google Cloud Workload Identity Federation

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: gemini-3.0-flash-preview (via Vertex AI)

🟡 Optional Information

Providing this information greatly speeds up the resolution process.

Regression:

Yes - This worked perfectly in ADK 1.22.1. The issue was introduced in ADK 1.23.0 as part of the OpenTelemetry refactoring for BigQuery plugin tracing.

Problematic Code (ADK 1.23.0 source):

# File: google/adk/plugins/bigquery_agent_analytics_plugin.py
# Lines: 1722-1745

async def _get_loop_state(self) -> _LoopState:
    # ... code ...
    creds, project_id = await loop.run_in_executor(self._executor, get_credentials)
    
    # This enforces quota_project_id globally
    quota_project_id = getattr(creds, "quota_project_id", None) or project_id
    
    # Problem: This affects ALL API calls, including authentication
    options = (
        client_options.ClientOptions(quota_project_id=quota_project_id)
        if quota_project_id
        else None
    )
    
    write_client = BigQueryWriteAsyncClient(
        credentials=creds,
        client_info=client_info,
        client_options=options,  # <-- Breaks federated auth flows
    )

Logs:

Complete error trace from Azure DevOps Pipeline:

2026-02-04T11:56:25.1234567Z Traceback (most recent call last):
2026-02-04T11:56:25.1234568Z   File "/home/vsts/work/_temp/run_agent.py", line 10, in <module>
2026-02-04T11:56:25.1234569Z     result = await agent.run(input_data)
2026-02-04T11:56:25.1234570Z   File "/opt/hostedtoolcache/Python/3.14.2/x64/lib/python3.14/site-packages/google/adk/agents/base.py", line 123, in run
2026-02-04T11:56:25.1234571Z     await self._initialize_plugins()
2026-02-04T11:56:25.1234572Z   File "/opt/hostedtoolcache/Python/3.14.2/x64/lib/python3.14/site-packages/google/adk/plugins/bigquery_agent_analytics_plugin.py", line 1745, in _get_loop_state
2026-02-04T11:56:25.1234573Z     write_client = BigQueryWriteAsyncClient(credentials=creds, client_options=options)
2026-02-04T11:56:25.1234574Z   File "/opt/hostedtoolcache/Python/3.14.2/x64/lib/python3.14/site-packages/google/auth/impersonated_credentials.py", line 456, in refresh
2026-02-04T11:56:25.1234575Z     self._update_token(request)
2026-02-04T11:56:25.1234576Z google.auth.exceptions.RefreshError: Unable to acquire impersonated credentials: USER_PROJECT_DENIED

Screenshots / Video:
N/A

Additional Context:

Why Granting Role Doesn't Fix It: Granting roles/serviceusage.serviceUsageConsumer to the service account doesn't help because the error occurs during the impersonation step BEFORE the service account's permissions are evaluated. The federated identity principal would need the role, which is a security anti-pattern (grants permissions to ALL identities in the pool).

Verified Findings:

  • All 62 unit tests pass locally with ADK 1.23.0 (no federated auth in local environment)
  • Failure only occurs in pipeline with Workload Identity Federation
  • Identical dependency versions between 1.22.1 and 1.23.0
  • Issue reproduced in multiple GCP projects (UAT and POC environments)

Suggested Fixes:

  1. Don't set quota_project_id on client initialization - Only apply it to specific BigQuery operations
  2. Use request-level quota project override - Set per-request instead of per-client
  3. Add configuration flag - Allow disabling quota project enforcement:
    BigQueryAgentAnalyticsPlugin(
        project_id=project_id,
        dataset_id=dataset_id,
        table_id=table_id,
        enforce_quota_project=False,  # New parameter
    )

Minimal Reproduction Code:

import asyncio
from google.adk.agents import LlmAgent
from google.adk.plugins import BigQueryAgentAnalyticsPlugin

# Configure Workload Identity Federation authentication
# (via environment variables: GOOGLE_CLOUD_PROJECT, GOOGLE_APPLICATION_CREDENTIALS)

# Initialize agent with BigQuery analytics plugin
agent = LlmAgent(
    name="test_agent",
    model="gemini-2.0-flash-exp",
    plugins=[
        BigQueryAgentAnalyticsPlugin(
            project_id="your-gcp-project",
            dataset_id="analytics_dataset",
            table_id="analytics_table"
        )
    ]
)

# This will fail with USER_PROJECT_DENIED when using Workload Identity Federation
result = await agent.run(input_data={"query": "test"})

How often has this issue occurred?:

  • Always (100%) - Consistent failure across all pipeline runs with ADK 1.23.0 when using Workload Identity Federation + Impersonation

Impact:

  • Severity: High - Completely blocks upgrading to ADK 1.23.0+ for enterprise environments using Workload Identity Federation
  • Workaround: Staying on ADK 1.22.1 (prevents access to newer features and bug fixes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bq[Component] This issue is related to Big Query integration

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions