ec2b666284
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
150 lines
4.5 KiB
Markdown
150 lines
4.5 KiB
Markdown
# OAuth2 Client Credentials Weather Agent
|
|
|
|
This sample demonstrates OAuth2 client credentials flow with ADK's `AuthenticatedFunctionTool` using a practical weather assistant agent.
|
|
|
|
## Overview
|
|
|
|
The OAuth2 client credentials grant type is used for server-to-server authentication where no user interaction is required. This demo shows:
|
|
|
|
- How to configure OAuth2 client credentials in ADK
|
|
- Using `AuthenticatedFunctionTool` for automatic token management
|
|
- Transparent authentication in a practical weather assistant
|
|
- Testing the OAuth2 client credentials implementation
|
|
|
|
## Architecture
|
|
|
|
```
|
|
[WeatherAssistant] -> [AuthenticatedFunctionTool] -> [OAuth2CredentialExchanger] -> [OAuth2 Server] -> [Weather API]
|
|
```
|
|
|
|
1. **WeatherAssistant** calls weather tool when user asks for weather data
|
|
1. **AuthenticatedFunctionTool** automatically handles OAuth2 flow
|
|
1. **OAuth2CredentialExchanger** exchanges client credentials for access token
|
|
1. **Authenticated requests** are made to weather API
|
|
|
|
## Files
|
|
|
|
### `agent.py` - WeatherAssistant Agent
|
|
|
|
Weather assistant agent that demonstrates OAuth2 client credentials flow transparently:
|
|
|
|
- **OAuth2 Configuration**: Client credentials setup with token URL and scopes
|
|
- **Weather Tool**: Single `get_weather_data` tool for fetching weather information
|
|
- **Agent Definition**: ADK LLM agent focused on providing weather information
|
|
|
|
**Key Features:**
|
|
|
|
- Automatic token exchange using client ID and secret
|
|
- Bearer token authentication
|
|
- Transparent OAuth2 handling (invisible to the model)
|
|
- Practical use case demonstrating machine-to-machine authentication
|
|
|
|
### `main.py` - CLI Interface
|
|
|
|
Command-line interface for running the WeatherAssistant agent:
|
|
|
|
```bash
|
|
# Ask for weather
|
|
python contributing/samples/oauth2_client_credentials/main.py "What's the weather in Tokyo?"
|
|
```
|
|
|
|
**Requirements:**
|
|
|
|
- LLM API key (Google AI or Vertex AI)
|
|
- OAuth2 test server running
|
|
|
|
### `oauth2_test_server.py` - Local OAuth2 Server
|
|
|
|
Mock OAuth2 server for testing the client credentials flow:
|
|
|
|
```bash
|
|
python contributing/samples/oauth2_client_credentials/oauth2_test_server.py
|
|
```
|
|
|
|
**Features:**
|
|
|
|
- OIDC discovery endpoint (`/.well-known/openid_configuration`)
|
|
- Client credentials token exchange (`/token`)
|
|
- Protected weather API (`/api/weather`)
|
|
- Supports both `authorization_code` and `client_credentials` grant types
|
|
- Test credentials: `client_id="test_client"`, `client_secret="test_secret"`
|
|
|
|
**Endpoints:**
|
|
|
|
- `GET /.well-known/openid_configuration` - OIDC discovery
|
|
- `POST /token` - Token exchange
|
|
- `GET /api/weather` - Weather API (requires Bearer token)
|
|
- `GET /` - Server info
|
|
|
|
## Quick Start
|
|
|
|
1. **Start the OAuth2 server:**
|
|
```bash
|
|
python contributing/samples/oauth2_client_credentials/oauth2_test_server.py &
|
|
```
|
|
1. Create a `.env` file in the project root with your API credentials:
|
|
|
|
```bash
|
|
# Choose Model Backend: 0 -> ML Dev, 1 -> Vertex
|
|
GOOGLE_GENAI_USE_ENTERPRISE=1
|
|
|
|
# ML Dev backend config
|
|
GOOGLE_API_KEY=your_google_api_key_here
|
|
|
|
# Vertex backend config
|
|
GOOGLE_CLOUD_PROJECT=your_project_id
|
|
GOOGLE_CLOUD_LOCATION=us-central1
|
|
```
|
|
|
|
3. **Run the agent:**
|
|
|
|
```bash
|
|
# Ask for weather
|
|
python contributing/samples/oauth2_client_credentials/main.py "What's the weather in Tokyo?"
|
|
```
|
|
|
|
1. **Interactive demo (use ADK commands):**
|
|
|
|
```bash
|
|
# Interactive CLI
|
|
adk run contributing/samples/oauth2_client_credentials
|
|
|
|
# Interactive web UI
|
|
adk web contributing/samples
|
|
```
|
|
|
|
## OAuth2 Configuration
|
|
|
|
The agent uses these OAuth2 settings (configured in `agent.py`):
|
|
|
|
```python
|
|
flows = OAuthFlows(
|
|
clientCredentials=OAuthFlowClientCredentials(
|
|
tokenUrl="http://localhost:8000/token",
|
|
scopes={
|
|
"read": "Read access to weather data",
|
|
"write": "Write access for data updates",
|
|
"admin": "Administrative access",
|
|
},
|
|
)
|
|
)
|
|
|
|
raw_credential = AuthCredential(
|
|
auth_type=AuthCredentialTypes.OAUTH2,
|
|
oauth2=OAuth2Auth(
|
|
client_id="test_client",
|
|
client_secret="test_secret",
|
|
),
|
|
)
|
|
```
|
|
|
|
## Authentication Flow
|
|
|
|
1. **Weather Request**: User asks WeatherAssistant for weather information
|
|
1. **Tool Invocation**: Agent calls `get_weather_data` authenticated function tool
|
|
1. **Credential Loading**: CredentialManager loads OAuth2 configuration
|
|
1. **Token Exchange**: OAuth2CredentialExchanger uses client credentials to get access token
|
|
1. **Request Enhancement**: AuthenticatedFunctionTool adds `Authorization: Bearer <token>` header
|
|
1. **API Call**: Weather API accessed with valid token
|
|
1. **Response**: Weather data returned to user
|