Skip to content

Commit 94859df

Browse files
fix(security): consolidate release-1.10.3 hardening backports (#14071)
* fix(security): harden component code module access * fix(security): protect Docling Serve requests * fix(auth): verify current password on password changes * fix(security): restrict MCP stdio package sources * fix(security): confine AssemblyAI audio file access * [autofix.ci] apply automated fixes * fix(kb): enforce folder connector security settings * fix(security): block native FFI imports in generated code * fix: track module assignment aliases in code scanner * fix(voice): enforce flow authorization on websocket * fix(security): block MCP Docker host access * fix(security): validate embedded MCP stdio configs * fix: require executable-only MCP commands * test: stub optional AssemblyAI dependency * test: use allowed MCP commands in timeout tests * fix(initial_setup): preserve variable bindings when loading flows from disk (#14053) fix(initial_setup): preserve variable bindings on flow load * fix(security): backport narrow tenant hardening Backport the targeted security fixes from release-1.11.0, including public-flow secret scrubbing, tenant-scoped MCP caching, trusted custom-component builds, code-execution gating, environment fallback protection, and query/path/header hardening. Source commits: 36c6d11 1f39a4b 331b637 2e7bfba 329f15f 359344b 3e3b70b 2f44a77 068c983 de0e232 8b473e4 a91b967 294effc b0a6350 9f15a60 79fca45 * fix(security): complete MCP tenant-isolation backport * docs(security): describe release hardening controls * fix(security): backport tenant isolation hardening * fix(security): harden published image defaults * fix(security): harden connector URLs against SSRF * fix(security): address alias review findings * fix(security): backport remaining hardening gaps * fix(security): pin WebSearch result and RSS DNS * fix(kb): enforce per-user path containment * fix(security): complete release-1.10.3 hardening backport * fix(security): harden AssemblyAI file submission * fix: bind loop and comprehension aliases * [autofix.ci] apply automated fixes * fix(lfx): register code execution aliases --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 00eb584 commit 94859df

164 files changed

Lines changed: 5168 additions & 480 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/typescript_test.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,11 +388,20 @@ jobs:
388388
command: |
389389
cd src/frontend
390390
echo 'Running tests with pattern: ${{ needs.determine-test-suite.outputs.test_grep }}'
391-
npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --list --retries=3
391+
TEST_LIST=$(npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --list --retries=3)
392+
echo "$TEST_LIST"
393+
394+
WORKERS=2
395+
if printf '%s\n' "$TEST_LIST" | grep -Eq 'user-flow-state-cleanup\.spec\.ts|user-progress-track\.spec\.ts'; then
396+
# These user/session tests share one SQLite-backed server and mutate
397+
# authentication state, so running them concurrently corrupts the
398+
# session and can leave both pages back on the sign-in screen.
399+
WORKERS=1
400+
fi
392401
# echo command before running
393-
echo "npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2 --retries=3"
402+
echo "npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers $WORKERS --retries=3"
394403
395-
npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2 --retries=3
404+
npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers "$WORKERS" --retries=3
396405
397406
- name: Upload Test Results
398407
if: always()

.secrets.baseline

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -317,40 +317,16 @@
317317
"is_verified": false,
318318
"line_number": 645,
319319
"is_secret": true
320-
},
321-
{
322-
"type": "Hex High Entropy String",
323-
"filename": "src/backend/base/langflow/agentic/flows/SystemMessageGen.json",
324-
"hashed_secret": "59416d210387d77a76c3c93f0fdcb89c08e42e6f",
325-
"is_verified": false,
326-
"line_number": 2324,
327-
"is_secret": true
328320
}
329321
],
330322
"src/backend/base/langflow/agentic/flows/TemplateAssistant.json": [
331-
{
332-
"type": "Hex High Entropy String",
333-
"filename": "src/backend/base/langflow/agentic/flows/TemplateAssistant.json",
334-
"hashed_secret": "d8b16a7764b2b6b2da9a15df8e4cca6b3bb16593",
335-
"is_verified": false,
336-
"line_number": 1134,
337-
"is_secret": true
338-
},
339323
{
340324
"type": "Hex High Entropy String",
341325
"filename": "src/backend/base/langflow/agentic/flows/TemplateAssistant.json",
342326
"hashed_secret": "05c44419f0be64056556f8c81c87e5d3bc7cd1f5",
343327
"is_verified": false,
344328
"line_number": 1927,
345329
"is_secret": true
346-
},
347-
{
348-
"type": "Hex High Entropy String",
349-
"filename": "src/backend/base/langflow/agentic/flows/TemplateAssistant.json",
350-
"hashed_secret": "a7db96ddbe558c8ec7514abb20420e4fbdc50da5",
351-
"is_verified": false,
352-
"line_number": 2082,
353-
"is_secret": true
354330
}
355331
],
356332
"src/backend/base/langflow/agentic/flows/TranslationFlow.json": [
@@ -1529,7 +1505,7 @@
15291505
"filename": "src/backend/tests/unit/api/v1/test_projects.py",
15301506
"hashed_secret": "8bb6118f8fd6935ad0876a3be34a717d32708ffd",
15311507
"is_verified": false,
1532-
"line_number": 1829,
1508+
"line_number": 1856,
15331509
"is_secret": true
15341510
}
15351511
],
@@ -1887,7 +1863,7 @@
18871863
"filename": "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py",
18881864
"hashed_secret": "72cb70dbbafe97e5ea13ad88acd65d08389439b0",
18891865
"is_verified": false,
1890-
"line_number": 603,
1866+
"line_number": 625,
18911867
"is_secret": true
18921868
}
18931869
],
@@ -7328,5 +7304,5 @@
73287304
}
73297305
]
73307306
},
7331-
"generated_at": "2026-07-13T18:14:58Z"
7307+
"generated_at": "2026-07-14T18:11:48Z"
73327308
}

