Skip to content
LogoLogo

OAuth Apps

OAuth apps let users connect their own upstream accounts to Centaur. An operator registers an OAuth client in the console, shares a consent link, and each user who completes the flow gets a managed credential. The Centaur Console keeps the token fresh and iron-proxy injects it as Authorization: Bearer <access token> into requests to the provider's API hosts. Refresh tokens never leave the Centaur Console.

Supported Providers

ProviderUse
googleGoogle APIs, such as Gmail or Drive scopes.
slackSlack user tokens with normal Slack API scopes.
githubGitHub user tokens for api.github.com.
granolaGranola MCP tokens for mcp.granola.ai.
linearLinear tokens for api.linear.app, uploads.linear.app, and mcp.linear.app.
attioAttio workspace tokens for api.attio.com.
zoomZoom user-managed OAuth tokens for api.zoom.us.
microsoftMicrosoft 365 account tokens for graph.microsoft.com (Outlook mail, calendar, OneDrive).
customAny pre-registered OAuth 2.1 server, such as a remote MCP server, configured per app. See Custom Provider.

Set Up An App

  1. Create an OAuth client with the provider (for example in the Google Cloud console or the Attio developer dashboard). Register this callback URL: <CENTAUR_CONSOLE_PUBLIC_URL>/oauth/<slug>/callback.
  2. Register it in Centaur. In the console, open OAuth Apps, click Add App, and fill in the slug, provider, client id, client secret, and allowed scopes (one per line).
  3. Share the consent link shown on the app page: <CENTAUR_CONSOLE_PUBLIC_URL>/oauth/<slug>/start. Each user who opens it and approves the provider's consent screen gets a credential, wrapped in a grantable secret.

Re-consenting with the same account updates the existing credential instead of creating another one.

Shared Apps

Shared apps use one admin-connected account. Set this when creating the app; it cannot be changed or combined with Always available. Reconnect uses the same account. Grant agents access through the credential's secret roles.

For Mercator, select Connect on Integrations, then Manage to claim MACH and configure agent access. Set CENTAUR_CONSOLE_PUBLIC_URL first; changing it later requires recreating the app.

Provider-Specific Setup

Granola

Granola has no app dashboard; obtain the OAuth client once via dynamic client registration, then use the returned client_id and client_secret when adding the app in the console:

curl -sS -X POST https://mcp-auth.granola.ai/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Centaur Console",
    "redirect_uris": ["<CENTAUR_CONSOLE_PUBLIC_URL>/oauth/granola/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"],
    "token_endpoint_auth_method": "client_secret_post",
    "scope": "openid email profile offline_access mcp"
  }'

Use mcp as the allowed scope for the app.

Custom Provider

Use custom for an authorization server that needs no provider-specific code, such as a remote MCP server whose OAuth client an administrator registers in advance. Fill in the Custom Provider fields from the server's metadata:

  • Authorization endpoint and Token endpoint from /.well-known/oauth-authorization-server.
  • Resource URL from /.well-known/oauth-protected-resource.
  • Userinfo endpoint, if the server publishes one. Without it, the access token must be a JWT, and Centaur reads the account's sub, email, and name from its claims.

The token endpoint must accept client_secret_post. Centaur uses PKCE (S256), sends the resource URL as the RFC 8707 resource parameter on the authorization, token, and refresh requests, and keeps the granted scopes on refresh. The token is injected only for requests to the resource URL's host and path. Use the scopes from the server's metadata as the allowed scopes.

As with other personal apps, the credential is granted automatically to the connecting user's principal, matched through their Slack sign-in or the account's email.

Zoom

Create a General App in the Zoom App Marketplace and choose User-managed. Add <CENTAUR_CONSOLE_PUBLIC_URL>/oauth/<slug>/callback as both the OAuth redirect URL and an allowed redirect URL. Add the least-privilege scopes for the API operations your integration will call; the identity lookup performed during consent requires the granular user:read:user scope, which Centaur always adds to the authorization request.

Centaur sends the client credentials with HTTP Basic authentication during authorization-code exchange and refresh, and stores each rotated refresh token before the next refresh. The access token is exposed only through the grantable wrapper secret created after consent. Grant that wrapper only to the principals that need Zoom access, as described below.

For a complete example that combines this credential with an overlay tool and a durable workflow, see Zoom Meeting Automation.

Microsoft

Register an app in the Microsoft Entra admin center with Accounts in any organizational directory as the supported account type: Centaur uses the common tenant endpoints, which a single-tenant registration rejects. Add <CENTAUR_CONSOLE_PUBLIC_URL>/oauth/<slug>/callback as a Web redirect URI and create a client secret. Use delegated Microsoft Graph permission names as the allowed scopes, for example Mail.ReadWrite, Mail.Send, Calendars.ReadWrite and Contacts.Read. Centaur always adds openid, email, profile and offline_access to the authorization request so the token response carries an id_token and a refresh token.

Under Token configuration, add the email and xms_edov optional claims to the ID token. Centaur records the account's email only when xms_edov confirms its domain is verified, because any tenant admin can set an unverified address. Without these claims, the credential has no email and is not granted to principals by email match.

Microsoft rotates the refresh token on every refresh; Centaur stores each rotated token before the next refresh.

Grant The Credential

Consent does not automatically grant the token to every session. In the console, open Principals, choose the user or channel, and use Direct Grants to select the secret created for the credential — or grant it to a reusable role.

Disable Or Remove

Toggle Enabled off on the app page to stop new consent flows; existing credentials keep working. To fully remove access, revoke grants to the wrapper secret, delete it, then delete the credential.