Home/Docs/OAuth & integrations
🔌 Infrastructure

OAuth & integrations via Nango

The integration catalog — Google, Slack, Microsoft, and more — connects through Nango, an OAuth connection broker. The tenant server is the only thing that talks to Nango; the Flutter app never sees provider tokens. This page covers running Nango, the callback proxy, registering provider credentials, and hardening the admin surface.

ℹ️
Nango brokers OAuth, LangGraph runs the work

Nango handles OAuth connections, token storage, and proxied API calls. It is not the automation engine — agents and workflows execute on the Python LangGraph engine. Nango is the connection layer those tools call through.

How a connection flows

A user clicks Connect; the tenant server injects the provider's client credentials into Nango; the user completes consent at the provider; and Nango keeps the resulting tokens. Every later API call is proxied through Nango so tokens stay server-side.

🖱️Click ConnectIn the app
🗝️Tenant serverInjects client creds
🔁NangoRuns OAuth handshake
🔐ProviderUser grants consent
Tokens storedIn Nango, server-side
OAuth runs server-side through Nango — the app never holds provider tokens.

Hosted vs self-hosted Nango

You can use Nango Cloud or run Nango yourself. Self-hosting keeps every OAuth secret on your own infrastructure, which is the right choice for an air-gapped or compliance-bound deployment.

OptionBest forOperational note
Nango CloudFastest path; no infrastructure to runProvider secrets live in Nango's hosted environment
Self-hosted NangoFull data residency and air-gapped deploymentsAction execution needs the full process set, not just the server container (see below)
⚠️
Self-hosting: OAuth works, actions need more

The nangohq/nango-server:hosted image runs only the server process — enough for OAuth connections, the catalog, and action discovery. Executing integration actions also needs the orchestrator, jobs, persist, and runner processes. Run those as additional containers (the deploy defines them under a nango-full Compose profile). Without them an action fails with a "runtime is starting up or not available" message.

The tenant-server callback proxy

OAuth providers redirect the user's browser to a publicly reachable callback URL, which would otherwise mean exposing Nango on its own public hostname — surface area you can simply avoid. Instead, the tenant server hosts a thin proxy that replays the OAuth callback to Nango over the internal Docker network, so Nango never needs a public hostname.

EnvironmentCallback URL
Productionhttps://ai.yoffice.ai/integrations/oauth-callback
Local devhttps://tenant-api.dev.yoffice.ai/integrations/oauth-callback

The proxy forwards the query string, cookies, and User-Agent verbatim, relays Set-Cookie and 3xx Location headers back to the browser without following redirects itself, and caps the response body at 1 MiB. It accepts GET only. To switch the flow over, update each provider's authorised redirect URI to the proxy URL and point Nango's NANGO_SERVER_URL at the proxy so it advertises the matching redirect_uri.

Registering provider credentials

Each provider you enable needs its own OAuth app registered both at the provider and in Nango. The flow is the same for every integration:

  1. Create the OAuth app at the provider

    In the provider's developer console (Google Cloud Console, Slack API, Azure AD, the GitHub developer settings, …) register an OAuth app and request the scopes that integration needs. Note the client ID and client secret.

  2. Set the redirect URI to the callback proxy

    Point the app's authorised redirect URI at the tenant-server callback proxy — for production, https://ai.yoffice.ai/integrations/oauth-callback. Many providers let you register more than one URI, so you can keep an old one in place while you migrate.

  3. Add the integration in the Nango dashboard

    Open the Nango dashboard (reached over an SSH tunnel for a hardened self-hosted instance), choose Set up new integration, pick the provider template, and paste the client ID and secret. Nango's provider key uses hyphens — for example google-mail for Gmail, not gmail.

  4. Connect from the app

    In Your Office AI, open Integrations, click Connect on the integration, and complete the consent flow. Nango stores the access and refresh tokens; the Flutter app never touches the provider or Nango directly.

Provider key conventions

Nango provider keys use hyphens, and they do not always match the Flutter catalog ID. A mismatch here is the classic cause of a "connect fails" bug. The Flutter side maps its catalog ID to the Nango key via CatalogIntegration.nangoProviderKey — that field is the source of truth.

Flutter catalog IDNango provider key
google_calendargoogle-calendar
google_drivegoogle-drive
gmailgoogle-mail (not gmail)
google_tasksgoogle-tasks
outlook_calendaroutlook-calendar
microsoft_teamsmicrosoft-teams
onedriveonedrive
slackslack
githubgithub
💡
Base-URL allowlist for split-host APIs

Some providers serve binary content from a different host than their JSON API (Dropbox uses content.dropboxapi.com for downloads). The materializer routes those through Nango's Base-Url-Override header, so add the content host to the provider's "Base URL Override Allowlist" in the Nango provider config.

Security considerations

Nango's admin dashboard and admin API show every configured provider's client ID and secret, and Nango OSS ships with its auth gate off, so keep the admin surface private — reachable only from your own infrastructure, never the public internet. The defenses below make that straightforward.

DefenseWhat it does
Loopback port bindingBind Nango's port 3003 to 127.0.0.1 only, so it is never reachable from the public internet.
nginx path allowlistAllow only the OAuth, Connect, and webhook paths through the vhost; every other path (including /api/v1/* and the dashboard) returns 403.
SSH-tunnel-only dashboardReach the dashboard by forwarding localhost:3003 over SSH. The tunnel itself is the access control — no public login.
Remove from public DNSOnce the callback proxy is live, delete the public Nango vhost and DNS record entirely so Nango has no public surface area at all.
💡
Encryption key and webhook secrets

Set a strong NANGO_ENCRYPTION_KEY so stored tokens are encrypted at rest inside Nango, and verify inbound provider webhooks by their signed secret. On the Your Office AI side, stored integration credentials and API keys get an additional layer of AES-GCM encryption at the application layer.

ℹ️
Next

Continue to Voice providers to enable the unified voice bridge, or read the Integrations guide for how the catalog is used day to day.