Skip to content

Credential Manager mix user credential #3772

@guillaumeblaquiere

Description

@guillaumeblaquiere

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??

Metadata

Metadata

Labels

needs-review[Status] The PR is awaiting review from the maintainerservices[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions