OAuth 2.0 auth provider
The OAuth 2.0 auth provider enables tools and agents to authorize with any OAuth 2.0-compatible API on behalf of a user. Behind the scenes, the Arcade Engine and this auth provider seamlessly manage OAuth 2.0 authorization for your users.
Arcade AI has pre-built integrations with many popular OAuth 2.0 providers. Use this OAuth 2.0 provider to connect to other systems that aren't pre-built.
What's documented here
This page describes how to configure OAuth 2.0 with Arcade AI, and use it in:
- Your app code that needs to call APIs protected by OAuth 2.0
- Or, your custom tools that need to call APIs protected by OAuth 2.0
Configuring OAuth 2.0
How you configure the OAuth 2.0 provider depends on whether you use the Arcade Cloud Engine or a self-hosted Engine.
Configuring OAuth 2.0 with the Arcade Cloud Engine
Coming soon! In 0.1.0-preview, the Arcade Cloud Engine does not yet support configuring auth providers.
Configuring OAuth 2.0 with a self-hosted Arcade Engine
Set environment variables
Set the following environment variables. Replace HOOLI
with the name of the OAuth 2.0 provider you are configuring:
export HOOLI_CLIENT_ID="<your client ID>"
export HOOLI_CLIENT_SECRET="<your client secret>"
Or, you can set these values in a .env
file:
HOOLI_CLIENT_ID="<your client ID>"
HOOLI_CLIENT_SECRET="<your client secret>"
See configuration for more information on how to set environment variables and configure the Arcade Engine.
Edit the Engine configuration
Edit the engine.yaml
file and add a new item to the auth.providers
section:
auth:
providers:
- id: hooli
type: oauth2
description: "Hooli OAuth 2.0 provider"
enabled: true
client_id: ${env:HOOLI_CLIENT_ID}
client_secret: ${env:HOOLI_CLIENT_SECRET}
oauth2:
# Server-specific configuration, see reference below
The ID of the provider (hooli
in this example) can be any string. It's used to reference the provider in your app code and must be unique.
Each service expects a slightly different set of parameters in the oauth2
section. Refer to the configuration reference below, and to your service's documentation to understand what parameters are required.
If you need help configuring a specific provider, get in touch with us!
Configuration reference
The only supported OAuth 2.0 flow is the authorization code grant (with or without PKCE).
scope_delimiter
(optional, default " "
/ space): The delimiter for scopes, if any.
pkce
(optional):
enabled
(optional, defaultfalse
): Iftrue
, PKCE will be used.code_challenge_method
(optional, defaultS256
): The code challenge method to use. The only supported method isS256
. This parameter is ignored if PKCE is not enabled.
authorize_request
This section configures the initial authorization request.
endpoint
: The authorization endpoint for your OAuth 2.0 server, e.g./oauth/authorize
params
: A map of parameter keys and values to include in the authorization request.
These placeholders are available in params
:
{{client_id}}
: The configured client ID.{{redirect_uri}}
: The redirect URI managed by Arcade AI.{{scopes}}
: The scopes to request, if any{{existing_scopes}}
: The scopes that the user has already granted, if any.
The state
parameter is automatically added to the request, and does not need
to be included in params
. If PKCE is enabled, code_challenge
and
code_challenge_method
are also added automatically.
For most providers, oauth2.authorize_request.params
will look like:
authorize_request:
params:
response_type: "code"
client_id: "{{client_id}}"
redirect_uri: "{{redirect_uri}}"
scope: "{{scopes}} {{existing_scopes}}"
Some providers support additional parameters in the authorization request. These can be added to params
as well. For example:
authorize_request:
params:
response_type: "code"
client_id: "{{client_id}}"
redirect_uri: "{{redirect_uri}}"
scope: "{{scopes}} {{existing_scopes}}"
prompt: "consent"
access_type: "offline"
token_request
This section configures the code/token exchange request, after the user has approved access to your app.
endpoint
: The token endpoint for your OAuth 2.0 server, e.g./oauth/token
auth_method
(optional, default none): The authentication method to use. Supported values are none (omitted) andclient_secret_basic
.params
: A map of parameter keys and values to include in the token request.
These placeholders are available in params
:
{{client_id}}
: The configured client ID.{{client_secret}}
: The configured client secret.{{redirect_uri}}
: The redirect URI managed by Arcade AI.
The code
parameter is automatically added to the request, and does not need
to be included in params
. If PKCE is enabled, the code_verifier
parameter
is also added to the request automatically.
For most providers, oauth2.token_request.params
will look like:
token_request:
params:
grant_type: "authorization_code"
redirect_uri: "{{redirect_uri}}"
client_id: "{{client_id}}"
client_secret: "{{client_secret}}" # Omit if using PKCE
response_content_type
(optional, defaultapplication/json
): The expected content type of the response. Supported values areapplication/json
andapplication/x-www-form-urlencoded
.response_map
(optional): A map of keys and values to extract from the response. Supports simple JSONPath expressions. Only applicable ifresponse_content_type
isapplication/json
. See the JSONPath reference for details on extracting values using JSONPath.
refresh_token_request
This section configures the refresh token request, if your OAuth 2.0 server supports refresh tokens. If not provided, refresh tokens will not be used.
endpoint
: The refresh token endpoint for your OAuth 2.0 server, e.g./oauth/token
auth_method
(optional, default none): The authentication method to use. Supported values are none (omitted),client_secret_basic
, andbearer_access_token
.params
: A map of parameter keys and values to include in the refresh token request.
These placeholders are available in params
:
{{refresh_token}}
: The refresh token to use.{{client_id}}
: The configured client ID.{{client_secret}}
: The configured client secret.
For most providers, oauth2.refresh_token_request.params
will look like:
refresh_token_request:
params:
grant_type: "refresh_token"
client_id: "{{client_id}}"
client_secret: "{{client_secret}}"
response_content_type
(optional, defaultapplication/json
): The expected content type of the response. Supported values areapplication/json
andapplication/x-www-form-urlencoded
.response_map
(optional): A map of keys and values to extract from the response. Supports simple JSONPath expressions. Only applicable ifresponse_content_type
isapplication/json
. See the JSONPath reference for details on extracting values using JSONPath.
user_info_request
Some OAuth 2.0 APIs provide a user info endpoint that returns information about the user. Arcade Engine can automatically request user info from servers that support it. If the user_info_request
section is omitted, user info will not be requested.
endpoint
: The user info endpoint for your OAuth 2.0 server, e.g./oauth/userinfo
auth_method
(optional, defaultbearer_access_token
): The authentication method to use. The only supported value isbearer_access_token
.response_content_type
(optional, defaultapplication/json
): The expected content type of the response. The only supported value isapplication/json
.triggers
: Controls when the user info request is made.on_token_grant
: Iftrue
, the user info request will be made when a token is granted. This is typically only once for each user, unless new scopes are granted.on_token_refresh
: Iftrue
, the user info request will be made every time a token is refreshed.
JSONPath expressions in response_map
In the token_request
and refresh_token_request
sections, you can optionally configure response_map
. Configuring response_map
is useful if your OAuth 2.0 server returns a JSON object with nested properties, or properties with non-standard names.
The typical JSON payload that most OAuth 2.0 servers return looks like this:
{
"access_token": "...",
"refresh_token": "...",
"expires_in": 3600,
"scope": "scope1 scope2"
}
If your server returns the above payload, you don't need response_map
.
But if your server returns:
{
"data": {
"access_token": "...",
"expires_in": 3600,
"refresh_token": "...",
"scope": "scope1 scope2"
}
}
Then you need to configure response_map
to extract the properties from inside the data
object. Use JSONPath (opens in a new tab) expressions to select the properties you need:
token_request: # or refresh_token_request
response_map:
access_token: "$.data.access_token"
expires_in: "$.data.expires_in"
refresh_token: "$.data.refresh_token" # Only needed if refresh tokens are used
scope: "$.data.scope" # Only needed if scopes are used
Not all OAuth 2.0 servers support refresh tokens, or use scopes. The only required properties are access_token
and expires_in
.
Joining scopes in response_map
Most OAuth 2.0 servers return scopes as a delimited string, such as scope1 scope2
or scope1,scope2
. If your server follows this convention, configuring the top-level scope_delimiter
property in the oauth2
section is all you need to do.
Some OAuth 2.0 servers return an array of scopes instead of a delimited string. For example:
{
"access_token": "...",
"expires_in": 3600,
"scope": ["scope1", "scope2"]
}
In this case, you need to use the join()
function in response_map
to join the scopes into a delimited string:
token_request:
response_map:
access_token: "$.access_token"
expires_in: "$.expires_in"
scope: "join('$.scope', ' ')"
join()
takes two arguments:
path
: The JSONPath expression to select the array to join.delimiter
: The delimiter to use between array elements. Make sure this matches thescope_delimiter
setting in theoauth2
section.
Full configuration example
Here's a full example of the YAML configuration for a custom OAuth 2.0 provider:
Using OAuth 2.0 in app code
Use the OAuth 2.0 auth provider in your own agents and AI apps to get a user token for any OAuth 2.0-compatible APIs. See authorizing agents with Arcade to understand how this works.
Use client.auth.start()
to get an access token:
from arcadepy import Arcade
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
user_id = "[email protected]"
# Start the authorization process
auth_response = client.auth.start(
user_id=user_id,
provider="hooli",
scopes=["scope1", "scope2"],
)
if auth_response.status != "completed":
print("Please complete the authorization challenge in your browser:")
print(auth_response.authorization_url)
# Wait for the authorization to complete
auth_response = client.auth.wait_for_completion(auth_response)
token = auth_response.context.token
# TODO: Do something interesting with the token...
Using OAuth 2.0 in custom tools
The Arcade LLM API is a convenient way to call LLMs and automatically invoke tools. You can author your own custom tools that interact with any OAuth 2.0-compatible APIs.
Use the OAuth2()
auth class to specify that a tool requires OAuth 2.0 authorization. In your tool function, context.authorization
will be automatically populated with the following properties:
context.authorization.token
contains the user's access token.- If
oauth2.user_info_request
is configured, the user info will be fetched and placed incontext.authorization.user_info
. The data payload is specific to each provider.
from typing import Annotated
from arcade.sdk import ToolContext, tool
from arcade.sdk.auth import OAuth2
@tool(
requires_auth=OAuth2(
provider_id="hooli",
scopes=["scope1", "scope2"],
)
)
async def reticulate_splines(
context: ToolContext,
num_splines: Annotated[int, "The number of splines to reticulate"],
):
"""Reticulate the specified number of splines."""
# Get an access token to call an API
token = context.authorization.token
# Get user info (if configured and supported by the OAuth 2.0 server):
user_id = context.authorization.user_info.get("sub")