Skip to content

Feature request: make the inbound integration webhook URL independently configurable (decouple from NANGO_SERVER_URL) #6614

Description

@ksk-ktsr

Summary

Self-hosted Nango already lets operators put several public surfaces on their own hosts/paths — Connect UI (NANGO_PUBLIC_CONNECT_URL), the WebSocket path (NANGO_SERVER_WEBSOCKETS_PATH), and the OAuth callback URL (customizable in Environment Settings > Callback URL). The inbound integration webhook URL (the per-integration URL Nango generates, shows under Integrations > [Integration] > Webhooks, and that we register in each provider's portal) is the one public surface with no independent configuration: it is derived from NANGO_SERVER_URL.

We'd like the inbound webhook base URL to be independently configurable as well, consistent with how the OAuth callback URL already works.

Current behavior

  • NANGO_SERVER_URL defines the base instance URL, which also determines the generated inbound webhook URLs.
  • The OAuth callback URL can already be overridden independently (Environment Settings > Callback URL).
  • Connect UI and WebSocket path are independently configurable.
  • There is no equivalent override for the inbound webhook URL: it always reflects NANGO_SERVER_URL.

The gap / asymmetry

The OAuth callback URL is decoupled from NANGO_SERVER_URL, but the inbound webhook URL is not — even though both are public, third-party-facing surfaces. Because Nango generates and advertises the webhook URL (shown in the dashboard and registered with providers), this cannot be solved purely at our reverse proxy / ingress layer: even if we route /webhook/* to a dedicated host, the URL Nango displays and registers would still point at the NANGO_SERVER_URL host. Only Nango can make the advertised webhook base URL configurable.

Why this is generally useful (not deployment-specific)

Inbound webhooks are a distinct trust surface from the API and dashboard: public, machine-to-machine, signature-authenticated endpoints receiving traffic from external SaaS providers with broad/unpredictable source IPs. This enables:

  • Network segmentation: route /webhook/* to a dedicated ingress/gateway with its own WAF, rate-limiting, and DDoS posture, separate from the API/dashboard surface — a standard requirement for the large/regulated enterprises self-hosting targets.
  • Minimize public attack surface: keep the API surface private/internal (consumed only by your own backend) and expose only the webhook surface publicly. Today, coupling the webhook URL to NANGO_SERVER_URL forces the server host to be the public webhook host.
  • Stable, dedicated webhook domain: webhook URLs are registered with providers and are effectively permanent; operators often want them on a dedicated domain decoupled from the app/API domain.

Proposed solution

Allow the inbound webhook base URL to be configured independently of NANGO_SERVER_URL, in the same spirit as the existing OAuth callback URL override. Either mechanism works for us:

  • a new env var (e.g. NANGO_WEBHOOK_URL / NANGO_PUBLIC_WEBHOOK_URL), and/or
  • an Environment Settings field (mirroring the existing "Callback URL" setting).

Requirements:

  • The generated/advertised integration webhook URL (dashboard display + what gets registered with providers) uses the configured base, not NANGO_SERVER_URL.
  • Inbound requests are accepted on the configured webhook host when arriving via a different DNS/ingress.
  • Backward compatible: when unset, behavior is unchanged and the webhook URL falls back to NANGO_SERVER_URL.

Acceptance criteria

  • With the new setting configured, the webhook URL shown under Integrations > [Integration] > Webhooks reflects the configured base.
  • A provider POST to the configured webhook host is accepted and attributed correctly.
  • With the setting unset, current behavior is unchanged.

Open question for maintainers

Is there already any supported way to override the advertised inbound webhook base URL independently of NANGO_SERVER_URL that we may have missed?

Context (one motivating deployment)

We self-host Nango (Enterprise, multi-region) and expose public surfaces through separate gateways by trust level. We can place /oauth/callback and /connect/* on a customer-facing gateway and the dashboard on an internal, IP-restricted gateway. We'd like to place the inbound /webhook/* surface on a dedicated public gateway with webhook-appropriate protections, while keeping the API surface internal — currently blocked only by the webhook URL being tied to NANGO_SERVER_URL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions