ApplicationIntegrationToolset oauth

Hi All,

I’ve been testing out agent development using an ApplicationIntegrationToolset and Integration connector for gemini enterprise and have been having issues with oauth. When i run the agent locally with adk web everything works exactly as i expect it to but when i publish it to agent engine and add it into gemini enterprise the oauth workflow doesn’t seem to run correctly. The popup to grant authorization never renders/opens when uploaded. I built out the example google calendar agent for testing and sanity checking and its behaving exactly like my agent. See example code below:

agent.py

from google.adk.agents.llm_agent import Agent
from .calendar import connector_tool


root_agent = Agent(
    model='gemini-2.5-flash',
    name='Calendar_agent_test',
    description='A helpful assistant for interacting with Calendar.',
    instruction="""Interact with Calendar using this Agent""",
    tools=[connector_tool]
)

calendar.py

from google.adk.tools.application_integration_tool.application_integration_toolset import ApplicationIntegrationToolset
from google.adk.tools.openapi_tool.auth.auth_helpers import dict_to_auth_scheme
from google.adk.auth import AuthCredential, AuthCredentialTypes, OAuth2Auth
from fastapi.openapi.models import OAuth2, OAuthFlowAuthorizationCode, OAuthFlows



project_id = <project-id>

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": "View and manage your data across Google Cloud Platform services",
              "https://www.googleapis.com/auth/calendar.readonly": "View your calendars"
            },
        )
    )
)

auth_credential = AuthCredential(
  auth_type=AuthCredentialTypes.OAUTH2,
  oauth2=OAuth2Auth(
      client_id=<client-id>,
      client_secret=<client-secret>, 
  ),
)

connector_tool = ApplicationIntegrationToolset(
    project=project_id,
    location="us-central1", 
    connection="test-calendar",
    entity_operations={
        "AllCalendars":["GET","LIST", "CREATE", "UPDATE"],
        "Calendars": ["GET","LIST", "CREATE", "UPDATE"],
    },
    actions=["ListCalendarEvents","GetCalendarEvent"], #replace with actions. this one is for list events
    tool_name_prefix="calendar",
    tool_instructions="use this tool to query your google calendar",
    auth_scheme=auth_scheme,
    auth_credential=auth_credential
)

If anyone has a suggestion on how to get the authorization window to open once the agent is uploaded into agent engine and added into gemini enterprise it would be much appreciated!

Edit: Adding a screenshot for clarity of what isn’t working. The box in the red square doesn’t render/open once the same agent is uploaded to agent engine and added to gemini enterprise. This one is from a Jira agent but it’s the same behavior with any agent using oauth including the example above.

Hi @scuffe_cdw, welcome to the forum :slight_smile:

We’ll keep your question on the radar to ensure it gets noticed and encourage the community to share their thoughts. In the meantime, feel free to check out the curated content from Googlers in the Knowledge Hub and on-demand videos.

Hi Spencer, thanks for the question. There is a difference in how/what manages the OAuth flow when running it locally in adk web vs when deployed and surfaced up in Gemini Enterprise via Agent Engine.

Gemini Enterprise manages it’s own OAuth config and the access tokens when they are minted.

The workaround for the moment is to use a before tool callback to retrieve the access token which is now managed in Gemini Enterprise. Once you have the token, you can inject it for the connector tool call.

Putting it all together you should be able to use the example code (incomplete) below.

DYNAMIC_AUTH_PARAM_NAME = "dynamic_auth_config" # Name of the parameter to inject
DYNAMIC_AUTH_INTERNAL_KEY = "oauth2_auth_code_flow.access_token" # Internal key for the token
AUTH_ID = "ge-auth-id"

def inject_auth_token(callback_context, tool):
    # auth_id is your OAuth resource you created for Gemini Enterprise https://docs.cloud.google.com/gemini/enterprise/docs/register-and-manage-an-adk-agent#add-authorization-resource
    auth_id = AUTH_ID
    access_token = callback_context.state.get(auth_id)
    if access_token:
        dynamic_auth_config = {DYNAMIC_AUTH_INTERNAL_KEY: access_token}
        args[DYNAMIC_AUTH_PARAM_NAME] = json.dumps(dynamic_auth_config)
    return None

sfdc_connector_tool = ApplicationIntegrationToolset(
    project=CONNECTION_PROJECT_ID, 
    location=CONNECTION_REGION, 
    connection=CONNECTION_NAME,
    tool_name_prefix="sfdc_tool",
    entity_operations={
        "Account": ["GET", "LIST"],
    },
    tool_instructions=TOOL_INSTR,
)

root_agent = Agent(
    model='gemini-2.5-flash',
    name='salesforce_agent',
    description="SalesForce Agent to get details on accounts and contacts.",
    instruction=ROOT_AGENT_INSTR,
    tools= [sfdc_connector_tool],
    # before_tool_callback=[inject_auth_token]
)

This is a workaround for the moment. There are some upcoming changes/fixes which will make this more streamlined. Ref: ApplicationIntegrationToolset not picking up Gemini Enterprise Authorization · Issue #4553 · google/adk-python · GitHub

HTH

1 Like