OAuth for Your App

This guide covers how to implement BlueNexus OAuth in your application so your users can connect their BlueNexus account and grant your app access to the API.

Overview

There are two ways to register your app:

  1. Dynamic Client Registration (DCR) — Your MCP client auto-registers by calling POST /v1/auth/register. Best for MCP-only integrations.
  2. Manual Registration — You create an auth client via the BlueNexus dashboard or API. Required for full API access, white-label, or custom branding.

Both use the same OAuth 2.1 + PKCE flow for user authorization.

Step 1: Register Your Auth Client

Option A: Dynamic Client Registration (RFC 7591)

curl -X POST https://api.bluenexus.ai/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My AI App",
    "redirect_uris": ["https://myapp.com/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"],
    "token_endpoint_auth_method": "none",
    "scope": "universal-mcp-read-write agents-use llm-all"
  }'

Response:

{
  "client_id": "client_a1b2c3d4e5f6a1b2c3d4e5f6",
  "client_name": "My AI App",
  "redirect_uris": ["https://myapp.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_method": "none",
  "scope": "universal-mcp-read-write agents-use llm-all"
}

DCR-registered clients always get the THIRD_PARTY role. Rate limit: 5 requests per minute per IP. Unknown scopes are silently ignored.

Option B: Manual Registration (API)

Requires an existing BlueNexus account token:

curl -X POST https://api.bluenexus.ai/api/v1/auth-clients \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My AI App",
    "type": "confidential",
    "roles": ["third-party"],
    "redirectUris": ["https://myapp.com/callback"],
    "allowedScopes": ["universal-mcp-read-write", "agents-use", "llm-all", "connections"],
    "branding": {
      "description": "AI-powered productivity assistant",
      "brandColor": "#4F46E5"
    }
  }'

Response includes clientId and clientSecret (for confidential clients).

Option C: Manual Registration (Dashboard)

Go to app.bluenexus.ai > Developers to create an auth client through the UI.

Step 2: Build the Authorization URL

Generate a PKCE code verifier and challenge, then redirect the user to the authorize endpoint:

// Generate PKCE values
const codeVerifier = generateRandomString(128);
const codeChallenge = base64url(sha256(codeVerifier));
const state = generateRandomString(32);

// Store codeVerifier and state in the user's session

const authorizeUrl = new URL("https://app.bluenexus.ai/oauth/authorize");
authorizeUrl.searchParams.set("response_type", "code");
authorizeUrl.searchParams.set("client_id", CLIENT_ID);
authorizeUrl.searchParams.set("redirect_uri", "https://myapp.com/callback");
authorizeUrl.searchParams.set("scope", "universal-mcp-read-write agents-use llm-all");
authorizeUrl.searchParams.set("state", state);
authorizeUrl.searchParams.set("code_challenge", codeChallenge);
authorizeUrl.searchParams.set("code_challenge_method", "S256");

// Redirect user
redirect(authorizeUrl.toString());

Authorization Parameters

Parameter Required Description
response_type Yes Must be code
client_id Yes Your client ID
redirect_uri Yes Must match a registered redirect URI
scope No Space-separated scopes (defaults to client's allowed scopes)
state Recommended CSRF protection token
code_challenge Yes Base64url(SHA256(code_verifier))
code_challenge_method Yes Must be S256
nonce No OpenID Connect replay protection
provider_permissions No JSON for per-provider granular control
agent_ids No URL-encoded JSON array of agent IDs the token may access. Omit or null for all agents
knowledge_base_ids No URL-encoded JSON array of knowledge base IDs the token may access. Omit or null for all KBs

For example, to restrict a token to a single agent:

authorizeUrl.searchParams.set("agent_ids", JSON.stringify(["agent_id_1"]));
// Encodes to: agent_ids=%5B%22agent_id_1%22%5D

Restrictions are enforced for the lifetime of the session and carry through token refreshes. A token with agent_ids set is blocked from calling /v1/agents/* for any agent not in the list.

What the User Sees

The user is presented with a consent screen showing:

  • Your app's name and branding
  • The scopes you're requesting (described in user-friendly terms)
  • Their connected services (if MCP scopes are requested)
  • Agent and knowledge base selectors (if agent_ids or knowledge_base_ids are specified)

The user can review and adjust which providers your app can access.

Step 3: Handle the Callback

After the user authorizes, they're redirected to your redirect_uri with an authorization code:

https://myapp.com/callback?code=AUTH_CODE_HERE&state=your-state-token

Verify the state matches what you stored in Step 2.

If the user denies access:

https://myapp.com/callback?error=access_denied&error_description=The+user+denied+the+request

Step 4: Exchange Code for Tokens

For Public Clients (SPAs, mobile)

curl -X POST https://api.bluenexus.ai/api/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://myapp.com/callback" \
  -d "client_id=client_a1b2c3d4e5f6a1b2c3d4e5f6" \
  -d "code_verifier=your-code-verifier"

For Confidential Clients (Server-side)

curl -X POST https://api.bluenexus.ai/api/v1/auth/token \
  -u "client_a1b2c3d4e5f6a1b2c3d4e5f6:secret_your-client-secret" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://myapp.com/callback" \
  -d "code_verifier=your-code-verifier"

Token Response

{
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "expires_in": 900,
  "refresh_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_expires_in": 604800,
  "scope": "universal-mcp-read-write agents-use llm-all",
  "id_token": "eyJhbGciOiJSUzI1NiIs..."
}

The id_token is included when the openid scope was requested.

Step 5: Use the Access Token

Include the access token in all API requests:

# MCP endpoint
curl -X POST https://api.bluenexus.ai/mcp \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":"1"}'

# REST API
curl https://api.bluenexus.ai/api/v1/connections \
  -H "Authorization: Bearer ACCESS_TOKEN"

Step 6: Refresh Tokens

Access tokens expire after ~15 minutes. Use the refresh token to get a new pair:

curl -X POST https://api.bluenexus.ai/api/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN" \
  -d "client_id=client_a1b2c3d4e5f6a1b2c3d4e5f6"

Refresh tokens are single-use — each exchange returns a new refresh token. Store the new one immediately.

Revoking Tokens

To revoke a token (e.g., on user logout):

curl -X POST https://api.bluenexus.ai/api/v1/auth/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_OR_REFRESH_TOKEN" \
  -d "client_id=client_a1b2c3d4e5f6a1b2c3d4e5f6"

Previewing the Consent Screen

Use the validate endpoint to preview what users will see without actually authorizing:

curl "https://api.bluenexus.ai/api/v1/auth/validate?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://myapp.com/callback&scope=universal-mcp-read-write&code_challenge=test&code_challenge_method=S256"

Returns the client info, requested scopes, and available providers.

Next Steps