mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-09 15:38:08 -05:00
doc(langchain-sdk): Add guidance for configuring and using authenticated tools in Toolbox. (#146)
This commit is contained in:
@@ -18,9 +18,40 @@ authSources:
|
||||
clientId: YOUR_GOOGLE_CLIENT_ID
|
||||
```
|
||||
|
||||
Tip: If you are accessing Toolbox with multiple applications, each application
|
||||
should register their own Client ID even if they use the same `kind` of auth
|
||||
provider.
|
||||
> [!TIP]
|
||||
> If you are accessing Toolbox with multiple applications, each application
|
||||
> should register their own Client ID even if they use the same `kind` of auth
|
||||
> provider.
|
||||
>
|
||||
> Here's an example:
|
||||
>
|
||||
> ```yaml
|
||||
> authSources:
|
||||
> my_auth_app_1:
|
||||
> kind: google
|
||||
> client_id: YOUR_CLIENT_ID_1
|
||||
> my_auth_app_2:
|
||||
> kind: google
|
||||
> client_id: YOUR_CLIENT_ID_2
|
||||
>
|
||||
> tools:
|
||||
> my_tool:
|
||||
> parameters:
|
||||
> - name: user_id
|
||||
> type: string
|
||||
> auth_sources:
|
||||
> - name: my_auth_app_1
|
||||
> field: sub
|
||||
> - name: my_auth_app_2
|
||||
> field: sub
|
||||
> ...
|
||||
>
|
||||
> my_tool_no_param:
|
||||
> auth_required:
|
||||
> - my_auth_app_1
|
||||
> - my_auth_app_2
|
||||
> ...
|
||||
> ```
|
||||
|
||||
## Kinds of authSources
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ applications, enabling advanced orchestration and interaction with GenAI models.
|
||||
- [Represent Tools as Nodes](#represent-tools-as-nodes)
|
||||
- [Connect Tools with LLM](#connect-tools-with-llm)
|
||||
- [Manual usage](#manual-usage)
|
||||
- [Authenticating Tools](#authenticating-tools)
|
||||
- [Supported Authentication Mechanisms](#supported-authentication-mechanisms)
|
||||
- [Configuring Tools for Authentication](#configuring-tools-for-authentication)
|
||||
- [Configure SDK for Authentication](#configure-sdk-for-authentication)
|
||||
- [Complete Example](#complete-example)
|
||||
|
||||
<!-- /TOC -->
|
||||
## Installation
|
||||
@@ -33,7 +38,7 @@ pip install toolbox-langchain-sdk
|
||||
|
||||
Import and initialize the toolbox client.
|
||||
|
||||
```python
|
||||
```py
|
||||
from toolbox_langchain_sdk import ToolboxClient
|
||||
|
||||
# Replace with your Toolbox service's URL
|
||||
@@ -48,7 +53,7 @@ toolbox = ToolboxClient("http://127.0.0.1:5000")
|
||||
> [!TIP]
|
||||
> You can also pass your own `ClientSession` so that the `ToolboxClient` can
|
||||
> reuse the same session.
|
||||
> ```
|
||||
> ```py
|
||||
> async with ClientSession() as session:
|
||||
> toolbox = ToolboxClient("http://localhost:5000", session)
|
||||
> ```
|
||||
@@ -57,7 +62,7 @@ toolbox = ToolboxClient("http://127.0.0.1:5000")
|
||||
|
||||
You can load a toolset, a collection of related tools.
|
||||
|
||||
```python
|
||||
```py
|
||||
# Load all tools
|
||||
tools = await toolbox.load_toolset()
|
||||
|
||||
@@ -69,7 +74,7 @@ tools = await toolbox.load_toolset("my-toolset")
|
||||
|
||||
You can also load a single tool.
|
||||
|
||||
```python
|
||||
```py
|
||||
tool = await toolbox.load_tool("my-tool")
|
||||
```
|
||||
|
||||
@@ -79,7 +84,7 @@ LangChain's agents can dynamically choose and execute tools based on the user
|
||||
input. The user can include the tools loaded from the Toolbox SDK in the agent's
|
||||
toolkit.
|
||||
|
||||
```python
|
||||
```py
|
||||
from langchain_google_vertexai import ChatVertexAI
|
||||
|
||||
model = ChatVertexAI(model="gemini-1.5-flash")
|
||||
@@ -103,7 +108,7 @@ minimal changes.
|
||||
Each tool generated by the SDK can be represented as a LangGraph node. The
|
||||
node's functionality would encapsulate the execution of the corresponding tool.
|
||||
|
||||
```python
|
||||
```py
|
||||
from toolbox_langchain_sdk import ToolboxClient
|
||||
from langgraph.graph import StateGraph, MessagesState
|
||||
from langgraph.prebuilt import ToolNode
|
||||
@@ -130,7 +135,7 @@ to use based on the user input or the context of the conversation. The output
|
||||
from a tool can then be fed back into the LLM for further processing or
|
||||
decision-making.
|
||||
|
||||
```python
|
||||
```py
|
||||
from typing import Literal
|
||||
from langgraph.graph import END, START
|
||||
from langchain_core.messages import HumanMessage
|
||||
@@ -163,6 +168,97 @@ graph.invoke(
|
||||
|
||||
You can also execute a tool manually using the `arun` method.
|
||||
|
||||
```python
|
||||
```py
|
||||
result = await tools[0].arun({ "name": "Alice", "age": 30 })
|
||||
```
|
||||
|
||||
## Authenticating Tools
|
||||
|
||||
> [!WARNING]
|
||||
> Always use HTTPS to connect your application with the Toolbox service,
|
||||
> especially when using tools with authentication configured. Using HTTP exposes
|
||||
> your application to serious security risks, including unauthorized access to
|
||||
> user information and man-in-the-middle attacks, where sensitive data can be
|
||||
> intercepted.
|
||||
|
||||
Some tools in your Toolbox configuration might require user authentication to
|
||||
access sensitive data. This section guides you on how to configure tools for
|
||||
authentication and use them with the SDK.
|
||||
|
||||
### Supported Authentication Mechanisms
|
||||
The Toolbox SDK currently supports authentication using [OIDC
|
||||
protocol](https://openid.net/specs/openid-connect-core-1_0.html). Specifically,
|
||||
it uses [ID
|
||||
tokens](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) and *not*
|
||||
access tokens for [Google OAuth
|
||||
2.0](https://cloud.google.com/apigee/docs/api-platform/security/oauth/oauth-home).
|
||||
|
||||
### Configuring Tools for Authentication
|
||||
|
||||
Refer to [these instructions](https://github.com/googleapis/genai-toolbox/blob/main/docs/tools/README.md#authenticated-parameters) on configuring tools for authenticated parameters.
|
||||
|
||||
### Configure SDK for Authentication
|
||||
|
||||
Provide the `auth_headers` parameter to the `load_tool` or `load_toolset` calls
|
||||
with a dictionary. The keys of this dictionary should match the names of the
|
||||
authentication sources configured in your tools file (e.g., `my_auth_service`),
|
||||
and the values should be callable functions (e.g., lambdas or regular functions)
|
||||
that return the ID token of the logged-in user.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```py
|
||||
def get_auth_header():
|
||||
# ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
|
||||
# This example just returns a placeholder. Replace with your actual token retrieval.
|
||||
return "YOUR_ID_TOKEN"
|
||||
|
||||
toolbox = ToolboxClient("http://localhost:5000")
|
||||
|
||||
tools = toolbox.load_toolset(auth_headers={ "my_auth_service": get_auth_header })
|
||||
|
||||
# OR
|
||||
|
||||
tool = toolbox.load_tool("my_tool", auth_headers={ "my_auth_service": get_auth_header })
|
||||
```
|
||||
|
||||
Alternatively, you can call the `add_auth_header` method to configure
|
||||
authentication separately.
|
||||
|
||||
```py
|
||||
toolbox.add_auth_header("my_auth_service", get_auth_header)
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> After adding authentication headers, either through `load_tool`,
|
||||
> `load_toolset`, or `add_auth_header`, all subsequent tool invocations from
|
||||
> that point onward will use these authentications, regardless of whether the
|
||||
> tool was loaded before or after calling these methods. This maintains a
|
||||
> consistent authentication context.
|
||||
|
||||
### Complete Example
|
||||
|
||||
```py
|
||||
import asyncio
|
||||
from toolbox_langchain_sdk import ToolboxClient
|
||||
|
||||
async def get_auth_header():
|
||||
# Replace with your actual ID token retrieval logic.
|
||||
# For example, using a library like google-auth
|
||||
# from google.oauth2 import id_token
|
||||
# from google.auth.transport import requests
|
||||
# request = requests.Request()
|
||||
# id_token_string = id_token.fetch_id_token(request, "YOUR_AUDIENCE")# Replace with your audience
|
||||
# return id_token_string
|
||||
return "YOUR_ACTUAL_ID_TOKEN" # placeholder
|
||||
|
||||
async def main():
|
||||
toolbox = ToolboxClient("http://localhost:5000")
|
||||
toolbox.add_auth_header("my_auth_service", get_auth_header)
|
||||
tools = await toolbox.load_toolset()
|
||||
result = await tools[0].arun({"input": "some input"})
|
||||
print(result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
Reference in New Issue
Block a user