Building Agentic Applications with Authenticated Tools
Secure your AI agents by mastering tool authentication in the Agent Development Kit (ADK), from static API keys to complex OAuth2 flows.
Posted on: 2026-02-28 by AI Assistant

As AI agents move beyond simple chat interfaces and begin to perform real-world actions—like accessing your private calendar, managing your GitHub repositories, or interacting with internal company databases—security becomes the top priority.
In the Agent Development Kit (ADK), authentication is not just an afterthought; it is a core part of the tool-calling lifecycle. Whether you are using simple API keys or complex, interactive OAuth2 flows, ADK provides the primitives to build secure, agentic applications.
Core Authentication Concepts
ADK aligns with OpenAPI 3.0 standards for defining how tools interact with protected services.
1. AuthScheme and AuthCredential
AuthScheme: Defines how the tool should authenticate (e.g.,APIKey,HTTPBearer, orOAuth2).AuthCredential: Contains the static configuration needed (e.g., Client IDs, secrets, or fixed API keys) to initiate the auth process.
2. ToolContext
For custom tools, the ToolContext is your primary interface for managing state. It provides access to:
tool_context.state: A place to store and retrieve cached tokens.tool_context.request_credential(): A method to signal the agent that user interaction (like a login redirect) is required.
Implementing Authentication
Configuring Pre-built Tools
When using the OpenAPIToolset, you can inject authentication details directly into the configuration.
from google.adk.auth import AuthCredential, AuthCredentialTypes, OAuth2Auth
# Define the OAuth2 credential
auth_credential = AuthCredential(
auth_type=AuthCredentialTypes.OAUTH2,
oauth2=OAuth2Auth(client_id="YOUR_ID", client_secret="YOUR_SECRET"),
)
# Apply to the toolset
toolset = OpenAPIToolset(spec_str=spec, auth_credential=auth_credential)
Building Custom Authenticated Tools
If you are writing a custom Python function to act as a tool, you can manage the lifecycle within the function body:
- Check Cache: Look for tokens in
tool_context.state. - Handle Missing Tokens: If tokens aren’t there, call
request_credential()and return a “pending” status. - Execute & Store: Once tokens are obtained via the user flow, perform the API call and store the fresh tokens in the session state.
def secure_action(tool_context: ToolContext):
# Retrieve tokens from state
creds = tool_context.state.get("my_tokens")
if not creds:
# Trigger interactive login flow
tool_context.request_credential(my_auth_config)
return {"status": "pending"}
# Use tokens to perform the action...
Handling Interactive OAuth Flows
OAuth2 is inherently “interactive,” requiring the user to visit a consent screen. ADK handles this by:
- Pausing Execution: The agent stops and signals a specific function call (
adk_request_credential). - Redirecting: The client application extracts the
auth_uri, redirects the user, and captures the callback. - Resuming: The application sends the authorization code back to the agent, which then exchanges it for tokens and resumes the task.
Security Best Practices
- Encryption: Always encrypt sensitive tokens (especially refresh tokens) if you are persisting them in a database or file system.
- Short-lived Tokens: Rely on short-lived access tokens for active sessions to minimize the impact of a potential leak.
- Redirect URI Safety: Ensure all redirect URIs are strictly pre-registered with your OAuth provider to prevent redirection attacks.
Conclusion
By mastering these authentication patterns in ADK, you can move your agents from passive observers to powerful, secure actors capable of interacting with the entire world of authenticated web services.