Custom Auth Flow with CrewAI
In this guide, we will explore how to create a custom auth flow that will be performed before executing Arcade tools within your CrewAI agent team.
The ArcadeToolManager
’s built-in authorization and tool execution flows work well for many typical use cases. However, some scenarios call for a tailored approach. By implementing a custom auth flow, you gain flexibility in handling tool authorization. If your use case calls for a unique interface, additional approval steps, or specialized error handling, then this guide is for you.
Prerequisites
Set up your environment
Install the required package, and ensure your environment variables are set with your Arcade and OpenAI API keys:
pip install crewai-arcade
Configure API keys
Provide your Arcade and OpenAI API keys. You can store them in environment variables like so:
export ARCADE_API_KEY="your_arcade_api_key"
export OPENAI_API_KEY="your_openai_api_key"
Define your custom auth flow
The custom auth flow defined in the following code snippet is a function that will be called whenever CrewAI needs to call a tool.
from typing import Any
from crewai_arcade import ArcadeToolManager
USER_ID = "[email protected]"
def custom_auth_flow(
manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any]
) -> Any:
"""Custom auth flow for the ArcadeToolManager
This function is called when CrewAI needs to call a tool that requires authorization.
Authorization is handled before executing the tool.
This function overrides the ArcadeToolManager's default auth flow performed by ArcadeToolManager.authorize_tool
"""
# Get authorization status
auth_response = manager.authorize(tool_name, USER_ID)
# If the user is not authorized for the tool,
# then we need to handle the authorization before executing the tool
if not manager.is_authorized(auth_response.id):
print(f"Authorization required for tool: '{tool_name}' with inputs:")
for input_name, input_value in tool_input.items():
print(f" {input_name}: {input_value}")
# Handle authorization
print(f"\nTo authorize, visit: {auth_response.url}")
# Block until the user has completed the authorization
auth_response = manager.wait_for_auth(auth_response)
# Ensure authorization completed successfully
if not manager.is_authorized(auth_response.id):
raise ValueError(f"Authorization failed for {tool_name}. URL: {auth_response.url}")
else:
print(f"Authorization already granted for tool: '{tool_name}' with inputs:")
for input_name, input_value in tool_input.items():
print(f" {input_name}: {input_value}")
def tool_manager_callback(tool_manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any]) -> Any:
"""Tool executor callback with custom auth flow for the ArcadeToolManager
ArcadeToolManager's default executor handles authorization and tool execution.
This function overrides the default executor to handle authorization in a custom way and then executes the tool.
"""
custom_auth_flow(tool_manager, tool_name, **tool_input)
return tool_manager.execute_tool(USER_ID, tool_name, **tool_input)
Get Arcade tools
You can now provide the tool manager callback to the ArcadeToolManager
upon initialization:
# Provide the tool manager callback to the ArcadeToolManager
manager = ArcadeToolManager(executor=tool_manager_callback)
# Retrieve the provided tools and/or toolkits as CrewAI StructuredTools.
tools = manager.get_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
Use tools in your CrewAI agent team
Create a Crew that uses your tools with the custom auth flow. When the tool is called, your tool manager callback will be called to handle the authorization and then the tool will be executed.
from crewai import Agent, Crew, Task
from crewai.llm import LLM
crew_agent = Agent(
role="Main Agent",
backstory="You are a helpful assistant",
goal="Help the user with their requests",
tools=tools,
allow_delegation=False,
verbose=True,
llm=LLM(model="gpt-4o"),
)
task = Task(
description="Get the 5 most recent emails from the user's inbox and summarize them and recommend a response for each.",
expected_output="A bulleted list with a one sentence summary of each email and a recommended response to the email.",
agent=crew_agent,
tools=crew_agent.tools,
)
crew = Crew(
agents=[crew_agent],
tasks=[task],
verbose=True,
memory=True,
)
result = crew.kickoff()
print("\n\n\n ------------ Result ------------ \n\n\n")
print(result)
Next steps
Now you’re ready to integrate Arcade tools with a custom auth flow into your own CrewAI agent team.