---
title: API keys and authentication
slug: /api-keys-and-authentication
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Icon from "@site/src/components/icon";

This page documents Langflow's built-in authentication, including user accounts, Langflow API keys, and the environment variables that control access to your server.
To connect Langflow to an external identity provider or SSO system, see [SSO and external authentication](./external-authentication).

:::warning
Never expose Langflow ports directly to the internet without proper security measures.
Set `LANGFLOW_AUTO_LOGIN=False`, use a non-default `LANGFLOW_SECRET_KEY`, and deploy your Langflow server behind a reverse proxy with authentication enabled.
For more information, see [Start a Langflow server with authentication enabled](#start-a-langflow-server-with-authentication-enabled).
:::

Authentication credentials help prevent unauthorized access to your Langflow server, flows, and services connected through components.

There are three types of credentials that you use in Langflow:

* [Langflow API keys](#langflow-api-keys): For authentication with the Langflow API and authorizing server-side Langflow actions like running flows and uploading files.
* [Component API keys](#component-api-keys): For authentication between Langflow and a service connected through a component, such as a model provider or third-party API.
* [Authentication environment variables](#authentication-environment-variables): These environment variables configure how Langflow handles user authentication and authorization.

## Langflow API keys {#langflow-api-keys}

You can use Langflow API keys to interact with Langflow programmatically.

By default, most Langflow API endpoints, such as `/v1/run/$FLOW_ID`, require authentication with a Langflow API key.

Langflow validates API keys against keys stored in the database, but you can configure Langflow to validate API keys against an environment variable instead.
For more information, see [`LANGFLOW_API_KEY_SOURCE`](#langflow-api-key-source).

Webhook endpoints require API key authentication by default. To disable authentication for webhook endpoints, use the [`LANGFLOW_WEBHOOK_AUTH_ENABLE`](/webhook#require-authentication-for-webhooks) environment variable.
To configure authentication for Langflow MCP servers, see [Use Langflow as an MCP server](/mcp-server).

### Langflow API key permissions

A Langflow API key adopts the privileges of the user who created it.
This means that API keys you create have the same permissions and access that you do, including access to your flows, components, and Langflow database.
A Langflow API key cannot be used to access resources outside of your own Langflow server.

In single-user environments, you are always a superuser, and your Langflow API keys always have superuser privileges.

In multi-user environments, users who aren't superusers cannot use their API keys to access other users' resources.
Superusers can only run their own flows, and cannot run flows owned by other users.
You must [start your Langflow server with authentication enabled](#start-a-langflow-server-with-authentication-enabled) to allow superusers to manage users and create non-superuser accounts.

### Create a Langflow API key

You can generate a Langflow API key in your Langflow **Settings** or with the Langflow CLI.

The CLI option is required if your Langflow server is running in `--backend-only` mode.

<Tabs>
<TabItem value="settings" label="Langflow Settings" default>

1. In the Langflow header, click your profile icon, and then select **Settings**.
2. Click **Langflow API Keys**, and then click **Add New**.
3. Name your key, and then click **Create API Key**.
4. Copy the API key and store it securely.

</TabItem>
<TabItem value="Langflow CLI" label="Langflow CLI">

If you're serving your flow with `--backend-only=true`, you can't create API keys in your Langflow **Settings** because the frontend isn't running.
In this case, you must create API keys with the Langflow CLI.

1. Recommended: [Start your Langflow server with authentication enabled](#start-a-langflow-server-with-authentication-enabled).

    The Langflow team recommends enabling authentication for security reasons to prevent unauthorized creation of API keys and superusers, especially in production environments.
    If authentication isn't enabled (`LANGFLOW_AUTO_LOGIN=True`), all users are effectively superusers, and they can create API keys with the Langflow CLI.

2. Create an API key with [`langflow api-key`](/configuration-cli#langflow-api-key):

    ```shell
    uv run langflow api-key
    ```

    All API keys created with the Langflow CLI have superuser privileges because the command requires superuser authentication, and Langflow API keys adopt the privileges of the user who created them.

</TabItem>
</Tabs>

### Use a Langflow API key

To authenticate Langflow API requests, pass your Langflow API key an `x-api-key` header or query parameter.

<Tabs>
<TabItem value="header" label="HTTP header" default>

```shell
curl -X POST \
  "http://$LANGFLOW_SERVER_ADDRESS/api/v1/run/$FLOW_ID?stream=false" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $LANGFLOW_API_KEY" \
  -d '{"inputs": {"text":""}, "tweaks": {}}'
```

</TabItem>
<TabItem value="parameter" label="Query parameter">

```shell
curl -X POST \
  "http://$LANGFLOW_SERVER_ADDRESS/api/v1/run/$FLOW_ID?x-api-key=$LANGFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"text":""}, "tweaks": {}}'
```

</TabItem>
</Tabs>

For more information about forming Langflow API requests, see [Get started with the Langflow API](/api-reference-api-examples) and [Trigger flows with the Langflow API](/concepts-publish).

### Track API key usage

By default, Langflow tracks API key usage through `total_uses` and `last_used_at` records in your [Langflow database](/memory).

To disable API key tracking, set `LANGFLOW_DISABLE_TRACK_APIKEY_USAGE=True` in your [Langflow environment variables](/environment-variables).
This can help avoid database contention during periods of high concurrency.

### Revoke an API key

To revoke and delete an API key, do the following:

1. In the Langflow header, click your profile icon, and then select **Settings**.
2. Click **Langflow API Keys**.
3. Select the keys you want to delete, and then click <Icon name="Trash2" aria-hidden="true"/> **Delete**.

This action immediately invalidates the key and prevents it from being used again.

## Component API keys {#component-api-keys}

Component API keys authorize access to external services that are called by components in your flows, such as model providers, databases, or third-party APIs.
These aren't Langflow API keys or general application credentials.

In Langflow, you can store component API keys in global variables in your **Settings** or import them from your runtime environment.
For more information, see [Global variables](/configuration-global-variables).

You create and manage component API keys within the service provider's platform.
Langflow only stores the encrypted key value or a secure reference to a key stored elsewhere; it doesn't manage the actual credentials at the source.
This means that deleting a global variable from Langflow doesn't delete or invalidate the actual API key in the service provider's system.
You must delete or rotate component API keys directly using the service provider's interface or API.

For added security, you can set `LANGFLOW_REMOVE_API_KEYS=True` to omit API keys and tokens from flow data in your [Langflow database](/memory).
Additionally, when [exporting flows](/concepts-flows-import), you can choose to omit API keys from the exported flow JSON.

## Authentication environment variables

This section describes the available authentication configuration variables.

You can use the [`.env.example`](https://github.com/langflow-ai/langflow/blob/main/.env.example) file in the Langflow repository as a template for your own `.env` file.

For JWT token signing configuration, including algorithm selection and key management, see [Configure JWT token signing](#configure-jwt-token-signing).

### LANGFLOW_AUTO_LOGIN {#langflow-auto-login}

This variable controls whether the visual editor uses automatic login or requires users to sign in.

* If `LANGFLOW_AUTO_LOGIN=False`, automatic login is disabled. Users must sign in to the visual editor, authenticate as a superuser to run certain Langflow CLI commands, and use a Langflow API key for Langflow API requests.
You must explicitly set [`LANGFLOW_SUPERUSER_PASSWORD`](#langflow-superuser) before startup. Set [`LANGFLOW_SUPERUSER`](#langflow-superuser) only if you want to override the default superuser username (`langflow`).

* If `LANGFLOW_AUTO_LOGIN=True`, the visual editor automatically signs in all users as the configured superuser, and Langflow uses that username with a configured or generated bootstrap password.
All users share the same visual editor environment without password protection, and they can run Langflow CLI commands as superusers.
API requests still require a Langflow API key unless you also set [`LANGFLOW_SKIP_AUTH_AUTO_LOGIN`](#langflow-skip-auth-auto-login) to `true`.

The Langflow application default is `True`.
Official Langflow Docker images set `false`. For more information, see [Docker image defaults](/deployment-docker#docker-image-security-defaults).

#### LANGFLOW_SKIP_AUTH_AUTO_LOGIN {#langflow-skip-auth-auto-login}

When `LANGFLOW_AUTO_LOGIN=true`, set `LANGFLOW_SKIP_AUTH_AUTO_LOGIN=true` to also skip API key authentication for API requests.
The default is `false`, so API keys are still required even when auto-login is enabled.
This variable will be removed in a future release.

### LANGFLOW_ENABLE_SUPERUSER_CLI {#langflow-enable-superuser-cli}

Controls the availability of the `langflow superuser` command in the Langflow CLI.
The default is `true`, but `false` is recommended to prevent unrestricted superuser creation.
For more information, see [`langflow superuser`](/configuration-cli#langflow-superuser).

### LANGFLOW_SUPERUSER and LANGFLOW_SUPERUSER_PASSWORD {#langflow-superuser}

These variables specify the username and password for the Langflow server's superuser.

```text
LANGFLOW_SUPERUSER=administrator
LANGFLOW_SUPERUSER_PASSWORD=securepassword
```

`LANGFLOW_SUPERUSER_PASSWORD` is required if `LANGFLOW_AUTO_LOGIN=False`. `LANGFLOW_SUPERUSER` is optional and defaults to `langflow`.
`LANGFLOW_SUPERUSER_PASSWORD` can't use the legacy default value `langflow`; startup fails closed instead.
When `LANGFLOW_AUTO_LOGIN=True`, `LANGFLOW_SUPERUSER` selects the auto-login account username and `LANGFLOW_SUPERUSER_PASSWORD` is optional. If the password isn't set, Langflow generates an unknown bootstrap password for the auto-login account.

When you [start a Langflow server with authentication enabled](#start-a-langflow-server-with-authentication-enabled), if the required password is _not_ set, then startup fails instead of creating a default password.
These defaults don't apply when using the Langflow CLI command [`langflow superuser`](/configuration-cli#langflow-superuser).

### LANGFLOW_SECRET_KEY {#langflow-secret-key}

This environment variable stores a secret key used for encrypting sensitive data like API keys and for JWT signing when using the HS256 algorithm.
Langflow uses the [Fernet](https://pypi.org/project/cryptography/) library for secret key encryption.
For JWT-specific configuration, see [Configure JWT token signing](#configure-jwt-token-signing).

If no secret key is provided, Langflow automatically generates one.

However, you should generate and explicitly set your own key in production environments.
This is particularly important for multi-instance deployments like Kubernetes to ensure consistent encryption across instances.

To generate a secret encryption key for `LANGFLOW_SECRET_KEY`, do the following:

1. Run the command to generate and copy a secret to the clipboard.

    <Tabs>
    <TabItem value="unix" label="macOS or Linux">

    * **macOS**: Generate a secret key and copy it to the clipboard:

        ```bash
        python3 -c "from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')" | pbcopy
        ```

    * **Linux**: Generate a secret key and copy it to the clipboard:

        ```bash
        python3 -c "from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')" | xclip -selection clipboard
        ```

    * **Unix**: Generate a secret key and print it to the terminal to manually copy it:

        ```bash
        python3 -c "from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')"
        ```

    </TabItem>
    <TabItem value="windows" label="Windows">

    * Generate a secret key and copy it to the clipboard:

        ```bash
        python -c "from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')"
        ```

    * Generate a secret key and print it to the terminal to manually copy it:

        ```bash

        # Or just print
        python -c "from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')"
        ```

    </TabItem>
    </Tabs>

2. Paste the value into your `.env` file:

    ```text
    LANGFLOW_SECRET_KEY=dBuu...2kM2_fb
    ```

    If you're running Langflow on Docker, reference the `LANGFLOW_SECRET_KEY` from your `.env` file in the `docker-compose.yml` file like this:

        ```yaml
        environment:
          - LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
        ```

#### Rotate the secret key {#rotating-the-secret-key}

Rotate `LANGFLOW_SECRET_KEY` if the key might have been compromised and as part of your routine credential management practices.
Langflow provides a migration script that re-encrypts stored credentials and other sensitive data with a new key so you can rotate without losing access.

For more information, see [Secret Key Rotation](https://github.com/langflow-ai/langflow/blob/main/SECURITY.md#secret-key-rotation) in the Langflow Security Policy.

### LANGFLOW_NEW_USER_IS_ACTIVE {#langflow-new-user-is-active}

When `LANGFLOW_NEW_USER_IS_ACTIVE=False` (default), accounts created by superusers are inactive by default and must be explicitly activated before users can sign in to the visual editor.
The superuser can also deactivate a user's account as needed.

When `LANGFLOW_NEW_USER_IS_ACTIVE=True`, accounts created by superusers are automatically activated.

```text
LANGFLOW_NEW_USER_IS_ACTIVE=False
```

Only superusers can manage user accounts for a Langflow server, but user management only matters if your server has authentication enabled.
For more information, see [Start a Langflow server with authentication enabled](#start-a-langflow-server-with-authentication-enabled).

### LANGFLOW_ENABLE_SIGNUP {#langflow-enable-signup}

This variable controls whether public self-registration is allowed at the `POST /api/v1/users/` endpoint.

| Value | Description |
|-------|-------------|
| `True` (default) | Anyone can create a new Langflow account by calling the registration endpoint directly. |
| `False` | Public registration is disabled. Only superusers can create new accounts through the admin interface. |

Self-registration is always disabled when `LANGFLOW_AUTO_LOGIN=True`, because single-user mode has no multi-account concept.
Superusers can create accounts regardless of this setting.

### LANGFLOW_API_KEY_SOURCE {#langflow-api-key-source}

This variable controls how Langflow validates API keys.

| Value | Description |
|-------|-------------|
| `db` (default) | Validates API keys against [Langflow API keys](#langflow-api-keys) stored in the database. This is the standard behavior where users create and manage API keys through the Langflow UI or CLI. |
| `env` | Validates API keys against the `LANGFLOW_API_KEY` environment variable. Useful for Kubernetes deployments, CI/CD pipelines, or any environment where you want to inject a pre-defined API key without database configuration. |

By default, Langflow validates the `x-api-key` header against the Langflow database with `LANGFLOW_API_KEY_SOURCE=db`.
When using database-based validation, you can create multiple keys with per-user permissions, track usage, and manage keys through the Langflow UI or CLI.

When `LANGFLOW_API_KEY_SOURCE=env`, Langflow validates the `x-api-key` header against the value of the `LANGFLOW_API_KEY` environment variable.
This means Langflow runs securely in stateless environments, such as with LFX or Kubernetes secrets.

When `LANGFLOW_API_KEY_SOURCE=env`, only a single API key can be used for the deployment. All authenticated requests use the same API key, and successful authentication grants superuser privileges.
This mode is designed for single-tenant deployments or automated systems, not multi-user environments where different users need different access levels. To rotate your keys, update the environment variable and restart the Langflow server.

To enable environment-based API key validation:

1. In the Langflow `.env` file, set the API key source to `env`:

    ```text
    LANGFLOW_API_KEY_SOURCE=env
    ```

2. In the Langflow `.env` file, set the API key value:

    ```text
    LANGFLOW_API_KEY=your-secure-api-key
    ```

3. Use the API key in your requests:

    ```shell
    curl -X POST \
      "http://LANGFLOW_SERVER_ADDRESS/api/v1/run/FLOW_ID?stream=false" \
      -H "Content-Type: application/json" \
      -H "x-api-key: LANGFLOW_API_KEY" \
      -d '{"inputs": {"text":""}, "tweaks": {}}'
    ```

    Replace `LANGFLOW_SERVER_ADDRESS`, `FLOW_ID`, and `LANGFLOW_API_KEY` with the values from your deployment.

<details>
<summary>Kubernetes deployment example</summary>

To configure an environment-based API key in a Kubernetes Secret, do the following:

1. Create a Kubernetes Secret with your API key:

    ```yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: langflow-api-key
    type: Opaque
    stringData:
      api-key: "YOUR_API_KEY"
    ```

    Replace `YOUR_API_KEY` with the `LANGFLOW_API_KEY` value from the Langflow `.env` file.

2. Reference the `langflow-api-key` Secret in your Kubernetes deployment:

    ```yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: langflow
    spec:
      template:
        spec:
          containers:
          - name: langflow
            image: langflowai/langflow:latest
            env:
            - name: LANGFLOW_API_KEY_SOURCE
              value: "env"
            - name: LANGFLOW_API_KEY
              valueFrom:
                secretKeyRef:
                  name: langflow-api-key
                  key: api-key
    ```

</details>

<details>
<summary>Docker Compose example</summary>

To configure an environment-based API key in Docker Compose, do the following:

1. Set the API key in your Langflow `.env` file.

    ```text
    LANGFLOW_API_KEY=your-secure-api-key
    ```

    Replace `YOUR_API_KEY` with your actual Langflow API key value.

2. Create or update your `docker-compose.yml` file to set `LANGFLOW_API_KEY_SOURCE=env` and reference the `LANGFLOW_API_KEY`.

    ```yaml
    services:
      langflow:
        image: langflowai/langflow:latest
        environment:
          - LANGFLOW_API_KEY_SOURCE=env
          - LANGFLOW_API_KEY=${LANGFLOW_API_KEY}
        ports:
          - "7860:7860"
    ```

</details>

### LANGFLOW_CORS_* {#cors-configuration-for-authentication}

Cross-Origin Resource Sharing (CORS) configuration controls how authentication credentials are handled when your Langflow frontend and backend are served from different origins.
The following `LANGFLOW_CORS_*` environment variables are available:

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_CORS_ALLOW_CREDENTIALS` | Boolean | `True` | Whether to allow credentials, such as cookies and authorization headers, in CORS requests. |
| `LANGFLOW_CORS_ALLOW_HEADERS` | List[String] or String | `*` | The allowed headers for CORS requests. Provide a comma-separated list of headers or use `*` to allow all headers. |
| `LANGFLOW_CORS_ALLOW_METHODS` | List[String] or String | `*` | The allowed HTTP methods for CORS requests. Provide a comma-separated list of methods or use `*` to allow all methods. |
| `LANGFLOW_CORS_ORIGINS` | String | `*` | The allowed CORS origins. Provide a comma-separated list of origins or use `*` for all origins. |

The default configuration enables CORS credentials and uses wildcards (`*`) to allow all origins, headers, and methods:

```text
LANGFLOW_CORS_ORIGINS=*
LANGFLOW_CORS_ALLOW_CREDENTIALS=True
LANGFLOW_CORS_ALLOW_HEADERS=*
LANGFLOW_CORS_ALLOW_METHODS=*
```

:::danger
Langflow's default CORS settings can be a security risk in production environments because any website can make requests to your Langflow API, and any website can include credentials in cross-origin requests, including authentication cookies and authorization headers.

In production deployments, specify exact origins in `LANGFLOW_CORS_ORIGINS`.
You can also specify allowed headers and methods, if needed.
For example:

```text
LANGFLOW_CORS_ORIGINS=["https://yourdomain.com","https://app.yourdomain.com"]
LANGFLOW_CORS_ALLOW_CREDENTIALS=True
LANGFLOW_CORS_ALLOW_HEADERS=["Content-Type","Authorization"]
LANGFLOW_CORS_ALLOW_METHODS=["GET","POST","PUT"]
```
:::

###  LANGFLOW_ACCESS_* {#session-cookie-hardening}

For a shared or public deployment served over HTTPS, harden the access-token cookie. These default to permissive values for local HTTP development and for the current frontend, which reads the access token in JavaScript.

The refresh-token cookie is `HttpOnly` + `Secure` + `SameSite` by default.

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_ACCESS_SECURE` | Boolean | `False` | When `true`, the `access_token_lf` cookie is sent only over HTTPS. Recommended `true` for any HTTPS deployment. |
| `LANGFLOW_ACCESS_HTTPONLY` | Boolean | `False` | When `true`, the `access_token_lf` cookie is not readable by JavaScript. The default is `false` because the bundled frontend currently reads this cookie in JavaScript. |
| `LANGFLOW_ACCESS_SAME_SITE` | String | `lax` | The `SameSite` attribute of the access-token cookie (`lax`, `strict`, or `none`). |

### LANGFLOW_RATE_LIMIT_* {#login-rate-limiting}

The following environment variables configure IP-based rate limiting to protect against brute-force attacks on the `/login` endpoint and abuse of public flow endpoints.
When the limit is exceeded, Langflow returns HTTP 429 with a `Retry-After: 60` header.

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_RATE_LIMIT_ENABLED` | Boolean | `True` | Enable rate limiting on the `/login` and `/api/v2/workflows/public` endpoints. Set to False to disable those limits (not recommended in production). |
| `LANGFLOW_RATE_LIMIT_PER_MINUTE` | Integer | `5` | Maximum number of login attempts allowed per minute from a single IP address. |
| `LANGFLOW_RATE_LIMIT_STORAGE_URI` | String | `memory://` | Storage backend for rate limit counters. Use `memory://` for single-server deployments or `redis://host:port` for multi-server deployments where the limit should be shared across instances. |
| `LANGFLOW_RATE_LIMIT_TRUST_PROXY` | Boolean | `False` | When `true`, Langflow reads the client IP from the rightmost `X-Forwarded-For` header entry instead of the direct connection IP. Enable only when Langflow is behind a trusted reverse proxy or load balancer. Do not enable if users can reach Langflow directly, as this allows header spoofing. |
| `LANGFLOW_PUBLIC_FLOW_RATE_LIMIT_PER_MINUTE` | Integer | `20` | Maximum number of unauthenticated public-flow runs allowed per minute from a single IP address. Public flows run as the flow owner and consume resources, so anonymous callers are rate-limited separately from the `/login` endpoint. |

### LANGFLOW_SSRF_* and LANGFLOW_CONNECTOR_SSRF_* {#ssrf-protection}

The following environment variables configure Server-Side Request Forgery (SSRF) protection for the [**API Request** component](/api-request) and for connector components that take a tenant-controlled host or URL.
SSRF protection prevents requests to internal or private network resources, such as private IP ranges, loopback addresses, and cloud metadata endpoints.

In a shared server where users you do not fully trust can build flows, set `LANGFLOW_CONNECTOR_SSRF_VALIDATION_ENABLED=true`, `LANGFLOW_SSRF_PROTECTION_ENABLED=true`, and `LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false`, and then allowlist your own internal hosts with `LANGFLOW_SSRF_ALLOWED_HOSTS`.

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_SSRF_PROTECTION_ENABLED` | Boolean | `True` | Enable SSRF protection for the **API Request** component. When enabled, the component blocks requests to private IP addresses. When disabled, requests are not blocked. |
| `LANGFLOW_SSRF_ALLOWED_HOSTS` | List[String] | Not set | A comma-separated list of allowed hosts, IP addresses, or CIDR ranges that can bypass SSRF protection checks. For example: `192.168.1.0/24,10.0.0.5,*.internal.company.local`.|
| `LANGFLOW_CONNECTOR_SSRF_VALIDATION_ENABLED` | Boolean | `True` | Apply SSRF host validation to connector components that take a tenant-controlled host or URL. Uses `LANGFLOW_SSRF_PROTECTION_ENABLED` and `LANGFLOW_SSRF_ALLOWED_HOSTS` for the host policy. Set to `false`, or allowlist specific hosts, only when a trusted single-tenant deployment intentionally connects to private-network services. |
| `LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK` | Boolean | `True` | When connector SSRF validation is enabled, allow literal loopback hosts (`localhost`, `127.0.0.0/8`, `::1`) so local Ollama, LM Studio, and similar services keep working. Multi-tenant deployments where a tenant must not reach the server's loopback should set this to `false`. |

### Component hardening for untrusted users {#multi-tenant-component-hardening}

Use these variables when users who can build or run flows on your server should not get host-level code execution, arbitrary file reads, or  MCP mounts.

For more information, see [Docker image defaults](/deployment-docker#docker-image-security-defaults).

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS` | Boolean | `False` | When `true`, blocks execution of any flow containing a built-in arbitrary-code-execution component, including the [**Python Interpreter**](/python-interpreter), Python REPL/Code tools, [**Smart Transform**](/smart-transform), [**CSV Agent**](/bundles-langchain#csv-agent), and code-running agents such as [**CodeAct**](/bundles-codeagents#codeact-agent-smolagents), [**CUGA**](/bundles-cuga), and [**OpenDsStar**](/bundles-codeagents#opendstar-agent). |
| `LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS` | Boolean | `False` | When `true`, built-in file-reading components, including the [**File**](/read-file), [**Directory**](/legacy-core-components#legacy-data-components), [**JSON/CSV-to-Data**](/legacy-core-components#legacy-data-components), and the [**CSV Agent**](/bundles-langchain#csv-agent), [**JSON Agent**](/bundles-langchain#legacy-langchain-components), and [**OpenAPI Agent**](/bundles-langchain#openapi-agent) can only read and write paths inside the [`LANGFLOW_CONFIG_DIR`](/memory) storage directory. This also blocks `sqlite` and `duckdb` dialects in the [**SQL Database**](/sql-database) components and local-filesystem Git clones. |
| `LANGFLOW_MCP_SERVER_DOCKER_HARDENING` | Boolean | `False` | When `true`, applies a strict Docker-argument policy to MCP stdio servers that use the `docker` transport. Rejects host filesystem or device mounts, `host/another-container` namespaces, non-default networks, privilege flags, and sandbox-disabling `--security-opt` values. Forms such as `--network none` / `bridge` and `--security-opt no-new-privileges` remain allowed. |

Enable these flags when untrusted users can build flows on this server.

The `LANGFLOW_ALLOW_CUSTOM_COMPONENTS` and `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS` flags are _complementary_.
`LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false` blocks user-authored component code, but built-in code-execution components still pass that check because their class code is trusted. Set `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true` to block those built-in components as well.

To enable these flags, set the following:

* `LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false`: blocks user-authored component code. See [Block custom components](/deployment-block-custom-components).
* `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true`: blocks built-in code-execution components.
* `LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true`: confines built-in file access to the upload sandbox.
* `LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true`: tightens Docker MCP server arguments.

Pair these settings with the [SSRF settings](#ssrf-protection) to reduce common escape hatches.

These settings **do not** provide full user isolation. For more information, see [Security](/security).

:::tip
Do not enable a shared tracer when users are untrusted. Instead, use [built-in local tracing](/traces).
External tracing integrations such as Langfuse and Arize are _process-wide_, not per user, so on a shared server, every user's flow inputs and outputs will go to the same tracing project.
:::

### LANGFLOW_WEBHOOK_AUTH_ENABLE {#langflow-webhook-auth-enable}

This variable controls whether API key authentication is required for webhook endpoints.

| Variable | Format | Default | Description |
|----------|--------|---------|-------------|
| `LANGFLOW_WEBHOOK_AUTH_ENABLE` | Boolean | `True` | When `True`, webhook endpoints require API key authentication and validate that the authenticated user owns the flow being executed. When `False`, no Langflow API key is required and all requests to the webhook endpoint are treated as being sent by the flow owner. |

By default, webhooks require API key authentication with `LANGFLOW_WEBHOOK_AUTH_ENABLE=True`.

To allow webhooks to run without authentication (not recommended; use only in trusted environments), in your Langflow `.env` file, set `LANGFLOW_WEBHOOK_AUTH_ENABLE=False`.

When webhook authentication is enabled, you must provide a Langflow API key with each webhook request as an HTTP header or query parameter. For more information, see [Require authentication for webhooks](/webhook#require-authentication-for-webhooks).

## Configure JWT token signing {#configure-jwt-token-signing}

Langflow issues short-lived JSON Web Tokens (JWTs) when a user logs in. The default HS256 algorithm works for most deployments. Switch to RS256 or RS512 for production deployments that require asymmetric keys or need to share the public key with other services.

<details closed>
<summary>About the JWT structure and contents</summary>

When a user logs in at the `/api/v1/login` endpoint, Langflow validates the credentials and creates a JWT containing the user's identity and expiration time. This token is then used for subsequent API requests instead of sending credentials with each request.

A JWT consists of three parts separated by dots (`.`):

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```

* The header contains the token type and signing algorithm.
* The payload contains _claims_ — token data for user information and expiration time.
* The signature ensures the token hasn't been tampered with.

Each part of the JWT is Base64URL-encoded. You can paste this example JWT to decode the actual JSON data at [jwt.io](https://jwt.io/).

</details>

The following environment variables control JWT signing. `LANGFLOW_SECRET_KEY` is also used for data encryption and is documented separately in [`LANGFLOW_SECRET_KEY`](#langflow-secret-key).

| Variable | Description | Default |
|---|---|---|
| `LANGFLOW_ALGORITHM` | JWT signing algorithm: `HS256`, `RS256`, or `RS512` | `HS256` |
| `LANGFLOW_PRIVATE_KEY` | RSA private key for RS256/RS512 signing | Auto-generated |
| `LANGFLOW_PUBLIC_KEY` | RSA public key for RS256/RS512 verification | Derived from private key |
| `LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS` | Access token expiration time | `3600` (1 hour) |
| `LANGFLOW_REFRESH_TOKEN_EXPIRE_SECONDS` | Refresh token expiration time | `604800` (7 days) |

### HS256 (default)

HS256 is the default JWT algorithm, suitable for single-server deployments.
Langflow automatically generates and persists a secret key via `LANGFLOW_SECRET_KEY`.
No configuration is necessary beyond what is already covered in the [`LANGFLOW_SECRET_KEY`](#langflow-secret-key) section above.

To explicitly set the algorithm in your `.env`:

```bash
LANGFLOW_ALGORITHM=HS256
LANGFLOW_SECRET_KEY="your-custom-secret-key"
```

### RS256

RS256 uses an RSA private/public key pair. The private key signs tokens; the public key verifies them. Use RS256 for production deployments or multi-instance setups where you want to share the public key with other services.

To automatically generate a key pair, set the algorithm and Langflow creates and persists the keys in [`LANGFLOW_CONFIG_DIR`](/logging) on startup:

```bash
LANGFLOW_ALGORITHM=RS256
```

To supply your own private key (public key is derived automatically):

```bash
LANGFLOW_ALGORITHM=RS256
LANGFLOW_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEF...
-----END PRIVATE KEY-----"
```

To supply a full key pair:

```bash
LANGFLOW_ALGORITHM=RS256
LANGFLOW_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEF...
-----END PRIVATE KEY-----"
LANGFLOW_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOC...
-----END PUBLIC KEY-----"
```

To generate an RSA key pair manually:

1. Generate a 2048-bit private key:
   ```bash
   openssl genrsa -out private_key.pem 2048
   ```

2. Extract the public key:
   ```bash
   openssl rsa -in private_key.pem -pubout -out public_key.pem
   ```

### RS512

RS512 uses the same RSA key format as RS256 but with SHA-512 hashing for greater cryptographic strength. Key generation and configuration follow the same pattern as RS256 — substitute `RS512` for `RS256` in all the examples above.

### Configure Docker and Kubernetes deployments

**Docker with HS256** — for single-server or development deployments:

```yaml
services:
  langflow:
    image: langflowai/langflow:latest
    environment:
      - LANGFLOW_ALGORITHM=HS256
      - LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
    volumes:
      - langflow_data:/app/langflow
volumes:
  langflow_data:
```

**Docker with RS256** — auto-generated keys (persisted in the volume):

```yaml
services:
  langflow:
    image: langflowai/langflow:latest
    environment:
      - LANGFLOW_ALGORITHM=RS256
    volumes:
      - langflow_data:/app/langflow
volumes:
  langflow_data:
```

**Docker with RS256** — mount an existing key pair:

```yaml
services:
  langflow:
    image: langflowai/langflow:latest
    environment:
      - LANGFLOW_ALGORITHM=RS256
    volumes:
      - ./keys/private_key.pem:/app/langflow/private_key.pem:ro
      - ./keys/public_key.pem:/app/langflow/public_key.pem:ro
      - langflow_data:/app/langflow
volumes:
  langflow_data:
```

**Kubernetes with RS256** — store keys as Secrets:

```yaml
# jwt-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: langflow-jwt-keys
type: Opaque
stringData:
  algorithm: "RS256"
  private-key: |
    -----BEGIN PRIVATE KEY-----
    MIIEvgIBADANBgkqhkiG9w0BAQEF...
    -----END PRIVATE KEY-----
  public-key: |
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOC...
    -----END PUBLIC KEY-----
---
# langflow-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: langflow
spec:
  template:
    spec:
      containers:
        - name: langflow
          image: langflowai/langflow:latest
          env:
            - name: LANGFLOW_ALGORITHM
              valueFrom:
                secretKeyRef:
                  name: langflow-jwt-keys
                  key: algorithm
            - name: LANGFLOW_PRIVATE_KEY
              valueFrom:
                secretKeyRef:
                  name: langflow-jwt-keys
                  key: private-key
            - name: LANGFLOW_PUBLIC_KEY
              valueFrom:
                secretKeyRef:
                  name: langflow-jwt-keys
                  key: public-key
```

### Configure token expiration

Access tokens authenticate API requests and typically expire within 15 minutes to 1 hour.
Refresh tokens obtain new access tokens without requiring the user to log in again and typically expire within 7 to 30 days.
When an access token expires, the client can use the refresh token to get a new one from `/api/v1/refresh`.

```bash
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS=3600    # 1 hour
LANGFLOW_REFRESH_TOKEN_EXPIRE_SECONDS=604800 # 7 days
```

## Start a Langflow server with authentication enabled {#start-a-langflow-server-with-authentication-enabled}

This section shows you how to use the [authentication environment variables](/api-keys-and-authentication#authentication-environment-variables) to deploy a Langflow server with authentication enabled.
This involves disabling automatic login, setting superuser credentials, generating a secret encryption key, and enabling user management.

This configuration is recommended for any deployment where Langflow is exposed to a shared or public network, or where multiple users access the same Langflow server.

:::tip Docker images
Official Langflow Docker images already set `LANGFLOW_AUTO_LOGIN=false`.
You still must set `LANGFLOW_SUPERUSER_PASSWORD` (and optionally `LANGFLOW_SUPERUSER`) before the container can start.
For more information, see [Docker image defaults](/deployment-docker#docker-image-security-defaults).
:::

With authentication enabled, all users must sign in to the visual editor with valid credentials, and API requests require authentication with a Langflow API key.
Additionally, you must sign in as a superuser to manage users and [create a Langflow API key](#create-a-langflow-api-key) with superuser privileges.

### Start the Langflow server

1. Create a `.env` file with the following variables:

    ```text
    LANGFLOW_AUTO_LOGIN=False
    LANGFLOW_SUPERUSER=
    LANGFLOW_SUPERUSER_PASSWORD=
    LANGFLOW_SECRET_KEY=
    LANGFLOW_NEW_USER_IS_ACTIVE=False
    LANGFLOW_ENABLE_SUPERUSER_CLI=False
    ```

    Your `.env` file can have other environment variables.
    This example focuses on authentication variables.

2. Set `LANGFLOW_SUPERUSER_PASSWORD` to your desired superuser password. Optionally set `LANGFLOW_SUPERUSER` to override the default `langflow` username.

    For a one-time test, you can use basic credentials like `administrator` and `password`.
    Strong, securely-stored credentials are recommended in genuine development and production environments.

3. Recommended: Generate and set a `LANGFLOW_SECRET_KEY` for encrypting sensitive data.

    If you don't set a secret key, Langflow generates one automatically, but this isn't recommended for production environments.

    For instructions on generating and setting a secret key, see [`LANGFLOW_SECRET_KEY`](#langflow-secret-key).

4. Save your `.env` file with the populated variables. For example:

    ```text
    LANGFLOW_AUTO_LOGIN=False
    LANGFLOW_SUPERUSER=administrator
    LANGFLOW_SUPERUSER_PASSWORD=securepassword
    LANGFLOW_SECRET_KEY=dBuu...2kM2_fb
    LANGFLOW_NEW_USER_IS_ACTIVE=False
    LANGFLOW_ENABLE_SUPERUSER_CLI=False
    ```

5. Start Langflow with the configuration from your `.env` file:

    ```text
    uv run langflow run --env-file .env
    ```

    Starting Langflow with this `.env` file creates or uses the configured superuser.
    If `LANGFLOW_SUPERUSER_PASSWORD` isn't set, startup fails instead of creating a default password.

6. Verify the server is running. The default location is `http://localhost:7860`.

Next, you can add users to your Langflow server to collaborate with others on flows.

### Manage users as an administrator

1. To complete your first-time login as a superuser, go to `http://localhost:7860/login`.

    If you aren't using the default location, replace `localhost:7860` with your server's address.

2. Log in with the superuser credentials from your `.env`: the `LANGFLOW_SUPERUSER` username, or `langflow` if unset, and the `LANGFLOW_SUPERUSER_PASSWORD` password.

3. To manage users on your server, navigate to `/admin`, such as `http://localhost:7860/admin`, click your profile icon, and then click **Admin Page**.

    As a superuser, you can add users, set permissions, reset passwords, and delete accounts.

4. To add a user, click **New User**, and then complete the user account form:

    1. Enter a username and password.
    2. To activate the account immediately, select **Active**. Inactive users cannot sign in or access flows they created before becoming inactive.
    3. Deselect **Superuser** if you don't want the user to have full administrative privileges.
    4. Click **Save**. The new user appears in the **Admin Page**.

5. Send the credentials to the user so they can sign in to Langflow. The superuser sets the initial password when creating the account, so users must receive their login credentials from the superuser.

6. To test the new user's access, sign out of Langflow, and then sign in with the new user's credentials.

    Try to access the `/admin` page.
    You are redirected to the `/flows` page if the new user isn't a superuser.

## See also

* [Langflow environment variables](/environment-variables)
* [Langflow Security Policy](https://github.com/langflow-ai/langflow/blob/main/SECURITY.md) — reporting vulnerabilities, security configuration, and [secret key rotation](https://github.com/langflow-ai/langflow/blob/main/SECURITY.md#secret-key-rotation)