docker/build_and_push.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,5 +131,12 @@ WORKDIR /app
131131
ENV LANGFLOW_HOST=0.0.0.0
132132
ENV LANGFLOW_PORT=7860
133133
ENV LANGFLOW_AUTO_LOGIN=false
134+
ENV LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false
135+
ENV LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true
136+
ENV LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true
137+
ENV LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false
138+
ENV LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES=mcp-proxy,lfx
139+
ENV LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true
140+
ENV LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true
134141

135142
CMD ["langflow", "run"]

docker/build_and_push_backend.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,12 @@ WORKDIR /app
112112
ENV LANGFLOW_HOST=0.0.0.0
113113
ENV LANGFLOW_PORT=7860
114114
ENV LANGFLOW_AUTO_LOGIN=false
115+
ENV LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false
116+
ENV LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true
117+
ENV LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true
118+
ENV LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false
119+
ENV LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES=mcp-proxy,lfx
120+
ENV LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true
121+
ENV LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true
115122

116123
CMD ["python", "-m", "langflow", "run", "--backend-only"]

docker/build_and_push_base.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,12 @@ WORKDIR /app
135135
ENV LANGFLOW_HOST=0.0.0.0
136136
ENV LANGFLOW_PORT=7860
137137
ENV LANGFLOW_AUTO_LOGIN=false
138+
ENV LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false
139+
ENV LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true
140+
ENV LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true
141+
ENV LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false
142+
ENV LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES=mcp-proxy,lfx
143+
ENV LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true
144+
ENV LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true
138145

139146
CMD ["langflow-base", "run"]

docker/build_and_push_ep.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ ENV LANGFLOW_HOST=0.0.0.0
122122
ENV LANGFLOW_PORT=7860
123123
ENV LANGFLOW_EVENT_DELIVERY=polling
124124
ENV LANGFLOW_AUTO_LOGIN=false
125+
ENV LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false
126+
ENV LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true
127+
ENV LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true
128+
ENV LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false
129+
ENV LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES=mcp-proxy,lfx
130+
ENV LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true
131+
ENV LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true
125132

126133
USER 1000
127134
CMD ["python", "-m", "langflow", "run", "--host", "0.0.0.0", "--backend-only"]

