arizuko › howto › Add an OAuth provider
OAuth providers
Some services give a static API key that you paste once. Other services use a "Connect" flow: the user lets arizuko act for them, and the service returns a short-lived access token and a refresh token. For the second kind, arizuko uses a surrogate OAuth provider. arizuko runs the flow, stores the token in the secrets table and refreshes the token before it expires, so the tools of an agent keep working.
A new provider needs only configuration: one .toml file in the data directory, a redirect URI at the provider and two env vars. No code and no rebuild. github and google are built in. This page adds a different provider.
secrets row for a REST connector is simpler.A descriptor file names the provider
Write <datadir>/surrogate/<name>.toml. The file name is the provider name. It becomes the URL segment and the start of the env var names. Example for Slack:
# <datadir>/surrogate/slack.toml
auth_url = "https://slack.com/oauth/v2/authorize"
token_url = "https://slack.com/api/oauth.v2.access"
revoke_url = "https://slack.com/api/auth.revoke"
scopes = ["chat:write", "channels:read"]
secret_key = "SLACK_TOKEN" # secrets-table key the token lands in
allowed_domain = "slack.com"
access_type = "" # "offline" where a provider gates refresh (google)
auth_url, token_url and secret_key are required. If one is missing, dashd does not start, and the error names the file. A provider with missing fields cannot run the flow, so the error comes at start and not at the first click. A file with the name of a built-in provider replaces the built-in provider. So you can change the scopes of github.toml without a new binary.
The provider must know the exact redirect URI
In the app console of the provider, for example the Slack API dashboard, the Google Cloud console or the Notion integrations, add this callback URL:
<AUTH_BASE_URL or WEB_HOST>/dash/me/connections/<name>/callback
dashd reads AUTH_BASE_URL first and uses WEB_HOST when it is not set.
For a Slack provider on acme.example.com, the URL is https://acme.example.com/dash/me/connections/slack/callback. The provider refuses the flow when the redirect URI is not the one it has. Operators often forget this step.
The client credentials go into .env
The client ID and secret from the provider go into the .env of the instance. The key contains the provider name in upper case, with _ in place of -:
SURROGATE_SLACK_CLIENT_ID=1234567890.abcdef
SURROGATE_SLACK_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxx
A provider without credentials still loads. The connections page does not show it until it can run, so a user never sees a "Connect" button that fails.
arizuko generate writes SURROGATE_GITHUB_CLIENT_ID and SURROGATE_GITHUB_CLIENT_SECRET into the env file of dashd, and no other SURROGATE_* key. For every other provider, the pair in .env does not reach dashd, and the provider stays connectable=false.After a restart, users can connect
sudo systemctl restart arizuko_<instance>
"Connect Slack" then appears at /dash/me/connections. A user clicks it, approves at Slack and comes back. arizuko writes the token into the secrets table under secret_key, here SLACK_TOKEN. The broker refreshes the token before it expires. If the provider revokes the refresh token, the agent gets a "reconnect" error and not a silent failure.
A connector gives agents a tool with the token
The stored token is a secret like any other. Point a REST or MCP connector at secret_key, and the agent gets a tool that calls the service as the connected user. No credential enters the guest. MCP reference lists the tool surface. Grants shows how to select the folders that can call the tool.
dashd logs each provider at start
sudo journalctl -u arizuko_<instance> --since "1 min ago" \
| grep -i "surrogate provider"
At start, dashd logs each loaded provider and whether it has credentials. A missing provider means that the .toml file did not parse or is in the wrong directory. connectable=false means that the SURROGATE_<NAME>_CLIENT_* variables are not set.
Three pages give the details
- secrets
- Where the token is stored and who can read it.
- env reference
- The
SURROGATE_*andWEB_HOSTvariables. - webhooks
- The other way an external service reaches an agent.