Custom OAuth Clients
In addition to the built-in providers (Google, Slack, Atlassian, etc.), SVAHNAR lets you register your own OAuth 2.0 application from any service — whether that's an internal API, a third-party SaaS tool, or an MCP server you control.
Once registered, agents can use the provider's access token automatically when calling MCP servers or custom tools that require OAuth authentication.
📋 Before You Start
You will need to create an OAuth application in the target service's developer console first. This usually means:
- Going to that service's developer portal (e.g., Google Cloud Console, Slack API, GitHub Developer Settings).
- Creating a new OAuth App or API Client.
- Setting the Redirect URI to:
https://api.platform.svahnar.com/oauth/callback - Noting down the Client ID and Client Secret it gives you.
➕ Creating a Custom OAuth Connection
Open the Connections Page
Navigate to Connections in the left-hand sidebar.
Click the + New Connection (or Create OAuth Connection) button in the top right.
Fill in the Provider Details
A modal will open. Fill in the fields described in detail in the Field Reference section below.
Save and Connect
Click Create Connection. The provider will appear in your connections list.
Click Connect on its card to trigger the OAuth authorization flow — a popup will open to the provider's login page where you approve access.
For Client Credentials grant type, there is no popup — SVAHNAR fetches the token automatically in the background.
Use It in Agents
Once connected, reference this provider in any MCP server tool config using oauth_provider_id:
tools:
mcp_assigned:
- name: my-internal-api
config:
url: "https://api.my-company.com/mcp"
transport: http
oauth_provider_id: "<uuid-of-your-provider>"
SVAHNAR will automatically inject a valid Authorization: Bearer <token> header into every MCP request, refreshing silently when needed.
📖 Field Reference
Required Fields
Provider Name (required)
A human-readable label you give this connection. It appears on the Connections page and in logs.
Example: Acme CRM, Internal Analytics API, My Slack App
Dynamic Client Registration (Checkbox)
Toggle this option if your provider supports dynamic client onboarding. When checked:
- The Client ID and Client Secret fields are hidden because SVAHNAR registers the application automatically at runtime (complying with RFC 7591).
- SVAHNAR performs server metadata discovery (complying with RFC 8414) via the Provider Domain URL or Token URL to locate the
registration_endpoint. - Upon deletion of the connection, SVAHNAR automatically performs client deregistration via the client configuration endpoint (complying with RFC 7592).
Client ID (required if Dynamic Client Registration is unchecked)
The public identifier for your OAuth application, issued by the provider when you created the app in their developer console.
Think of it as the username of your application — it is not secret.
Example: 1234567890-abc.apps.googleusercontent.com (Google), A01234B56CD (Slack)
Client Secret (required if Dynamic Client Registration is unchecked)
The private password for your OAuth application. Treat this like a password — never share it.
SVAHNAR encrypts this with Fernet (AES-128-CBC) before storing it. It is never visible again after you save.
Do not paste your Client Secret into chat, tickets, or emails. Only enter it here in the SVAHNAR UI.
Token URL (required)
The endpoint SVAHNAR calls to exchange an authorization code for an access token, or to refresh an expired token.
This is always provided in the OAuth service's documentation.
| Provider | Token URL |
|---|---|
https://oauth2.googleapis.com/token | |
| Slack | https://slack.com/api/oauth.v2.access |
| GitHub | https://github.com/login/oauth/access_token |
| Microsoft | https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token |
| Atlassian | https://auth.atlassian.com/oauth/token |
| Box | https://api.box.com/oauth2/token |
| Notion | https://api.notion.com/v1/oauth/token |
If your provider (such as Notion) gives you a Token URL with extra query parameters in their developer documentation, paste the URL without them. SVAHNAR constructs and appends these parameters internally.
-
Example: If the provider documentation lists:
https://api.notion.com/v1/oauth/token?grant_type=authorization_codeYou should only enter:
https://api.notion.com/v1/oauth/token
Grant Type (required)
How the OAuth flow works. Choose based on who is authenticating:
| Grant Type | When to Use |
|---|---|
| Authorization Code (default) | A specific user must log in and approve access. The popup flow. Use this for Google, Slack, GitHub, Notion, Atlassian, etc. |
| Client Credentials | No user is involved. Your application authenticates directly using Client ID + Secret. Use this for server-to-server APIs like SharePoint (Azure AD) or internal machine-to-machine services. |
When using Client Credentials, SVAHNAR fetches a token in the background automatically — there is no popup for the user to click through. It also auto-renews when the token expires.
Optional Fields
Provider Type (optional)
A category hint used by SVAHNAR for icon selection and internal MCP tool mapping. Choose the closest match from the list, or leave it as Custom if your provider is not listed.
This does not affect how the OAuth flow works.
Description (optional)
A short note for yourself and your team explaining what this connection is for.
Example: "Acme Corp's internal project management API — used by the PM agent."
Authorization URL (required when Grant Type = Authorization Code)
The URL where SVAHNAR sends the user to log in and approve permissions. This is the page that opens in the popup.
| Provider | Authorization URL |
|---|---|
https://accounts.google.com/o/oauth2/v2/auth | |
| Slack | https://slack.com/oauth/v2/authorize |
| GitHub | https://github.com/login/oauth/authorize |
| Microsoft | https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize |
| Atlassian | https://auth.atlassian.com/authorize |
| Box | https://account.box.com/api/oauth2/authorize |
| Notion | https://api.notion.com/v1/oauth/authorize |
If your provider (such as Notion) gives you an Authorization URL with extra query parameters in their developer documentation, paste the URL without them. SVAHNAR constructs and appends these parameters (like client_id, redirect_uri, response_type, and state) internally.
-
Example: If the provider documentation lists:
https://api.notion.com/v1/oauth/authorize?client_id=YOUR_CLIENT_ID&response_type=code&owner=userYou should only enter:
https://api.notion.com/v1/oauth/authorize
Not shown for Client Credentials grant type since no user redirect is needed.
Default Scopes (optional)
The permissions your application requests from the provider. Add one scope per line using the + Add Scope button.
Scopes define exactly what data and actions your agent is allowed to perform.
Examples:
- Google Calendar read:
https://www.googleapis.com/auth/calendar.readonly - Slack messaging:
chat:write,channels:read - GitHub repos:
repo - Microsoft Graph:
https://graph.microsoft.com/.default
Only request the scopes your agent actually needs. Over-permissioned tokens are a security risk if a token is ever compromised.
Advanced Configuration
Click Advanced Configuration to reveal these options. Most users won't need to change them.
Revocation URL (Advanced, optional)
The endpoint SVAHNAR calls to revoke the token when you click Disconnect. This is defined in RFC 7009.
If provided, SVAHNAR will actively invalidate the token at the provider on disconnect rather than just deleting it locally. This is important for security — it ensures the token can't be reused even if it's somehow obtained.
| Provider | Revocation URL |
|---|---|
https://oauth2.googleapis.com/revoke | |
| Slack | https://slack.com/api/auth.revoke |
| GitHub | (not supported — omit this field) |
| Microsoft | https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout |
Introspection URL (Advanced, optional)
The endpoint SVAHNAR calls to introspect/inspect the status of an access token directly on the Authorization Server. This is defined in RFC 7662.
If provided, you can click the Introspect Token action button on your connected provider's card in the Connections page. This will call the introspection endpoint, verify the token's active status, and show diagnostic metadata (such as scopes, client identity, and expiration) returned by the AS.
Provider Domain URL (Advanced, optional)
The base URL of the service. Used for display purposes and internal URL construction. Not required for the OAuth flow itself.
Example: https://api.acme.com, https://app.notion.so
Auth Method (Advanced)
How SVAHNAR sends your Client ID and Secret to the Token URL when exchanging codes or refreshing tokens. The correct value depends on what the provider expects.
| Method | Behaviour | Use when |
|---|---|---|
| Client Secret Post (default) | Sends client_id and client_secret as POST body parameters | Most providers (Google, Atlassian, Box, GitHub) |
| Client Secret Basic | Sends credentials as an HTTP Basic Authorization header | Some providers require this (e.g., Notion; RFC 6749 §2.3.1) |
When in doubt, leave this as Client Secret Post.
If your provider (such as Notion) gives you an Authorization URL with extra query parameters in their developer documentation, paste the URL without them. SVAHNAR constructs and appends these parameters (like client_id, redirect_uri, response_type, and state) internally.
-
Example: If the provider documentation lists:
https://api.notion.com/v1/oauth/authorize?client_id=YOUR_CLIENT_ID&response_type=code&owner=userYou should only enter:
https://api.notion.com/v1/oauth/authorize
Supports PKCE (Advanced)
Proof Key for Code Exchange — an extra security measure for the Authorization Code flow, defined in RFC 7636. Check this box if:
- The provider's documentation says PKCE is required or recommended.
- You are connecting a mobile or single-page app registration (public clients).
Note: PKCE is automatically enabled when Dynamic Client Registration is used.
Extra Auth Params (Advanced, optional)
Additional query parameters appended to the Authorization URL when redirecting the user to the provider's login page. Add key-value pairs using + Add Param.
This is for provider-specific requirements that don't fit standard OAuth fields.
Common examples:
| Key | Value | Why |
|---|---|---|
access_type | offline | Google only — required to receive a refresh token so SVAHNAR can renew access without asking the user again |
prompt | consent | Google only — forces the permission screen to show even if the user has approved before (useful when changing scopes or ensuring a fresh refresh token) |
response_type | code | Usually set automatically; some providers need it explicit |
Without access_type=offline for Google, you will not receive a refresh token. This means SVAHNAR can only use the connection for about 1 hour before it expires.
🔁 Token Lifecycle & AS Management
Once saved, SVAHNAR handles the token lifecycle automatically:
- First connect — user clicks Connect → popup opens → user approves → access token + refresh token stored (encrypted).
- Each agent call — SVAHNAR checks Redis cache for a valid token. Cache TTL is 55 minutes.
- Token expiry — If the token is within 60 seconds of expiry, SVAHNAR silently refreshes it using the refresh token (for Authorization Code) or re-fetches via Client Credentials.
- Disconnect — Token revoked at provider (if Revocation URL is set), then deleted locally.
🛠️ Client Management & Diagnostics
For custom OAuth providers, SVAHNAR includes premium actions on the Connections dashboard to manage and diagnose your setup:
- Sync AS: Fetches the current client registration metadata directly from the Authorization Server (AS) using the registration client URI and access token (complying with RFC 7592).
- Sync AS and Push AS actions display a details modal containing the JSON client registration metadata returned by the AS.
- Push AS: Pushes the current local client registration configuration back to the AS to update the remote metadata.
- Introspect Token: Instantly calls the AS introspection endpoint (complying with RFC 7662) to verify token status and displays its raw active/inactive state and metadata.
DCR client management actions (Sync AS / Push AS) require the client to have been dynamically registered with the provider first. This registration is automatically performed when you click Connect on the provider card for the first time. Attempting to sync or push configuration prior to the first connection will result in a No registration_client_uri or registration_access_token found error.
🔌 Using Custom Providers with MCP Servers
This is the most powerful use case for custom OAuth clients: connecting SVAHNAR agents to any MCP server that requires OAuth authentication.
How It Works
When you add oauth_provider_id to an MCP server config, SVAHNAR:
- Looks up the registered OAuth provider by UUID.
- Fetches and decrypts the stored access token for the current user.
- Automatically refreshes the token if it has expired.
- Injects
Authorization: Bearer <access_token>into every HTTP request made to that MCP server.
Your MCP server simply validates the incoming Bearer token against the OAuth provider — SVAHNAR handles all credential management transparently.
Supported MCP Transports
| Transport value in YAML | Behaviour |
|---|---|
http | Streamable HTTP (recommended for most servers) |
streamable_http | Alias for http — same behaviour |
sse | Server-Sent Events — also uses HTTP with Bearer header injection |
stdio transport is intentionally disabled for security. Only HTTP-based transports support OAuth header injection.
Agent YAML Syntax
create_agent_network:
agent-1:
agent_name: "My_OAuth_MCP_Agent"
LLM_config:
params:
model: "gpt-4o"
tools:
mcp_assigned:
- name: my-protected-server # human-readable name
config:
url: "https://mcp.example.com/mcp"
transport: http
oauth_provider_id: "<uuid>" # UUID from the Connections page
agent_function:
- "Use the MCP server tools to complete the task."
incoming_edge:
- Start
outgoing_edge: []
You can also combine OAuth MCP tools with built-in tools:
create_agent_network:
agent-1:
agent_name: "Combined_Agent"
LLM_config:
params:
model: "gpt-4o"
tools:
tool_assigned:
- name: Gmail # built-in tool, uses its own OAuth
mcp_assigned:
- name: custom-crm
config:
url: "https://crm.example.com/mcp"
transport: http
oauth_provider_id: "<uuid-of-crm-provider>"
agent_function:
- "Read emails and sync relevant info into the CRM."
incoming_edge:
- Start
outgoing_edge: []
Static Headers (Alternative to OAuth)
If your MCP server uses API key authentication instead of OAuth, you can pass static headers directly:
tools:
mcp_assigned:
- name: my-api-server
config:
url: "https://api.example.com/mcp"
transport: http
headers:
Authorization: "Bearer ${MY_API_KEY}" # resolved from Key Vault
X-Custom-Header: "my-value"
Use ${VARIABLE_NAME} placeholders to reference secrets stored in your SVAHNAR Key Vault — the values are resolved at runtime and never stored in the agent YAML.
📜 Supported OAuth & OpenID Connect Specifications
SVAHNAR's OAuth engine is compliant with modern security standards and supports the following protocols out of the box:
- RFC 6749 (The OAuth 2.0 Authorization Framework): Supports standard flows (Authorization Code and Client Credentials).
- RFC 6750 (Bearer Token Usage): Transmits and accepts bearer tokens securely in HTTP headers.
- RFC 7009 (Token Revocation): Actively revokes tokens at the authorization server when a connection is disconnected.
- RFC 7523 (JWT Profile for Client Auth): Supports authenticating clients with JSON Web Tokens (JWT) for secure server-to-server exchanges.
- RFC 7591 (Dynamic Client Registration): Registers client metadata dynamically on authorization servers that support dynamic onboarding.
- RFC 7592 (Dynamic Client Registration Management): Actively manages dynamically registered clients, including automated client deregistration upon provider deletion.
- RFC 7636 (Proof Key for Code Exchange - PKCE): Mitigates interception attacks for public clients by generating and verifying random code challenges.
- RFC 7662 (OAuth 2.0 Token Introspection): Inspects token status and metadata directly from the authorization server.
- RFC 8414 (OAuth 2.0 Authorization Server Metadata): Performs metadata discovery from well-known endpoints to automatically resolve auth, token, and registration URIs.
- RFC 8628 (OAuth 2.0 Device Authorization Grant): Supports token authorization flows for input-constrained devices.
- RFC 9068 (JWT Profile for Access Tokens): Validates access tokens in JWT format against public keys.
- RFC 9101 (JWT-Secured Authorization Request - JAR): Passes authorization request parameters securely inside signed JWTs.
- RFC 9207 (Authorization Server Issuer Identification): Prevents mix-up attacks by verifying authorization server issuer parameters.
- OpenID Connect 1.0: Fetches identity credentials via standard OIDC token claims and UserInfo endpoints.
- OpenID Connect RP-Initiated Logout 1.0: Formally requests logout of the end-user session from the OpenID Provider.
💡 Real-World Examples
Example 1: Google Workspace (Custom App)
Your organization has its own Google Cloud project and wants agents to use Gmail and Google Sheets with custom branding on the consent screen.
| Field | Value |
|---|---|
| Provider Name | Google Workspace |
| Provider Type | Google |
| Client ID | (from Google Cloud Console → Credentials → OAuth 2.0 Client IDs) |
| Client Secret | (from Google Cloud Console → Credentials → OAuth 2.0 Client IDs) |
| Grant Type | Authorization Code |
| Token URL | https://oauth2.googleapis.com/token |
| Authorization URL | https://accounts.google.com/o/oauth2/v2/auth |
| Revocation URL | https://oauth2.googleapis.com/revoke |
| Default Scopes | https://www.googleapis.com/auth/gmail.readonlyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/spreadsheetshttps://www.googleapis.com/auth/drive.readonly |
| Extra Auth Params | access_type = offline, prompt = consent |
After connecting, use it with an MCP server that calls Google Sheets:
tools:
mcp_assigned:
- name: google-sheets-mcp
config:
url: "https://sheets-mcp.my-company.com/mcp"
transport: http
oauth_provider_id: "<uuid-of-google-workspace-provider>"
Example 2: Connecting a Custom Slack App
You've built a Slack app for your company's workspace and want agents to post to internal channels.
| Field | Value |
|---|---|
| Provider Name | Company Slack App |
| Provider Type | Slack |
| Client ID | (from Slack API → Basic Information) |
| Client Secret | (from Slack API → Basic Information) |
| Grant Type | Authorization Code |
| Token URL | https://slack.com/api/oauth.v2.access |
| Authorization URL | https://slack.com/oauth/v2/authorize |
| Default Scopes | chat:write, channels:read, channels:history |
Example 3: Azure AD / SharePoint (Machine-to-Machine)
Your organization uses SharePoint and you want an agent to sync documents. No user popup needed — Azure AD issues tokens directly to your registered app.
| Field | Value |
|---|---|
| Provider Name | Azure AD SharePoint |
| Provider Type | SharePoint |
| Client ID | (from Azure App Registration → Application (client) ID) |
| Client Secret | (from Azure App Registration → Certificates & secrets) |
| Grant Type | Client Credentials (machine-to-machine) |
| Token URL | https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token |
| Default Scopes | https://graph.microsoft.com/.default |
Example 4: Internal API with OAuth 2.0
Your team has built an internal REST API that issues tokens via Client Credentials. You want agents to call it via an MCP server.
| Field | Value |
|---|---|
| Provider Name | Internal Analytics API |
| Provider Type | Custom |
| Client ID | (from your API's developer console) |
| Client Secret | (from your API's developer console) |
| Grant Type | Client Credentials |
| Token URL | https://auth.internal.example.com/oauth/token |
| Default Scopes | read:reports, write:dashboards |
tools:
mcp_assigned:
- name: analytics-mcp
config:
url: "https://analytics-mcp.internal.example.com/mcp"
transport: http
oauth_provider_id: "<uuid-of-internal-api-provider>"
With Client Credentials, SVAHNAR automatically fetches and renews the token — no user interaction ever required.
🗑️ Deleting a Custom Connection
To delete a custom OAuth connection you created:
- Open the Connections page.
- Find your custom provider under My Custom Connections.
- Click the trash icon.
This will permanently remove the provider registration and revoke any stored tokens. Agents configured with this provider's oauth_provider_id will stop working until you create a new provider.