Configure connection OAuth
Langflow's connection broker authorizes Google, Microsoft, and Slack registrations, stores tokens in encrypted connection records, and refreshes them in the worker that uses them. Configure registrations on the backend instance before connecting an account.
To connect an account in Settings and select it on a component, see Connections. This page is the operator setup those connections depend on.
Instance configuration
LANGFLOW_CONNECTION_OAUTH_REGISTRATIONS is a JSON object keyed by registration name.
Registration names, such as google-work, are selected when starting consent. They are
separate from the portable connection handle, such as google/work, stored in a flow.
The supported provider keys are google, microsoft, and slack.
{
"google-work": {
"provider": "google",
"owner": "customer",
"context": "self_managed",
"client_type": "confidential",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://langflow.example/api/v1/connections/oauth/google/callback",
"scopes": ["https://www.googleapis.com/auth/calendar.events.readonly"]
}
}
Load this JSON through your deployment's secret manager. Do not put registration
secrets in flow inputs, global variables, source control, or frontend configuration.
All LANGFLOW_CONNECTION_OAUTH_ settings are covered by the existing protected
environment-variable prefix. Registration JSON and individual secret fields are also
redacted in structured logs. All workers must have the same registration configuration,
database, and LANGFLOW_SECRET_KEY.
The scopes array is an operator-controlled ceiling. The start request must select a
nonempty subset; it cannot supply endpoints, a redirect URI, a client ID, or secrets.
Changing a registration's provider, client ID, scopes, tenant restrictions, profile, or
redirect invalidates its pending consent and requires affected connections to reconnect.
Client secrets and certificates can rotate without changing that binding.
LANGFLOW_CONNECTION_OAUTH_CONTEXT defaults to self_managed, which accepts customer-owned
registrations. Set it to hosted for a hosted instance. A hosted registration with
owner: "langflow" additionally requires LANGFLOW_CONNECTION_OAUTH_HOSTED_ENABLED=true.
No provider registration is enabled without explicit configuration.
For Desktop, set the context to desktop, configure a public client, and use the exact
loopback callback, for example http://localhost:7860/api/v1/connections/oauth/google/callback.
Public registrations cannot contain a client secret or private key, and consent for a
public client always uses PKCE. A Desktop distribution can provision Langflow-owned client
IDs with owner: "langflow"; customer-owned registrations use the same configuration format
and remain available as the override for tenants that require their own registration.
Register and configure the actual client IDs before shipping. The broker does not provide
an OAuth redirect relay or provision provider apps.
Use the same hostname in the browser and the redirect (localhost and 127.0.0.1 have
different cookie origins). Both loopback IP families are supported.
Customer-owned Google registration
- In a Google Cloud project, enable the APIs needed by the selected actions, such as Google Calendar API. Configure the OAuth consent screen, audience, and test users.
- Create a Web application OAuth client for a self-managed or hosted server. Add
https://YOUR_INSTANCE/api/v1/connections/oauth/google/callbackas an authorized redirect. For Desktop, create a Desktop app client and configure its loopback redirect. - Add a registration with
provider: "google", the client ID, and the web client's secret when using a confidential client. Set the allowedscopesexplicitly. - To restrict accounts to Workspace domains, set
allowed_tenantsto the permitted domain names and includeopenidandemailin both the configured and requested scopes. The broker validates the signed ID token's issuer, audience, expiry, and hosted-domain claim. A domain hint in the authorization URL is not sufficient. - Run the consent check below. The broker requests offline access and consent; verify refresh succeeds before using a connection for non-interactive execution.
Sensitive and restricted scopes can require Google verification. Use an approved scope profile and test users until verification is complete. Follow Google's web server registration guide, Desktop guide, and ID-token validation requirements.
Google sign-in errors
If Google shows redirect_uri_mismatch, compare the redirect_uri in the selected
registration under LANGFLOW_CONNECTION_OAUTH_REGISTRATIONS with the authorized
redirect URI on that OAuth client in Google Cloud. That configured value is the URI
this instance sends to Google. Match the scheme, hostname, port, and path exactly,
including /api/v1/connections/oauth/google/callback. For example,
http://127.0.0.1:7896/api/v1/connections/oauth/google/callback does not match the
same URL on port 7895, or one using localhost instead of 127.0.0.1.
If Google shows invalid_client, check that the registration's client_id matches
the intended Google Cloud OAuth client. Apply corrected registration settings to
every Langflow worker and restart the deployment before choosing Try Again.
Retrying without changing the registration repeats the same error.
Google's error page can isolate its popup from Langflow, so Langflow can no longer track the window even while it remains open. The dialog reports that loss of tracking and keeps checking for the server's authorization result until the sign-in link expires. Inspect the provider window for the actual error. Langflow cannot read its contents, and loss of tracking does not mean you closed the window.
Customer-owned Microsoft registration
- In Microsoft Entra, create an app registration for the intended tenant and record its
application ID and directory (tenant) UUID. This broker uses a fixed tenant authority;
commonandorganizationsauthorities are not accepted. - Add a Web redirect for a server or Mobile and desktop applications redirect for
Desktop:
/api/v1/connections/oauth/microsoft/callbackon the configured instance. - Add delegated Graph permissions for the selected actions. Grant administrator consent
where required by your organization's policy. Include
offline_accesswhen refresh is required, and include it in both the configured and requested scopes. - Configure
provider: "microsoft",tenant,client_id,redirect_uri, andscopes. A confidential registration uses eitherclient_secretor an RSA PEMprivate_keywithcertificate_thumbprint(the certificate's SHA-256 digest as 64 hexadecimal characters). Upload the matching certificate to the app registration. Assertions use PS256, the token endpoint audience, and a five-minute lifetime. - For Desktop, use
client_type: "public"with no secret or private key. Run the consent check below and verify a worker refresh after the initial access token expires.
See Microsoft's authorization code flow, redirect URI rules, and certificate credential format.
Microsoft does not expose a standard per-grant token revocation endpoint for this flow.
Langflow removes local credentials and returns provider_revocation: "unsupported".
An administrator or user must remove the app's consent in Entra when upstream revocation
is required; already-issued access tokens follow Microsoft's lifetime and revocation rules.
Customer-owned Slack registration
- Create a Slack app in the target workspace. Under OAuth & Permissions, register
https://YOUR_INSTANCE/api/v1/connections/oauth/slack/callback. - Configure User Token Scopes for a
profile: "user"registration or Bot Token Scopes forprofile: "bot". Use separate named registrations and connections for these identity types; the broker selects and validates the corresponding token. - Configure
provider: "slack",client_id,client_secret,redirect_uri, andscopes. Setallowed_tenantsto workspace IDs to restrict installation. The broker checks the workspace returned by Slack before storing credentials. - Enable token rotation if required. Refresh tokens are replaced atomically under the connection lock, and the replacement stays in encrypted storage.
- For Desktop, use a separate app with PKCE enabled,
client_type: "public", no secret,profile: "user", and a localhost redirect. PKCE opt-in is one-way; Slack Desktop redirects cannot request bot scopes. Run the consent check below.
See Slack's installation guide, PKCE requirements, token rotation, and token revocation.
Consent and revocation check
Use the browser logged in to the configured Langflow origin. The existing connections
API creates metadata first; use executing_identity.identity: "user_delegated" for
Google, Microsoft, and Slack user connections, or "bot" for Slack bot connections.
Instance-owned connections require a superuser. Tokens are not part of these requests.
Bot identity and connection ownership are independent. A regular user can create a
user-owned Slack bot connection and authorize an operator-configured profile: "bot"
registration, subject to connection permissions and Slack's installation/consent policy.
The identity match prevents a user-token registration from populating a bot connection
and vice versa; it is not an operator-only gate. Creating and changing an instance-owned
connection remains superuser-only. Configuring registrations and their scope ceilings
requires access to instance configuration.
Registration configuration is operator-only, so a client discovers the ids it may name, and the scopes it may request, from the listing endpoint. It returns availability and non-secret fields only: client ids, secrets, private keys, and redirect URIs stay on the server. A registration this deployment context would refuse, and a provider outside the integration policy's approved set, are omitted rather than listed, so a picker never offers consent that cannot start.
GET /api/v1/connections/oauth/registrations?provider=google
{
"registrations": [
{
"id": "google-work",
"provider": "google",
"profile": "user",
"context": "self_managed",
"client_type": "confidential",
"scopes": ["https://www.googleapis.com/auth/calendar.events.readonly"],
"allowed_tenants": []
}
]
}
From an authenticated browser API client, start consent:
POST /api/v1/connections/CONNECTION_ID/oauth/start
Content-Type: application/json
{"registration_id":"google-work","scopes":["https://www.googleapis.com/auth/calendar.events.readonly"]}
Navigate that same browser to the returned authorization_url. Starting consent sets
an HttpOnly, SameSite=Lax cookie. An authorization URL copied to another browser cannot
complete the connection. The callback returns a static success or failure page and never
tokens. State expires after ten minutes, is consumed once even when the provider rejects
the code, and is invalidated by a newer consent attempt or revocation.
Verify the connection's metadata and scopes using GET /api/v1/connections, then call
POST /api/v1/connections/CONNECTION_ID/test with the required scopes. Verify non-owner
access is denied under your authorization policy. Set allow_non_interactive explicitly
when this connection may be used by background or serving workers.
allow_non_interactive is a connection-level permission and survives reauthorization,
including reconnecting after an expired or revoked grant. Reconnecting preserves both
enabled and disabled settings; it does not grant unattended access. To withdraw that
permission, use PATCH /api/v1/connections/CONNECTION_ID with
{"allow_non_interactive":false}. Revocation still blocks all credential use until a
new authorization succeeds.
Refresh happens within the executing worker. Database transaction locks serialize refresh, consent completion, health checks, revoke, and delete. No token is placed in a job payload. When a provider rejects a cached token, the worker supplies only its digest to coordinate one replacement with other workers. A successful rotating-token exchange is committed even if subsequent scope validation rejects execution.
POST /api/v1/connections/CONNECTION_ID/revoke always removes local credentials and
invalidates pending consent. Its provider_revocation field reports revoked,
unsupported, failed, or not_applicable. On failed, revoke access in the provider's
account/app console too. Delete attempts the same provider revocation before removing the
record. A previously issued credential already held by an in-flight provider request cannot
be recalled locally; subsequent connection resolution fails after revoke.
The backend removes callback query strings from its access-log request scope. Configure reverse proxies and external request tracing to omit callback query strings as well, because those systems observe requests before Langflow does. Avoid capturing browser callback URLs in screenshots or support logs.
Executing identity per entry point (INT-6)
A connection resolves under the identity of the run that needs it, not under whoever happens to be authenticated. Every Langflow entry point stamps that identity on the graph before it executes, and the resolver enforces the rule below. A graph that reaches a component without one resolves nothing, so a misconfigured or unrecognized path fails closed rather than borrowing someone else's credential.
| Entry point | Runs as | Which connection it may use |
|---|---|---|
Playground and canvas builds, POST /api/v1/run, the OpenAI-compatible Responses API, voice, POST /api/v2/workflows | the authenticated caller | that caller's own connection, or one explicitly shared with them |
POST /api/v1/webhook/FLOW_ID | the published flow's owner | the owner's connection, and only when allow_non_interactive is set on it |
| Deployments on the serving plane | the deployment owner | the owner's connection, and only when allow_non_interactive is set on it |
| A resumed background or human-in-the-loop run | the owner of the job that started it | that owner's connection with allow_non_interactive set; the identity is recomputed on the worker and is never read back from the checkpoint |
| MCP (legacy transport and MCP projects) | the transport's authenticated user | that user's own connection only — a shared connection is not used, because a shared flow is not admitted through MCP either |
| Shareable-playground links, the public workflow endpoint, and A2A | an isolated anonymous principal | none: no user connection and no instance connection, whatever the flow references |
Two rules are worth stating plainly, because they change what a working flow does when it is published:
- Owner-based non-interactive execution needs an explicit opt-in. Webhooks, deployments, and resumed
background or human-in-the-loop jobs require the connection's owner to set
allow_non_interactive. This applies even when the caller and owner are the same person. It describes the execution identity, not whether someone is at a keyboard: an API-key call toPOST /api/v1/runuses the authenticated caller's own or explicitly shared connection and does not require this opt-in, even when invoked by cron. - Publishing a flow does not publish its credentials. Making a flow public, or exposing it over A2A,
means the run resolves no connection at all. For a public link or an unauthenticated A2A agent
(
auth_type=none) that is the anonymous principal doing what it must. An A2A agent protected with an API key or OAuth is held to the same floor in 1.13: A2A admission is not a route through which one account's credential is used on another's behalf, so an agent that needs a connection should be reached through a flow run instead. Use an authenticated run route with an owned, explicitly shared, or policy-authorized instance connection; an instance connection does not bypass the public or A2A restriction.
An instance-owned connection resolves for any authenticated principal in the deployment. Provisioning one
is therefore a deployment-wide grant of that provider account; see
design/dedicated-integrations/decisions/instance-connection-referenceability.md.
Errors a caller sees
When resolution fails, the response carries a machine-readable error_code (connection-unresolved,
connection-not-authorized, auth-expired, scope-missing, rate-limited, provider-unavailable, network-error,
action-unsupported, invalid-request, resource-not-found) together with hint, provider, retryable, and retry_after where it applies, and
the HTTP status the provider situation warrants (403 for an unauthorized connection, 401 for expired
credentials, 429 for a rate limit). The error's own sentence, which names the connection handle, is returned
only to the flow's owner; delegated and anonymous callers get a generic message alongside the same code, so
a client can still show the right call to action without learning which account the owner connected.
Google Workspace actions report network-error when the Langflow server cannot communicate with the
Google API because of a timeout, DNS lookup failure, refused connection, unreachable network, or TLS
failure. The message includes the API hostname and guidance to check the server's outbound network
access. These failures return HTTP 504 for a timeout or 502 for other transport failures. Langflow does
not automatically retry them because a timed-out write may already have reached Google. An actual HTTP 5xx
response still reports provider-unavailable (except 501, which reports action-unsupported).
Google Workspace socket operations use a 10-second timeout. This is not a total action deadline or an
IPv4 fallback guarantee, and DNS resolution or multi-chunk transfers can take longer.
For connection-not-authorized, the hint distinguishes a missing allow_non_interactive opt-in from a
public/A2A execution or an execution whose identity was not supplied by the host. Owner diagnostics also
include details.reason (non-interactive-opt-in-required, anonymous-principal, or unknown-principal).
The opt-in hint asks the connection owner to enable the setting and retry; it contains no connection name,
owner ID, or credential, so delegated callers can pass the remedy along safely. A caller without ownership
or an explicit share receives no information about another user's connection or its opt-in setting.
Microsoft 365 bundle
The Microsoft 365 bundle resolves its connections through a
provider: "microsoft" registration configured above. Its components hold a
portable handle such as microsoft/work, never a token.
Configure Langflow for Microsoft Entra walks through the server registration and the Settings connection. Create the application itself in Microsoft Entra. Two constraints are worth repeating here.
Use Microsoft's short scope names, such as Mail.Read, consistently in the
registration and consent request. For execution checks, the resolver normalizes
Microsoft Graph's fully qualified names (such as
https://graph.microsoft.com/Mail.Read) to the same permission.
Include offline_access in the registration's scopes, because it is what makes
Entra issue a refresh token. No component requires it as an action permission:
Entra never echoes offline_access in a token response, so requiring it per
action would fail every Microsoft resolution.
Only customer-owned single-tenant registrations are configurable today, since this broker uses a fixed-tenant authority. A Langflow-owned multitenant application, which also needs Entra publisher verification, is a follow-up.
Slack redirect URLs and scopes per action
Redirect URLs
Register both forms the deployment needs. A server redirect is used for hosted and self-managed instances; the loopback form is used by the Desktop PKCE app.
https://YOUR_INSTANCE/api/v1/connections/oauth/slack/callback
http://localhost:7860/api/v1/connections/oauth/slack/callback
Scopes per action
The lfx-slack bundle declares these scopes per action. A registration's scopes
array is the operator ceiling, so it must be a superset of the actions you intend to
enable; the connection then requests the subset an action needs.
| Action | Identity | Registration | Scopes |
|---|---|---|---|
| Search | user | profile: "user" | search:read |
| Read Thread | user | profile: "user" | channels:history, groups:history, im:history, mpim:history |
| Send Message | user | profile: "user" | chat:write |
| Create Canvas | user | profile: "user" | canvases:write |
| Post Message | bot | profile: "bot" | chat:write |
| Add Reaction | bot | profile: "bot" | reactions:write |
| List Channel Members | bot | profile: "bot" | channels:read, plus groups:read for private channels and users:read to resolve display names |
User Token Scopes and Bot Token Scopes are configured separately in the Slack app,
and chat:write appears in both lists. Because the two token types cannot be told
apart from their granted scopes, keep one registration and one connection per
identity, and name them accordingly.
A worked two-registration example, covering every action above:
{
"slack-user": {
"provider": "slack",
"profile": "user",
"owner": "customer",
"context": "self_managed",
"client_type": "confidential",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://langflow.example/api/v1/connections/oauth/slack/callback",
"allowed_tenants": ["T0SLACKTEAM"],
"scopes": [
"search:read",
"channels:history",
"groups:history",
"im:history",
"mpim:history",
"chat:write",
"canvases:write"
]
},
"slack-bot": {
"provider": "slack",
"profile": "bot",
"owner": "customer",
"context": "self_managed",
"client_type": "confidential",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://langflow.example/api/v1/connections/oauth/slack/callback",
"allowed_tenants": ["T0SLACKTEAM"],
"scopes": ["chat:write", "reactions:write", "channels:read", "groups:read", "users:read"]
}
}
To receive Slack trigger events
through the Events API as well, add the app's signing_secret to the bot registration
and the event scopes (channels:history, groups:history, im:history,
mpim:history, app_mentions:read, reactions:read) to its scopes.
Slack desktop redirects may not request bot scopes, so the Desktop PKCE app carries
only the user scopes. On Desktop, paste the bot token (xoxb-) instead, under
Add connection > Paste a token. For headless runtimes,
provide the token directly as LF_CONNECTION__SLACK__<NAME> instead of registering
an OAuth app. That path records no executing identity, so the bundle trusts the
operator to supply the right token type.
Headless connection resolution
- Resolve connections in headless LFX, for hosts that resolve the same connection references without Langflow's database.
Google Workspace action scopes
The wave-1 Google action components each request exactly one scope. Configure a Google
registration whose scopes ceiling contains the ones your flows use:
| Component | Scope |
|---|---|
| Gmail: Send Email | https://www.googleapis.com/auth/gmail.send |
| Drive: List Files (app files) | https://www.googleapis.com/auth/drive.file |
| Drive: Fetch File (app files) | https://www.googleapis.com/auth/drive.file |
| Calendar: List Events | https://www.googleapis.com/auth/calendar.events.readonly |
| Calendar: Create Event | https://www.googleapis.com/auth/calendar.events |
{
"google-work": {
"provider": "google",
"owner": "customer",
"context": "self_managed",
"client_type": "confidential",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://langflow.example/api/v1/connections/oauth/google/callback",
"scopes": [
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/calendar.events.readonly",
"https://www.googleapis.com/auth/calendar.events"
]
}
}
gmail.send, calendar.events, and calendar.events.readonly are sensitive scopes and
require Google's sensitive-scope verification before a published app can request them.
drive.file is non-sensitive. No wave-1 action requests a restricted scope, so no Google
security assessment is required for these components.
Declare scopes as the full https://www.googleapis.com/auth/... URLs shown above. That is
the form Google returns in the token response and therefore the form stored on the
connection and compared against when an action resolves. A short suffix such as
drive.file on its own fails resolution with scope-missing.
The legacy Google Drive Loader accepts an optional connection on drive.file as an
alternative to pasted token JSON. The legacy Gmail Loader does not: reading a mailbox
needs https://www.googleapis.com/auth/gmail.readonly, a restricted scope that 1.13
connections do not use, so it keeps pasted token JSON only.
Tenant and workspace consent policy
A working registration is not the same as an allowed one. Before rollout, validate the application, the executing identity, and the requested scope set against the consent policy of the target tenant or workspace, and record the administrator approval you relied on as a deployment prerequisite. Reviewing this documentation, or completing a test consent in a sandbox tenant, does not establish consent in the production tenant.
- Google: A Workspace administrator controls which applications may access the organization's data and can mark an app Trusted, Limited, or Blocked; a Limited or Blocked app cannot complete consent for the affected services regardless of the Langflow configuration. See Control which apps access Google Workspace data.
- Microsoft: Tenant user-consent settings can restrict consent to verified publishers and low-impact permissions, or disable it entirely, in which case each connection needs administrator approval. See the consent guidance in Delegated permissions.
- Slack: A workspace can require administrator approval before an app is installed or before new scopes are added to it. Install the app in the target workspace and confirm its approval before users connect accounts.
Provider revocation and token rotation
POST /api/v1/connections/CONNECTION_ID/revoke always removes the stored credential
locally; its provider_revocation field then reports what happened upstream:
| Provider | Upstream call on revoke | provider_revocation |
|---|---|---|
| Google (OAuth sign-in) | Google's token revocation endpoint, with the refresh token when one is stored, otherwise the access token. See the web server registration guide. | revoked on success |
| Slack (OAuth sign-in or pasted token) | auth.revoke with the stored token, without requiring an OAuth registration for pasted tokens | revoked only when Slack confirms revocation |
| Microsoft (OAuth sign-in) | None: Entra exposes no per-grant revocation endpoint for this flow | unsupported |
failed means the provider did not confirm revocation, so revoke the token in the
provider's account or admin console as well. This includes rejected token types and
network failures. For Slack Socket Mode app-level tokens (xapp-), use
Basic Information > App-Level Tokens in the Slack app's settings if the request fails.
not_applicable means no credential was stored or the connection used a pasted token
for a provider other than Slack.
The Connections page distinguishes confirmed provider revocation from local credential removal.
For Microsoft's unsupported, remove the app's consent in Entra as
described in Revocation.
revoked reports token revocation, not a complete uninstall. Langflow sends only the
stored access token to Slack's auth.revoke, which revokes that token without
uninstalling the app; if the app uses token rotation, the installation survives and can
still issue new tokens. To end the installation itself, remove the app from the
workspace in Slack.
Refresh behavior also differs by provider:
- Google and Microsoft issue refresh tokens for offline access. Microsoft rotates its refresh token on use, and the broker stores each replacement atomically under the connection lock, so rotation does not require re-consent. An Entra refresh token that goes unused past its lifetime, 90 days by default, expires, after which the connection must be reconnected. See Refresh tokens.
- Slack tokens do not expire unless the app opted into token rotation. With rotation
enabled, each refresh token is single-use and the broker stores the replacement under
the same lock. Without rotation, a provider rejection is the only signal that a token
died, so the component re-resolves the connection once before surfacing
auth-expired.
Whatever the provider outcome, revocation is always final locally: the connection's
status becomes revoked, and every later resolution fails with connection-unresolved
until a new authorization completes.
Move a flow between deployments
A flow stores the connection handle, never the credential. Exporting a flow keeps each
connection field as its portable handle, such as google/work; no token, account
identity, or granted scope set is included.
Importing a flow preserves its nodes and connection fields unchanged. Langflow never
substitutes a different provider, action, or connection on import or at run time. If the
target deployment has no connection with the referenced handle, the run fails with
connection-unresolved. If one exists but the executing identity may not use it, the
run fails with connection-not-authorized. If the deployment's integration policy
blocks the provider or action, it fails with policy-blocked. See
Catalog and model policy.
Rebinding is explicit: either create a connection with the same provider and name in the target deployment, or edit the component's connection field to the handle you provisioned. Nothing rebinds a flow on its own.
Was this page helpful?