docker/build_and_push_with_extras.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,12 @@ WORKDIR /app
123123
ENV LANGFLOW_HOST=0.0.0.0
124124
ENV LANGFLOW_PORT=7860
125125
ENV LANGFLOW_AUTO_LOGIN=false
126+
ENV LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false
127+
ENV LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true
128+
ENV LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true
129+
ENV LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK=false
130+
ENV LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES=mcp-proxy,lfx
131+
ENV LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true
132+
ENV LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true
126133

127134
CMD ["langflow", "run"]

docs/docs/Develop/api-keys-and-authentication.mdx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,16 +457,60 @@ SSRF protection prevents requests to internal or private network resources, such
457457

458458
| Variable | Format | Default | Description |
459459
|----------|--------|---------|-------------|
460-
| `LANGFLOW_SSRF_PROTECTION_ENABLED` | Boolean | `False` | Enable SSRF protection for the **API Request** component. When enabled, the component blocks requests to private IP addresses. When disabled, requests are not blocked. |
460+
| `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. |
461461
| `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`.|
462+
| `LANGFLOW_CONNECTOR_SSRF_VALIDATION_ENABLED` | Boolean | `True` | Apply SSRF host validation to connector components that take a tenant-controlled host or URL, including vector stores, SQL databases, model-provider discovery, and remote service base URLs. It defers to `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. |
463+
| `LANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK` | Boolean | `True` | Preserve literal `localhost`, `127.0.0.0/8`, and `::1` connector targets for common local deployments. Set to `false` when mutually-untrusted tenants must not reach services bound to loopback. Hostnames that merely resolve to loopback are still validated. |
464+
465+
:::note Multi-tenant recommendation
466+
In a multi-tenant deployment where mutually-untrusted users build flows, keep `LANGFLOW_CONNECTOR_SSRF_VALIDATION_ENABLED=true` and `LANGFLOW_SSRF_PROTECTION_ENABLED=true`. Allowlist your own internal hosts with `LANGFLOW_SSRF_ALLOWED_HOSTS`.
467+
:::
468+
469+
### Multi-tenant component hardening {#multi-tenant-component-hardening}
470+
471+
The following environment variables close code-execution and local-file-read surfaces that remain reachable through *built-in* components even when user-authored custom components are disabled.
472+
They are disabled by default to preserve single-tenant behavior, and are meant to be set together with [`LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false`](/deployment-block-custom-components) in deployments where mutually-untrusted users build flows.
473+
474+
| Variable | Format | Default | Description |
475+
|----------|--------|---------|-------------|
476+
| `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS` | Boolean | `False` | When `true`, blocks execution of flows containing built-in arbitrary-code-execution components, including Python interpreter/REPL tools, lambda evaluators, and code-running agents. |
477+
| `LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS` | Boolean | `False` | When `true`, built-in file-reading components can read only from the authenticated user's or executing flow's storage namespace, and `save_file` writes are confined there. This also blocks local-file database dialects and local-filesystem Git clones. |
478+
| `LANGFLOW_MCP_SERVER_DOCKER_HARDENING` | Boolean | `False` | When `true`, MCP Docker transports are limited to isolated `docker run` invocations. Host file/API/device access, namespace sharing, named networks, published ports, custom runtimes, restart persistence, and sandbox downgrades are rejected. Published Langflow images enable this by default. |
479+
| `LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES` | String | Not set | A comma-separated allowlist of exact package names that MCP `npx` and `uvx` stdio servers may download and execute. Version pins are permitted, but direct URL/path references and package-injection options are rejected. Published Langflow images allow only `mcp-proxy` and `lfx` by default. |
480+
| `LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING` | Boolean | `False` | When `true`, MCP stdio configurations cannot execute tenant-selected Python modules/scripts, Node.js files, or direct shell scripts. Validated package-runner wrappers and Langflow's authenticated internal agentic MCP module remain available. Published Langflow images enable this by default. |
481+
482+
:::caution Upgrade behavior
483+
This hardening limits `LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true` to the authenticated user's or executing flow's storage namespace. Before upgrading a deployment that already enables this setting, move component-managed files stored directly under `config_dir` into the appropriate user or flow storage namespace and update saved paths.
484+
:::
485+
486+
:::note Multi-tenant recommendation
487+
For a deployment where mutually-untrusted users build flows, set `LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false`, `LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS=true`, `LANGFLOW_RESTRICT_LOCAL_FILE_ACCESS=true`, `LANGFLOW_MCP_SERVER_DOCKER_HARDENING=true`, `LANGFLOW_MCP_SERVER_INTERPRETER_HARDENING=true`, and `LANGFLOW_MCP_SERVER_ALLOWED_PACKAGES` together. Pair these controls with the SSRF settings above.
488+
:::
489+
490+
:::warning Tracing in multi-tenant deployments
491+
External tracing integrations are configured process-wide, not per user. When one is enabled in a multi-tenant deployment, every tenant's flow inputs, outputs, and prompts are sent to that external project. Do not enable a shared SaaS tracing backend where mutually-untrusted tenants can build flows; use built-in local tracing instead.
492+
:::
493+
494+
### Session cookie hardening {#session-cookie-hardening}
495+
496+
For a multi-tenant 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.
497+
498+
| Variable | Format | Default | Description |
499+
|----------|--------|---------|-------------|
500+
| `LANGFLOW_ACCESS_SECURE` | Boolean | `False` | When `true`, the `access_token_lf` cookie is sent only over HTTPS. Recommended `true` for any HTTPS deployment. Leave `false` for plain-HTTP/localhost development, where a `Secure` cookie would not be sent. |
501+
| `LANGFLOW_ACCESS_HTTPONLY` | Boolean | `False` | When `true`, the `access_token_lf` cookie is not readable by JavaScript (mitigates token theft via XSS). The default is `false` because the bundled frontend currently reads this cookie in JavaScript; enabling `HttpOnly` requires a frontend that does not read the token directly. |
502+
| `LANGFLOW_ACCESS_SAME_SITE` | String | `lax` | The `SameSite` attribute of the access-token cookie (`lax`, `strict`, or `none`). |
503+
504+
The refresh-token cookie is already `HttpOnly` + `Secure` + `SameSite` by default.
462505

