Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

OpenAPIToolset does not support tools (endpoints) that have multiple security definitions. #2228

Copy link
Copy link
@hsuyuming

Description

@hsuyuming
Issue body actions

Describe the bug
OpenAPIToolset and APIHubToolset only allow each tool to have a single security schema.
For example:
If your endpoint(tool) required multiple security, then OpenAPIToolset and APIHubToolset will only choose the first one become its auth_scheme [1]

[1] https://github.com/google/adk-python/blob/main/src/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py#L129-L136

To Reproduce
Steps to reproduce the behavior:

  1. Create python environment
uv venv --python 3.12.0
source .venv/bin/activate
uv pip install google-adk==1.8.0
  1. Use this openapi.json
{
  "openapi": "3.1.0",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "servers": [
    {
      "url": "http://localhost:8080"
    }
  ],
  "paths": {
    "/helloworld": {
      "get": {
        "summary": "Helloworld",
        "operationId": "helloworld_helloworld_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {

                }
              }
            }
          }
        },
        "security": [
          {
            "api1": []
          },
          {
            "api2": []
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "api1": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key-1"
      },
      "api2": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key-2"
      }
    }
  }
}
  1. use test_tool.py to testing.
import os
import json
from google.auth import default
from google.auth.transport.requests import Request
from google.cloud import secretmanager
from google.adk.tools.apihub_tool.apihub_toolset import APIHubToolset
from google.adk.agents.llm_agent import LlmAgent
from google.adk.auth.auth_credential import AuthCredential, AuthCredentialTypes, HttpAuth, HttpCredentials
from google.adk.tools.openapi_tool.auth.auth_helpers import token_to_scheme_credential
from google.adk.tools.openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset
import asyncio

OPENAPI_SPEC_FILENAME="hello_world_openapi.json"
TOKEN="secret-key-1"

with open(os.path.join(os.path.dirname(__file__), OPENAPI_SPEC_FILENAME), 'r') as f:
    spec_content = f.read()


auth_scheme, auth_credential = token_to_scheme_credential(
   "apikey", "header", "x-api-key-1", TOKEN
)


smorch_toolset = OpenAPIToolset(
  spec_str=spec_content,
  spec_str_type='json',
  auth_scheme=auth_scheme,
  auth_credential=auth_credential
)



async def main():
    tools = await smorch_toolset.get_tools()
    for tool in tools:
        print(tool.auth_scheme)

asyncio.run(main())
  1. tool only have one auth_scheme (x-api-key-1), x-api-key-2 is missing....
(adk_with_different_auth) user@abehsu-us-vscode:~/abehsu/fastapi_with_multiple_security$ python /home/user/abehsu/adk_with_different_auth/api_key/openapi/test_tool.py
type_=<SecuritySchemeType.apiKey: 'apiKey'> description=None in_=<APIKeyIn.header: 'header'> name='x-api-key-1'
  1. The other way you can test it is using this agent.py
import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.openapi_tool.auth.auth_helpers import token_to_scheme_credential
from google.adk.tools.openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset


OPENAPI_SPEC_FILENAME="hello_world_openapi.json"
TOKEN="secret-key-1"

with open(os.path.join(os.path.dirname(__file__), OPENAPI_SPEC_FILENAME), 'r') as f:
    spec_content = f.read()


auth_scheme, auth_credential = token_to_scheme_credential(
   "apikey", "header", "x-api-key-1", TOKEN
)


hello_world_toolset = OpenAPIToolset(
  spec_str=spec_content,
  spec_str_type='json',
  auth_scheme=auth_scheme,
  auth_credential=auth_credential
)


# --- Agent Configuration ---
# Configure and create the main LLM Agent.
root_agent = LlmAgent(
    model='gemini-2.0-flash',
    name='hello_world_agent',
    instruction='when user say hi you will use hello world tool to response them',
    tools=[hello_world_toolset],
)

Backend server example code:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import APIKeyHeader

api_key_header_1 = APIKeyHeader(name="x-api-key-1", auto_error=False, scheme_name="api1")
api_key_header_2 = APIKeyHeader(name="x-api-key-2", auto_error=False, scheme_name="api2")

SECRET_KEY_1 = "secret-key-1"
SECRET_KEY_2 = "secret-key-2"

async def get_api_keys_1(
    key1: str = Depends(api_key_header_1),
    key2: str = Depends(api_key_header_2),
):
    if not key1 or key1 != SECRET_KEY_1:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or missing API Key 1",
        )
    if not key2 or key2 != SECRET_KEY_2:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or missing API Key 2",
        )
    return key1, key2

app = FastAPI()

@app.get("/helloworld", dependencies=[Depends(get_api_keys_1)])
async def helloworld():
    return {"message": "Hello World"}

Screenshots

Image

Desktop (please complete the following information):

  • OS: Linux
  • Python version(python -V): Python 3.12.10
  • ADK version(pip show google-adk): 1.18.0
Reactions are currently unavailable

Metadata

Metadata

Assignees

Labels

needs review[Status] The PR/issue is awaiting review from the maintainer[Status] The PR/issue is awaiting review from the maintainertools[Component] This issue is related to tools[Component] This issue is related to tools

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.