Providers¶
A provider profile tells Nexus how to authenticate users against a third-party service and how to apply those credentials to outgoing requests. This guide covers registering new providers, the full range of auth types Nexus supports, and how to list, update, and delete providers after they are registered.
For declarative provider management in production, see Security-as-Code.
Step 1 — Set up the OAuth app in the provider console¶
Every OAuth2 provider requires you to register an application in their developer portal before issuing credentials. The terminology varies — "OAuth Apps", "API Credentials", "Integrations" — but the process is the same: create an app, collect the client ID and secret, and register the Broker's callback URI.
What you need from the provider¶
| Field | Description |
|---|---|
| Client ID | The public identifier for your application |
| Client Secret | The secret Nexus uses to exchange authorization codes for tokens |
| Authorization URL | The endpoint users are redirected to for consent |
| Token URL | The endpoint Nexus calls to exchange codes and refresh tokens |
| Issuer URL | For OIDC-capable providers — replaces auth URL and token URL |
The redirect URI¶
Register the Broker's callback endpoint as the redirect URI in the provider console:
For local development:
The Broker's BASE_URL + /auth/callback must match this exactly. Most providers perform strict string matching — a trailing slash or http vs https mismatch causes every OAuth flow to fail.
Compliance fields¶
Most providers sandbox new apps in "Development Mode" until compliance metadata is filled in. This limits you to a small number of test users and blocks production access.
| Field | What to provide |
|---|---|
| App name | Your product name |
| App logo | Your company logo |
| Website URL | https://your-company.com |
| Privacy Policy URL | https://your-company.com/privacy |
| Terms of Service URL | https://your-company.com/terms |
| Support email | Your support address |
Fill these in before requesting production access from the provider.
Step 2 — Register the provider in Nexus¶
All provider registration goes through POST /v1/providers on the Gateway. The X-API-Key header must carry your API_KEY.
OAuth2 with OIDC discovery¶
Use OIDC discovery when the provider supports it (Google, Microsoft Entra, Okta, Auth0). Nexus fetches the authorization endpoint, token endpoint, and JWKS URI automatically from {issuer}/.well-known/openid-configuration.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "google-workspace",
"auth_type": "oauth2",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"issuer": "https://accounts.google.com",
"enable_discovery": true,
"scopes": ["openid", "email", "profile", "offline_access"]
}' | jq .
OAuth2 with manual endpoints¶
Use manual configuration for providers without OIDC discovery (GitHub, Slack, Stripe, Salesforce).
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "github",
"auth_type": "oauth2",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"auth_url": "https://github.com/login/oauth/authorize",
"token_url": "https://github.com/login/oauth/access_token",
"scopes": ["repo", "read:user"]
}' | jq .
API key provider¶
Static credential providers do not use a redirect flow. The credential_schema defines the form your application presents to collect the credential from the user.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "airtable",
"auth_type": "api_key",
"params": {
"credential_schema": {
"type": "object",
"required": ["api_key"],
"properties": {
"api_key": { "type": "string", "title": "Personal Access Token" }
}
}
}
}' | jq .
Basic auth provider¶
Username and password credentials. The Bridge encodes them as Base64 and sets the Authorization: Basic header automatically.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "jira-basic",
"auth_type": "basic_auth",
"params": {
"credential_schema": {
"type": "object",
"required": ["username", "password"],
"properties": {
"username": { "type": "string", "title": "Username" },
"password": { "type": "string", "title": "Password", "format": "password" }
}
}
}
}' | jq .
AWS SigV4 provider¶
For services that use AWS Signature Version 4 request signing. params.service and params.region configure the signing scope.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "bedrock-us-east",
"auth_type": "aws_sigv4",
"params": {
"service": "bedrock",
"region": "us-east-1",
"credential_schema": {
"type": "object",
"required": ["access_key", "secret_key"],
"properties": {
"access_key": { "type": "string", "title": "AWS Access Key ID" },
"secret_key": { "type": "string", "title": "AWS Secret Access Key" }
}
}
}
}' | jq .
Query param provider¶
Injects the API key into the URL query string instead of a header. params.param_name sets the query parameter name.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "weatherapi",
"auth_type": "query_param",
"params": {
"param_name": "api_token",
"credential_schema": {
"type": "object",
"required": ["api_key"],
"properties": {
"api_key": { "type": "string", "title": "API Token" }
}
}
}
}' | jq .
HMAC signature provider¶
For APIs that require request signing with a shared secret. params.header_name, params.algo, and params.encoding configure the signature format.
curl -s -X POST https://your-gateway.example.com/v1/providers \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "webhook-hmac",
"auth_type": "hmac_payload",
"params": {
"header_name": "X-Signature",
"algo": "sha256",
"encoding": "hex",
"credential_schema": {
"type": "object",
"required": ["api_secret"],
"properties": {
"api_secret": { "type": "string", "title": "Signing Secret" }
}
}
}
}' | jq .
Provider field reference¶
| Field | Type | Description |
|---|---|---|
name |
string | Unique alias. Used in all subsequent operations. |
auth_type |
string | oauth2, api_key, basic_auth, aws_sigv4, query_param, hmac_payload |
client_id |
string | OAuth 2.0 client ID |
client_secret |
string | OAuth 2.0 client secret |
issuer |
string | OIDC issuer URL — required when enable_discovery: true |
auth_url |
string | Authorization endpoint — required when enable_discovery: false |
token_url |
string | Token endpoint — required when enable_discovery: false |
api_base_url |
string | Provider API root URL |
enable_discovery |
boolean | Fetch endpoints from OIDC discovery document |
scopes |
array | Default scopes to request during the OAuth handshake |
params |
object | Provider-specific configuration (schemas, signing params, quirks) |
Provider-specific quirks¶
Some providers deviate from the OAuth2 spec in ways that require additional params:
| Provider | Issue | Fix |
|---|---|---|
| Salesforce | Rejects scope on the authorization URL |
"params": { "skip_scope_on_auth": true } |
| Salesforce | Rejects scope on the token exchange |
"params": { "skip_scope_on_exchange": true } |
| Twitter/X | Requires Basic Auth for token exchange | "auth_header": "client_secret_basic" |
| Microsoft Entra | Requires scope on the token exchange |
Default behaviour — no change needed |
Step 3 — Verify the registration¶
Test an OAuth2 provider by requesting a connection URL and completing the flow in your browser:
curl -s -X POST https://your-gateway.example.com/v1/request-connection \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"workspace_id": "test-user-001",
"provider_id": "PROVIDER_UUID_FROM_REGISTRATION",
"scopes": ["openid", "email"],
"return_url": "https://httpbin.org/get"
}' | jq .
Open the auth_url from the response in a browser. After authorizing, you should be redirected to httpbin.org/get with connection_id and status=success as query parameters.
Listing providers¶
To retrieve a condensed metadata view (useful for rendering a connection UI):
curl -s https://your-gateway.example.com/v1/providers/metadata \
-H "X-API-Key: your-api-key" | jq .
The metadata endpoint returns providers grouped by auth_type, with only the fields needed for connection UI rendering: api_base_url, user_info_endpoint, and scopes.
Updating a provider¶
Use PATCH to update specific fields. Do not delete and recreate a provider — this orphans every active connection that references it.
curl -s -X PATCH https://your-gateway.example.com/v1/providers/PROVIDER_ID \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"client_secret": "ROTATED_SECRET"
}' | jq .
Every update is recorded in the audit log.
Deleting a provider¶
Deleting a provider removes its configuration. Existing connections that reference the provider will fail credential retrieval immediately because the client credentials are gone. Verify you have migrated or decommissioned all dependent connections before deleting.
curl -s -X DELETE https://your-gateway.example.com/v1/providers/PROVIDER_ID \
-H "X-API-Key: your-api-key"
Delete operations are audit-logged with the caller IP and timestamp.