463506
### Login rate limiting {#login-rate-limiting}
464507

465-
The following environment variables configure IP-based rate limiting on the `/login` endpoint to protect against brute-force attacks.
508+
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.
466509
When the limit is exceeded, Langflow returns HTTP 429 with a `Retry-After: 60` header.
467510

468511
| Variable | Format | Default | Description |
469512
|----------|--------|---------|-------------|
513+
| `LANGFLOW_RATE_LIMIT_ENABLED` | Boolean | `True` | Enable rate limiting globally. Set to `False` to disable all rate limiting (not recommended in production). |
470514
| `LANGFLOW_RATE_LIMIT_PER_MINUTE` | Integer | `5` | Maximum number of login attempts allowed per minute from a single IP address. |
471515
| `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. |
472516
| `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. |

docs/docs/Develop/environment-variables.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ See [Telemetry](/contributing-telemetry).
446446
| `LANGFLOW_ALLOW_COMPONENTS_PATHS_OVERRIDE` | Boolean | `True` | When `false` alongside `LANGFLOW_ALLOW_CUSTOM_COMPONENTS=false`, components contributed by `LANGFLOW_COMPONENTS_PATH` and `LANGFLOW_COMPONENTS_INDEX_PATH` no longer bypass the block. Has no effect when `LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true`. For more information, see [Block custom components](../Deployment/deployment-block-custom-components.mdx). |
447447
| `LANGFLOW_LOAD_FLOWS_PATH` | String | Not set | Path to a directory containing flow JSON files to be loaded on startup. Typically used when creating a Docker image with prepackaged flows. Requires `LANGFLOW_AUTO_LOGIN=True`. |
448448
| `LANGFLOW_LOAD_FLOWS_OVERWRITE_ON_NAME_MATCH` | Boolean | `False` | When a flow file in `LANGFLOW_LOAD_FLOWS_PATH` shares a name with an existing DB row but has a different `id`, controls whether to overwrite the existing row. `False` (default) skips with a warning so UI edits are preserved on restart when file UUIDs regenerate. Set to `True` to opt into prepackaged-flows-are-source-of-truth semantics, typically for CI/CD pipelines. |
449+
| `LANGFLOW_LOAD_FLOWS_PRESERVE_VARIABLE_BINDINGS` | Boolean | `True` | Preserve global-variable bindings configured in the visual editor when an existing flow is reloaded from `LANGFLOW_LOAD_FLOWS_PATH`. Bindings explicitly configured in the flow file still take precedence. Set to `False` to restore blind replacement of the flow data on restart. |
449450
| `LANGFLOW_CREATE_STARTER_PROJECTS` | Boolean | `True` | Whether to create templates during initialization. If `false`, Langflow doesn't create templates, and `LANGFLOW_UPDATE_STARTER_PROJECTS` is treated as `false`. |
450451
| `LANGFLOW_UPDATE_STARTER_PROJECTS` | Boolean | `True` | Whether to update templates with the latest component versions when initializing after an upgrade. |
451452
| `LANGFLOW_LAZY_LOAD_COMPONENTS` | Boolean | `False` | If `true`, Langflow only partially loads components at startup and fully loads them on demand. This significantly reduces startup time but can cause a slight delay when a component is first used. |
@@ -485,4 +486,4 @@ You can hide individual elements without enabling the umbrella flag.
485486
| `LANGFLOW_HIDE_NEW_PROJECT_BUTTON` | Boolean | `False` | If `true`, hides the new project/folder button in the sidebar. Automatically enabled when `LANGFLOW_EMBEDDED_MODE=true`. |
486487
| `LANGFLOW_HIDE_NEW_FLOW_BUTTON` | Boolean | `False` | If `true`, hides the new flow button in the header. Automatically enabled when `LANGFLOW_EMBEDDED_MODE=true`. |
487488
| `LANGFLOW_HIDE_STARTER_PROJECTS` | Boolean | `False` | If `true`, hides the starter projects tab in the templates modal. Does not affect database seeding of starter projects. Automatically enabled when `LANGFLOW_EMBEDDED_MODE=true`. |
488-
| `LANGFLOW_HIDE_GETTING_STARTED_PROGRESS` | Boolean | `False` | If `true`, hides the getting-started onboarding progress UI. Not automatically enabled when `LANGFLOW_EMBEDDED_MODE=true`. |
489+
| `LANGFLOW_HIDE_GETTING_STARTED_PROGRESS` | Boolean | `False` | If `true`, hides the getting-started onboarding progress UI. Not automatically enabled when `LANGFLOW_EMBEDDED_MODE=true`. |
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Shared dependencies for the agentic API.
2+
3+
Kept in a leaf module (only fastapi + lfx settings) so both the route definitions
4+
(langflow.agentic.api.router) and the router-include site (langflow.api.router) can import it
5+
without a circular import.
6+
"""
7+
8+
from fastapi import HTTPException, status
9+
from lfx.services.deps import get_settings_service
10+
11+
12+
def require_agentic_experience() -> None:
13+
"""Backend gate for the agentic assistant's code-generating/executing endpoints.
14+
15+
SECURITY: the assistant generates and EXECUTES component code in-process
16+
(langflow.agentic.helpers.validation.validate_component_runtime and the user-components
17+
overlay). ``agentic_experience`` was only a frontend/UX + MCP-provisioning flag, so the codegen
18+
endpoints were live by default. Gate them here (404 when off), matching the per-endpoint
19+
precedent in api/v1/endpoints.py. The read-only ``/agentic/check-config`` probe is intentionally
20+
NOT gated so non-agentic deployments can still query provider configuration.
21+
"""
22+
if not get_settings_service().settings.agentic_experience:
23+
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="This endpoint is not available")

0 commit comments

Comments
 (0)