Skip to content

feat: ServiceAccount with ID token option#4474

Open
lpezet wants to merge 1 commit intogoogle:mainfrom
lpezet:feat/service-account-id-token
Open

feat: ServiceAccount with ID token option#4474
lpezet wants to merge 1 commit intogoogle:mainfrom
lpezet:feat/service-account-id-token

Conversation

@lpezet
Copy link

@lpezet lpezet commented Feb 13, 2026

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
ServiceAccountCredentialExchanger implementation is restricted to OAuth2-type tokens (access token).
For Service-to-Service authentication, ID token+audience is needed.

Solution:
Provide attributes in ServiceAccount auth config to specify ID token-type auth.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

NB: Some of test_cli_deploy.py fail for me but I have not changed anything there:

FAILED tests/unittests/cli/utils/test_cli_deploy.py::TestValidateAgentImport::test_success_with_app_export - click.exceptions.ClickException: Failed to import agent module:
FAILED tests/unittests/cli/utils/test_cli_deploy.py::TestValidateAgentImport::test_raises_on_import_error - assert 'nonexistent_module' in "Failed to import agent module:\nNo module named 'test_raises_on_import_error0'\n\nPlease ensure all dependencies are ... omitting --validate-agent-import (default) or passing --skip-agent-import-validat...
FAILED tests/unittests/cli/utils/test_cli_deploy.py::TestValidateAgentImport::test_cleans_up_sys_modules - click.exceptions.ClickException: Failed to import agent module:

Manual End-to-End (E2E) Tests:

In my setup I have a custom MCP Server deployed to Cloud Run running under a SA "producer", NOT public, and with a SA "consumer" granted "role/run.invoker" on that service.

  1. Create VM instance with SA "consumer"
gcloud compute instances create adk-test-instance \
    --zone=us-central1-a \
    --machine-type=e2-micro \
    --image-family=ubuntu-2204-lts \
    --image-project=ubuntu-os-cloud \
    --service-account=$SA \
    --scopes=https://www.googleapis.com/auth/cloud-platform
  1. SSH into instance
gcloud compute ssh adk-test-instance --zone=$ZONE
  1. Clone branch and set things up
git clone --single-branch --branch feat/service-account-id-token https://github.com/lpezet/adk-python.git
cd adk-python
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uv venv --python "python3.11" ".venv"
source .venv/bin/activate
uv sync --all-extras
  1. Create test
mkdir tests/integration/fixture/adk_id_token/
cd tests/integration/fixture/adk_id_token/
echo "from . import agent" > __init__.py
vi agent.py

Paste the following:

import os
from google.adk import Agent
from google.genai import types

from google.adk.tools.mcp_tool.mcp_toolset import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
from google.adk.auth.auth_credential import AuthCredential, AuthCredentialTypes, ServiceAccount

from fastapi.openapi.models import OAuth2
from fastapi.openapi.models import OAuthFlowClientCredentials
from fastapi.openapi.models import OAuthFlows

# Check necessary environment variables
MCP_BASE_URL = os.getenv("MCP_BASE_URL") # custom remote MCP server base URL, deployed in say Cloud Run or GCE, e.g. "https://your-service-xyz-uc.a.run.app"
if not MCP_BASE_URL:
  raise ValueError(
      "MCP_BASE_URL environment variable is not set. Please set it"
      " to the MCP URL."
  )

SCOPES = {"https://www.googleapis.com/auth/cloud-platform": ""}

auth_scheme=OAuth2(
    flows=OAuthFlows(
        clientCredentials=OAuthFlowClientCredentials(
            tokenUrl="https://oauth2.googleapis.com/token",
            scopes=SCOPES,
        )
    )
)
auth_credential = AuthCredential(
    auth_type=AuthCredentialTypes.SERVICE_ACCOUNT, service_account=ServiceAccount(use_default_credential = True, scopes=SCOPES.keys(), token_kind="id_token", audience=MCP_BASE_URL)
)
mcp_toolset = McpToolset(
    connection_params=StreamableHTTPConnectionParams(url=f"{MCP_BASE_URL}/mcp"),
    auth_scheme=auth_scheme,
    auth_credential=auth_credential,
)

root_agent = Agent(
    model="gemini-2.5-flash",
    name="agent",
    description="A helpful assistant to talk to.",
    instruction="""You are a helpful assistant to talk to.
    """,
    tools=[mcp_toolset],
)
  1. Run adk
cd tests/integration/fixture/
ask run adk_id_token
  1. Test MCP tool calls

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

@gemini-code-assist
Copy link
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@lpezet lpezet changed the title ServiceAccount with ID token option feat: ServiceAccount with ID token option Feb 13, 2026
@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Feb 13, 2026
@ryanaiagent ryanaiagent self-assigned this Feb 13, 2026
@ryanaiagent
Copy link
Collaborator

/gemini review

@gemini-code-assist
Copy link
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ServiceAccountCredentialExchanger: ID Token kind

3 participants