-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Bug #4458 #4467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
P-nishant
wants to merge
2
commits into
google:main
Choose a base branch
from
P-nishant:bug_#4458
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+293
−2
Open
Bug #4458 #4467
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| # Fix: ID Token support for Cloud Run MCP auth | ||
|
|
||
| ## Why | ||
|
|
||
| Cloud Run (and Cloud Functions, IAP, etc.) with "Require authentication" expects | ||
| an **OIDC ID Token**, not an OAuth2 access token. The | ||
| `ServiceAccountCredentialExchanger` always fetched an access token via | ||
| `credentials.token`, so calls to authenticated Cloud Run services failed with | ||
| `401 Unauthorized`. | ||
|
|
||
| There was no way for users to ask for an ID token — the only workaround was | ||
| monkey-patching the exchanger at runtime. | ||
|
|
||
| ## What changed | ||
|
|
||
| ### `ServiceAccount` model (`src/google/adk/auth/auth_credential.py`) | ||
|
|
||
| Two new optional fields: | ||
|
|
||
| - **`use_id_token`** (`bool`, default `False`) — when `True`, fetch an ID token | ||
| instead of an access token. | ||
| - **`audience`** (`str`) — the target audience for the ID token, typically the | ||
| service URL. Required when `use_id_token` is `True`. | ||
|
|
||
| `scopes` also got a default (`[]`) so callers using ID tokens don't have to pass | ||
| an empty list. | ||
|
|
||
| ### `ServiceAccountCredentialExchanger` (`src/google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py`) | ||
|
|
||
| Added a `_fetch_id_token` helper and a branch at the top of `exchange_credential` | ||
| that calls it when `use_id_token` is set. The existing access-token path is | ||
| untouched. | ||
|
|
||
| For default credentials it uses `google.oauth2.id_token.fetch_id_token()`. For | ||
| explicit service-account JSON keys it uses | ||
| `service_account.IDTokenCredentials.from_service_account_info()`. | ||
|
|
||
| ### Tests | ||
|
|
||
| Four new tests covering: default-credential ID token, explicit-SA ID token, | ||
| missing audience validation, and fetch failure handling. All existing tests still | ||
| pass. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```python | ||
| auth_credential = AuthCredential( | ||
| auth_type=AuthCredentialTypes.SERVICE_ACCOUNT, | ||
| service_account=ServiceAccount( | ||
| use_default_credential=True, | ||
| use_id_token=True, | ||
| audience="https://my-service-xyz.us-central1.run.app/mcp", | ||
| ), | ||
| ) | ||
|
|
||
| mcp_toolset = McpToolset( | ||
| connection_params=StreamableHTTPConnectionParams(url=MCP_URL), | ||
| auth_scheme=HTTPBearer(bearerFormat="JWT"), | ||
| auth_credential=auth_credential, | ||
| ) | ||
| ``` | ||
|
|
||
| ## PR Description (ready to paste) | ||
|
|
||
| ### Summary | ||
|
|
||
| Cloud Run-protected MCP endpoints require an OIDC ID token, but service-account | ||
| exchange always returned an OAuth access token. This change adds an opt-in ID | ||
| token path for service account auth and keeps existing access-token behavior as | ||
| the default. | ||
|
|
||
| ### Testing Plan | ||
|
|
||
| - Run formatter (`autoformat.sh` equivalent on Windows shell): | ||
| - `.\.venv\Scripts\python.exe -m isort src\google\adk\auth\auth_credential.py src\google\adk\tools\openapi_tool\auth\credential_exchangers\service_account_exchanger.py tests\unittests\tools\openapi_tool\auth\credential_exchangers\test_service_account_exchanger.py` | ||
| - `.\.venv\Scripts\python.exe -m pyink --config pyproject.toml src\google\adk\auth\auth_credential.py src\google\adk\tools\openapi_tool\auth\credential_exchangers\service_account_exchanger.py tests\unittests\tools\openapi_tool\auth\credential_exchangers\test_service_account_exchanger.py` | ||
| - Run focused unit tests: | ||
| - `.\.venv\Scripts\python.exe -m pytest tests\unittests\tools\openapi_tool\auth\credential_exchangers\test_service_account_exchanger.py -q` | ||
| - Run related broader tests: | ||
| - `.\.venv\Scripts\python.exe -m pytest tests\unittests\tools\openapi_tool\auth\ tests\unittests\auth\test_credential_manager.py tests\unittests\tools\mcp_tool\test_mcp_tool.py -q` | ||
|
|
||
| ### Unit Test Evidence | ||
|
|
||
| - Focused exchanger tests: **11 passed in 1.59s** | ||
| - Broader auth + MCP tests: **126 passed, 336 warnings in 2.64s** | ||
|
|
||
| ### Manual E2E Evidence (MCP + Cloud Run auth) | ||
|
|
||
| > Note: This local workspace currently has no Cloud Run endpoint configured | ||
| > (`MCP_URL` and `GOOGLE_CLOUD_PROJECT` are empty), so this section is prepared | ||
| > for final evidence capture in your Cloud environment. | ||
|
|
||
| Please attach in the PR: | ||
|
|
||
| 1. A screenshot of `adk web` prompt/response where the MCP tool call succeeds. | ||
| 2. Console logs proving successful authenticated call (no 401). | ||
| 3. The exact agent config used (`use_id_token=True`, `audience=<cloud-run-url>`). | ||
|
|
||
| Suggested log snippet to include: | ||
|
|
||
| ```text | ||
| HTTP Request: POST https://<service>.run.app/mcp "HTTP/1.1 200 OK" | ||
| ... tool call result ... | ||
| ``` | ||
|
|
||
| ### Docs Impact | ||
|
|
||
| - This introduces user-facing auth fields (`use_id_token`, `audience`) for | ||
| service-account auth flow. | ||
| - Recommended follow-up: open/update a docs PR in `google/adk-docs` to document | ||
| Cloud Run authenticated MCP setup with ID token usage. | ||
|
|
||
| ### Review Request | ||
|
|
||
| - Request review from ADK auth/tooling maintainers. | ||
| - Suggested focus areas: | ||
| - Backward compatibility of service-account access-token flow. | ||
| - Correctness of ID-token exchange for ADC and explicit service-account keys. | ||
| - Error messaging when `audience` is missing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better code clarity and to leverage static type checking, please add a type hint for the
sa_configparameter. It should be of typeServiceAccount.You will also need to import
ServiceAccountfrom.....auth.auth_credential.