-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Describe the bug
When I use a AuthenticatedFunctionTool, only the first call of the first user is asked for authentication. Then, the other users, on the same instance won't have to authenticate themselves. They are considered as authenticated
To Reproduce
Please share a minimal code and data to reproduce your problem.
Steps to reproduce the behavior:
Here the sample agent
import requests
from fastapi.openapi.models import OAuth2, OAuthFlows, OAuthFlowAuthorizationCode
from google.adk.agents.llm_agent import Agent
from google.adk.auth import AuthCredential, AuthCredentialTypes, OAuth2Auth, AuthConfig
from google.adk.auth.credential_service.session_state_credential_service import SessionStateCredentialService
from google.adk.tools import ToolContext
from google.adk.tools.authenticated_function_tool import AuthenticatedFunctionTool
YOUR_OAUTH_CLIENT_ID = "<redacted>"
YOUR_OAUTH_CLIENT_SECRET = "<redacted>"
def log_tool(prompt: str, tool_context: ToolContext) -> None:
"""
Log the user query with the log_tool
:param prompt: The user query to log
:param tool_context: The tool context to access credentials
:return: None
"""
print(f"DEBUG: Received prompt: {prompt}")
# Make a POST request on this URL
url = f"https://<redacted>.us-central1.run.app?prompt={prompt}"
headers = {}
# Retrieve the credential using the context and auth config
exchanged_credential = tool_context.get_auth_response(auth_config)
if exchanged_credential and exchanged_credential.oauth2:
# Log the token for debug purposes as requested
print(f"DEBUG: Found credential for user {tool_context.user_id}")
token = exchanged_credential.oauth2.access_token
print(f"DEBUG: Access Token: {token[:10]}... (truncated)")
headers = {"Authorization": f"Bearer {token}"}
else:
print("DEBUG: No credential found in tool_context")
print(f"DEBUG: Sending request to {url}")
print(f"DEBUG: Headers: {headers}")
response = requests.get(url, headers=headers)
print(f"DEBUG: Response: {response.text}")
auth_scheme = OAuth2(
flows=OAuthFlows(
authorizationCode=OAuthFlowAuthorizationCode(
authorizationUrl="https://accounts.google.com/o/oauth2/auth",
tokenUrl="https://oauth2.googleapis.com/token",
scopes={
"https://www.googleapis.com/auth/cloud-platform": "Cloud Run"
},
)
)
)
auth_credential = AuthCredential(
auth_type=AuthCredentialTypes.OAUTH2,
oauth2=OAuth2Auth(
client_id=YOUR_OAUTH_CLIENT_ID,
client_secret=YOUR_OAUTH_CLIENT_SECRET
),
)
auth_config = AuthConfig(
auth_scheme=auth_scheme,
raw_auth_credential= auth_credential
)
authenticated_log_tool = AuthenticatedFunctionTool(func=log_tool, auth_config=auth_config, response_for_auth_required="Pending User Authorization.")
credential_service = SessionStateCredentialService()
root_agent = Agent(
model='gemini-2.5-flash',
name='root_agent',
description='A helpful assistant for user questions.',
instruction='Answer user questions to the best of your knowledge. Log the user query with the log_tool',
tools=[authenticated_log_tool]
)
Run the agent adk web
Then perform a first OAuth flow with a user, change the user (in the URL address bar) and ask a question. The 2nd user and the 2nd session won't have OAuth challenge
Expected behavior
Have a OAuth challenge with different user, not the first one
Desktop (please complete the following information):
- OS: Windows with WSL Unbuntu 24
- Python version(python -V): python 3.12
- ADK version(pip show google-adk): adk 1.19.0
Model Information:
- Which model is being used(e.g. gemini-2.5-pro) Gemini 2.5 flash
Additional context
By commenting this line and the following one, the problem disappeared. I don't understand why the exchange check is not dependent of the callback_context. Maybe the bug??