Skip to content

Bridge Express is configured with a single createBridge(config) call at startup. There are no modules, no decorators, no dependency injection. The config object is typed as BridgeConfig.

import { createBridge } from '@nebulr-group/bridge-express';

const bridge = createBridge({
  appId: 'YOUR_APP_ID',
  guard: {
    defaultAccess: 'protected',
    rules: [{ path: '/health', privilege: 'ANONYMOUS' }],
  },
});

app.use(bridge.auth());

There’s no async-factory ceremony. Read environment variables directly when you build the config:

import 'dotenv/config';
import { createBridge } from '@nebulr-group/bridge-express';

const bridge = createBridge({
  appId: process.env.BRIDGE_APP_ID!,
  apiBaseUrl: process.env.BRIDGE_API_BASE_URL || undefined,
  debug: process.env.BRIDGE_DEBUG === 'true',
  guard: {
    defaultAccess: 'protected',
    rules: [{ path: '/health', privilege: 'ANONYMOUS' }],
  },
});
VariableDescriptionDefault
BRIDGE_APP_IDYour Bridge app ID(required)
BRIDGE_API_BASE_URLBridge API base URLhttps://api.thebridge.dev
BRIDGE_DEBUGEnable debug loggingfalse
BRIDGE_APP_ID=your-app-id-here
BRIDGE_DEBUG=true
OptionTypeDefaultDescription
appIdstring(required)Your Bridge app ID
apiBaseUrlstringhttps://api.thebridge.devBase URL for the Bridge API. All other endpoints are derived from this.
guardGuardConfig(none)Declarative route rules + default access; see Route guards
debugbooleanfalseEnable debug logging
introspectionUrlstring{apiBaseUrl}/account/api-token/introspectOverride the API-token introspection endpoint, for environments where the process reaches Bridge over a private network address that differs from the public apiBaseUrl
introspectionCacheTtlMsnumber0How long (ms) a successful API-token introspection is cached, keyed by token. 0 disables caching, so every request introspects (instant revocation); raise it to trade revocation latency for fewer network calls.
userJwksUrlstring{apiBaseUrl}/auth/.well-known/jwks.jsonOverride the JWKS URL for user-JWT verification; same private-network use case as introspectionUrl

Everything is derived from apiBaseUrl unless overridden:

PurposeDerived URLOverride
User JWT verification (JWKS){apiBaseUrl}/auth/.well-known/jwks.jsonuserJwksUrl
Feature flag evaluation{apiBaseUrl}/cloud-views(none)
API token introspection{apiBaseUrl}/account/api-token/introspectintrospectionUrl
Unified tenant surface (bridge.fromJwt()){apiBaseUrl}/session/init(none)

In most deployments you set only appId (and optionally apiBaseUrl). The introspectionUrl and userJwksUrl overrides exist specifically for environments (Docker, private VPCs) where the process reaches the Bridge over an address that differs from the public apiBaseUrl.

const BRIDGE_DEFAULTS = {
  apiBaseUrl: 'https://api.thebridge.dev',
  debug: false,
  defaultAccess: 'protected',
};

Route rules govern the declarative bridge.auth() middleware. Roles and feature flags are applied per route with bridge.protect(...), not in route rules; see Route guards.

FieldTypeDescription
pathstringREST URL wildcard pattern (e.g. /account/subscription/*). * matches any characters, including /.
graphqlOperationstringGraphQL operation name. Present on the type for cross-framework parity; not wired in the Express plugin.
privilegeRoutePrivilege (required)Required privilege level for this route.
plansstring[]Declared on the type but not yet enforced by the middleware; a matching rule’s plans list is currently ignored. For plan-based gating that actually blocks requests, use entitlement checks via bridge.fromJwt(...) (see Tenant Data).
type RoutePrivilege =
  | 'ANONYMOUS'       // No authentication required
  | 'AUTHENTICATED'   // Any valid credential (user JWT or API token)
  | 'USER_READ'       // Requires USER_READ in the user JWT privileges claim
  | 'USER_WRITE'      // Requires USER_WRITE in the user JWT privileges claim
  | 'TENANT_READ'     // Requires TENANT_READ in the user JWT privileges claim
  | 'TENANT_WRITE'    // Requires TENANT_WRITE in the user JWT privileges claim
  | string;           // Any custom privilege string

A specific privilege (anything other than ANONYMOUS / AUTHENTICATED) requires that string to appear in the user JWT’s privileges claim.

FieldTypeDefaultDescription
defaultAccess'public' | 'protected''protected'Access level when no rule matches
rulesRouteRule[][]Centralized route rules

Unlike a module-based framework, there is no global flag; the guard becomes “global” simply by mounting bridge.auth() with app.use(...). Mount it on a sub-router instead to scope the declarative rules to a subtree of routes.

Some settings aren’t passed to createBridge(...) at all. They’re set once per app in Control Center (your admin dashboard at app.thebridge.dev) or via the CLI, and Bridge enforces them server-side regardless of which SDK is talking to it:

SettingWhat it does
Redirect URIsThe allowlist of callback URLs Bridge is allowed to redirect a frontend sign-in flow to.
Allowed originsThe CORS allowlist: origins permitted to call the Bridge API directly from a browser.
Default callback URLUsed whenever a frontend doesn’t pass an explicit callback URL in code.
SSO providersFederation connections (Google, Azure AD, etc.) available to the sign-in flow.

These matter to an Express backend indirectly: your appId ties this backend to the same app record these settings live on, so the JWKS/introspection endpoints your middleware calls, and the tokens your frontend obtains, are all scoped consistently to one app configuration.

bridge app update \
  --redirect-uris "https://app.example.com/oauth-callback,https://admin.example.com/oauth-callback" \
  --allowed-origins "https://app.example.com,https://admin.example.com" \
  --default-callback-uri "https://app.example.com/oauth-callback"

bridge setup sso --provider google --client-id <clientId> --client-secret <clientSecret>
  • Control Center: the same settings, managed from your app’s settings.
  • MCP (AI-assistant integration): connect your AI assistant to https://api.thebridge.dev/mcp as a remote MCP server (sign in and approve access to your app in the browser when it asks). Its add_redirect_uri and remove_redirect_uri tools change redirect URIs one at a time, update_app sets allowed origins (the list you pass replaces the whole list) and the default callback URL, and setup_sso saves an SSO provider’s credentials and turns it on.