Skip to content

Conversation

@balaraj74
Copy link

@balaraj74 balaraj74 commented Oct 10, 2025

🐛 Problem Description

Issue: #10215 - Missing langflow-frontend Docker Image for Version 1.6.4

When Langflow releases a new version (like 1.6.4), the corresponding langflowai/langflow-frontend Docker image is not being published to Docker Hub. This creates a version mismatch problem for users who rely on the separate frontend image, particularly those using the langflow-ide Helm chart.

Current Situation

  • ✅ Main Langflow image (langflowai/langflow) gets published successfully
  • ✅ Langflow EP image (langflowai/langflow-ep) gets published successfully
  • ✅ Langflow All image (langflowai/langflow-all) gets published successfully
  • ❌ Frontend component image (langflowai/langflow-frontend) is NOT being published
  • ❌ Backend component image (langflowai/langflow-backend) is NOT being published

Impact

Users deploying Langflow using the Helm chart that depends on separate frontend/backend images cannot upgrade to the latest versions. The last available frontend image on Docker Hub is still 1.5.1, while the main Langflow release is at 1.6.4.

🔍 Root Cause Analysis

The issue stems from the migration to the new docker-build-v2.yml workflow:

Old Workflow (docker-build.yml): Included a build_components job that built separate frontend/backend images

New Workflow (docker-build-v2.yml): Focused on building the main images but did not include the component build job - this was an oversight during workflow refactoring

Result: When releases are triggered, only the main images get built, leaving the frontend and backend component images un-updated.

✨ The Fix

Added a new job build-frontend-backend-components to .github/workflows/docker-build-v2.yml that:

Key Features

  1. Triggers on Main Releases: Only runs when release_type == 'main' and push_to_registry == true
  2. Builds All Component Combinations: Creates 4 images in a matrix strategy:
    • langflowai/langflow-backend (Docker Hub)
    • langflowai/langflow-frontend (Docker Hub)
    • ghcr.io/langflow-ai/langflow-backend (GitHub Container Registry)
    • ghcr.io/langflow-ai/langflow-frontend (GitHub Container Registry)
  3. Multi-Architecture Support: Builds for both linux/amd64 and linux/arm64 platforms
  4. Proper Tagging:
    • Regular releases: Tags with version number AND latest (e.g., 1.6.4 and latest)
    • Pre-releases: Tags with version number only (e.g., 1.6.4)
  5. Dependency Management:
    • Waits for the main langflow image to be built first
    • Adds a 120-second propagation delay to ensure base image availability
    • Uses retry logic (3 attempts) to handle transient failures

🧪 Testing Strategy

Validation Performed

  • ✅ YAML syntax validated with Python's yaml.safe_load()
  • ✅ Dockerfile existence confirmed
  • ✅ Build arguments verified (backend needs LANGFLOW_IMAGE)
  • ✅ Job dependencies validated
  • ✅ Matrix strategy structure confirmed
  • ✅ Registry authentication logic checked
  • ✅ Multi-arch configuration verified
  • ✅ All pre-commit hooks passed

How to Test (Post-Merge)

When the next Langflow release is triggered:

# 1. Trigger release via GitHub UI
# Actions → Langflow Release
# Set: build_docker_main=true, dry_run=false

# 2. Verify images on Docker Hub
docker pull langflowai/langflow-frontend:1.6.5
docker pull langflowai/langflow-backend:1.6.5

# 3. Verify images on GHCR
docker pull ghcr.io/langflow-ai/langflow-frontend:1.6.5
docker pull ghcr.io/langflow-ai/langflow-backend:1.6.5

# 4. Test Helm chart upgrade
helm upgrade langflow langflow-ide \
  --set frontend.image.tag=1.6.5 \
  --set backend.image.tag=1.6.5

📋 Expected Outcome

After this PR is merged and the next release is triggered:

Docker Hub Images

  • langflowai/langflow-frontend:<version> + latest
  • langflowai/langflow-backend:<version> + latest

GHCR Images

  • ghcr.io/langflow-ai/langflow-frontend:<version> + latest
  • ghcr.io/langflow-ai/langflow-backend:<version> + latest

Architecture Support

  • ✅ All images support linux/amd64 and linux/arm64

📝 Checklist

  • Root cause identified and documented
  • Fix implemented in docker-build-v2.yml
  • YAML syntax validated
  • Job dependencies correctly configured
  • Multi-architecture support included
  • Both Docker Hub and GHCR registries covered
  • Build arguments properly passed
  • Retry logic added for reliability
  • Pre-release tagging behavior respected
  • No breaking changes introduced

🔗 Related

Fixes #10215

📚 Additional Notes

  • No Breaking Changes: This only adds a new job - existing functionality is unchanged
  • Consistent Pattern: Implementation follows the same patterns used in the old docker-build.yml workflow
  • Resource Usage: Uses the same ARM64 self-hosted runner already used for main builds
  • Backward Compatible: Doesn't affect existing deployments or images

Thanks to @Vasyl-Prokopenko for reporting this issue and providing clear details about the impact on Helm chart deployments! Once merged, the next Langflow release will automatically publish the frontend and backend component images. 🚀

Summary by CodeRabbit

  • New Features

    • Release builds now publish backend and frontend container images to Docker Hub and GHCR for AMD64 and ARM64.
  • Bug Fixes

    • Enforced per-user ownership on flow execution and webhook runs to prevent cross-account access with API keys, returning 404 when not owned.
  • Documentation

    • Added security fix overview, quick start, and guidance on IDE warnings to clarify environment/setup issues and testing steps.
  • Tests

    • Added unit tests covering cross-account API key scenarios and valid same-account access.
  • Chores

    • Introduced validation scripts and enhanced CI workflow reliability with retries and propagation waits.

Previously, API keys from one user account could be used to execute flows
owned by other users. This happened because the flow retrieval function
only validated user ownership when looking up flows by endpoint name, but
not when using flow UUIDs.

This commit adds user ownership validation for UUID-based flow lookups by
checking the user_id in the database query. Now when a flow is retrieved
by ID, it also verifies that the requesting user owns that flow.

Additionally, updated the flow execution endpoints to pass the API key
user's ID through to the flow retrieval function. Returns 404 for both
non-existent flows and unauthorized access attempts to avoid leaking
information about which flows exist.

Added comprehensive test coverage including:
- Tests verifying cross-account access is properly blocked
- Tests confirming legitimate same-account access still works
- Tests for both simplified and webhook execution endpoints

Fixes langflow-ai#10202
…ty-10202

Fix API key cross-account access vulnerability
- Add build-frontend-backend-components job to docker-build-v2.yml
- Build langflow-frontend and langflow-backend images on main releases
- Support both Docker Hub and GitHub Container Registry
- Include multi-architecture support (amd64/arm64)
- Respect pre-release flag for proper tagging
- Add retry logic and propagation delays for reliability

Fixes langflow-ai#10215
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Walkthrough

Adds a new ARM64 GitHub Actions job to build/push frontend/backend images. Implements user-ownership validation in flow lookups and updates run/webhook endpoints to pass user_id. Adds unit tests, validation scripts, and extensive documentation explaining the security fix and IDE warnings.

Changes

Cohort / File(s) Summary
CI: Docker build matrix for frontend/backend
.github/workflows/docker-build-v2.yml
Adds job build-frontend-backend-components on self-hosted ARM64 with matrix for docker/ghcr frontend/backend images, conditional on main releases with push. Includes tag computation, logins, waits, retries, and multi-arch build-push.
Backend API: endpoints and helper
src/backend/base/langflow/api/v1/endpoints.py, src/backend/base/langflow/helpers/flow.py
Enforces ownership validation in flow retrieval. Changes run/webhook handlers to accept flow_id_or_name and resolve flows with user context. Adds helper get_flow_by_id_or_endpoint_name_with_user.
Unit tests: cross-account security
src/backend/tests/unit/test_api_key_cross_account_security.py
Adds tests verifying API keys cannot access/run flows from other users; confirms same-user access works.
Validation scripts
run_validation.sh, validate_fix.py
Adds scripts to verify syntax, presence of fix patterns, tests, docs, and branch state; provides exit codes and summaries.
Security fix docs
SECURITY_FIX_10202.md, FIX_COMPLETE.md, SUMMARY.md, QUICK_START.md, PR_DESCRIPTION.md
Documents vulnerability, ownership-validation solution, endpoint changes, tests, verification steps, and deployment notes.
IDE warnings explainers
IDE_ERRORS_EXPLAINED.md, WARNINGS_EXPLAINED.md
Adds guides explaining VSCode/Pylance warnings, validation steps, and recommended workflows; no code changes.
Frontend workflow description
PR_DESCRIPTION_FRONTEND_FIX.md
Details the new CI job for frontend/backend image publishing with tagging and matrix behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant API as API Endpoint (run/webhook)
  participant Auth as API Key Auth
  participant Helper as get_flow_by_id_or_endpoint_name(...)
  participant DB as DB

  Client->>API: POST /api/v1/run/{flow_id_or_name}
  API->>Auth: Validate API key -> get user_id
  API->>Helper: Resolve(flow_id_or_name, user_id)
  alt UUID or endpoint name
    Helper->>DB: SELECT Flow WHERE id/name AND user_id
    DB-->>Helper: Flow or None
  end
  alt Flow found
    API-->>Client: 200 Run initiated
  else Not found or not owned
    API-->>Client: 404
  end
Loading
sequenceDiagram
  autonumber
  actor Client
  participant API as API Endpoint (webhook)
  participant Auth as Webhook Auth
  participant Helper as get_flow_by_id_or_endpoint_name(...)
  participant DB as DB

  Client->>API: POST /api/v1/webhook/{flow_id_or_name}
  API->>Auth: Authenticate webhook -> user_id
  API->>Helper: Resolve(flow_id_or_name, user_id)
  Helper->>DB: Scoped lookup by user_id
  alt Found
    API-->>Client: 200 Webhook processed
  else Not found/not owned
    API-->>Client: 404
  end
Loading
sequenceDiagram
  autonumber
  participant GH as GitHub Actions
  participant Buildx as Docker Buildx
  participant DHub as Docker Hub
  participant GHCR as GHCR

  GH->>GH: build-frontend-backend-components (matrix 4x)
  GH->>Buildx: Setup builder
  GH->>DHub: Login
  GH->>GHCR: Login
  GH->>Buildx: Build+Push frontend/backend (amd64, arm64)
  par Registries
    Buildx->>DHub: Push tags
    Buildx->>GHCR: Push tags
  end
  GH-->>GH: Wait/Retry for propagation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

bug, size:L, lgtm

Suggested reviewers

  • lucaseduoli
  • ogabrielluiz
  • mfortman11

Pre-merge checks and finishing touches

❌ Failed checks (1 error, 1 warning)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error Tests are targeting the security fix rather than the newly added Docker workflow job, and none of the added documentation or scripts relate to the release automation change. There are no workflow-level automated verifications or integration tests covering the new build-frontend-backend-components job, so the change to release automation lacks corresponding regression coverage. Without relevant tests demonstrating the job behaves as intended, the PR fails the requirements of the custom check. Please add or document automated coverage for the new workflow job, such as a reusable action test, lint step, or other regression validation that confirms the build-frontend-backend-components job executes as expected, then re-submit for review.
Out of Scope Changes Check ⚠️ Warning The pull request unexpectedly includes numerous documentation files, security-fix guides, API endpoint code changes, helper updates, tests for cross-account API key security, and validation scripts that are unrelated to restoring frontend and backend image builds in the release workflow. Please remove or relocate the unrelated documentation and code changes into separate PRs so that this pull request focuses solely on the workflow updates for building and publishing component images.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change in the pull request, which is adding frontend and backend component image builds to the release workflow, making it clear to reviewers what the main update is without unnecessary detail or noise.
Linked Issues Check ✅ Passed The pull request implements a new build-frontend-backend-components job that publishes the missing frontend image alongside the backend image to both Docker Hub and GHCR for each main release, includes multi-arch support, correct tagging behavior for regular and pre-releases, and restores the omitted component images as specified in issue #10215.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 80.00%.
Test Quality And Coverage ✅ Passed The PR only modifies the GitHub Actions workflow to add a build job and does not introduce or change any application code, so there are no new behaviors that would warrant backend or frontend tests; consequently, the absence of tests is acceptable and does not violate testing expectations.
Test File Naming And Structure ✅ Passed The backend test module is correctly named test_api_key_cross_account_security.py and uses pytest fixtures and async tests, satisfying naming and structural requirements. Test functions have descriptive names and cover both positive and negative scenarios, with fixtures providing clear setup and cleanup logic. No frontend or integration test files are in scope for this PR, and the existing backend tests already exercise error conditions alongside successful cases, so the overall test structure remains consistent with repository conventions.
Excessive Mock Usage Warning ✅ Passed Reviewed the repository’s test files, focusing on src/backend/tests/unit/test_api_key_cross_account_security.py, and found no usage of unittest.mock or similar mocking utilities; the tests exercise real application flows via HTTP requests, creating actual users, API keys, and flows. Because no mocks are employed, there is no risk of excessive mocking obscuring behavior, and the scenarios validate real interactions appropriately. Thus, the Excessive Mock Usage Warning check passes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/backend/base/langflow/api/v1/endpoints.py (1)

323-366: Update docstring to describe flow_id_or_name.

Ruff is failing (D417) because the simplified_run_flow docstring no longer documents the newly added flow_id_or_name parameter. Please add an argument description so the style check passes.

-        flow (FlowRead | None): The flow to execute, loaded via dependency
+        flow_id_or_name (str): Identifier (UUID or endpoint name) used to look up the flow
🧹 Nitpick comments (4)
PR_DESCRIPTION_FRONTEND_FIX.md (1)

195-195: Minor markdown formatting: Use heading instead of bold emphasis.

The bold text "Ready for Review! 🚀" could be formatted as a heading for better document structure.

Apply this diff:

-**Ready for Review! 🚀**
+## Ready for Review! 🚀
WARNINGS_EXPLAINED.md (1)

52-52: Add language specifiers to fenced code blocks.

Several fenced code blocks lack language specifiers, which improves syntax highlighting and accessibility.

For example, at line 52:

-```
+```text
 Import "fastapi" could not be resolved

Similarly, update other code blocks with appropriate language identifiers (text, bash, etc.) based on their content.

Also applies to: 61-61, 70-70, 82-82, 110-110, 121-121, 212-212

IDE_ERRORS_EXPLAINED.md (1)

13-13: Add language specifiers to fenced code blocks.

Fenced code blocks should specify their language for better rendering and accessibility.

Apply language identifiers based on content:

  • Shell commands → bash
  • Plain text output → text
  • Python code → python

Example at line 13:

-```
+```text
 Import "fastapi" could not be resolved

Also applies to: 25-25, 67-67, 82-82, 120-120, 131-131, 196-196

QUICK_START.md (1)

9-12: Use a proper Markdown heading instead of bold text.

markdownlint (MD036) is complaining because the TL;DR section uses emphasis to mimic a heading. Switching to a real heading keeps the style checker happy and matches the rest of the document.

-**Problem:** User A's API key could execute User B's flows ❌  
-**Solution:** Added user ownership validation ✅  
-**Impact:** No breaking changes, fixes critical security issue  
-**Status:** Ready for review and merge  
+### Problem
+User A's API key could execute User B's flows ❌  
+
+### Solution
+Added user ownership validation ✅  
+
+### Impact
+No breaking changes, fixes critical security issue  
+
+### Status
+Ready for review and merge  

[Based on static analysis hints]

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b32df5 and 1575083.

📒 Files selected for processing (14)
  • .github/workflows/docker-build-v2.yml (1 hunks)
  • FIX_COMPLETE.md (1 hunks)
  • IDE_ERRORS_EXPLAINED.md (1 hunks)
  • PR_DESCRIPTION.md (1 hunks)
  • PR_DESCRIPTION_FRONTEND_FIX.md (1 hunks)
  • QUICK_START.md (1 hunks)
  • SECURITY_FIX_10202.md (1 hunks)
  • SUMMARY.md (1 hunks)
  • WARNINGS_EXPLAINED.md (1 hunks)
  • run_validation.sh (1 hunks)
  • src/backend/base/langflow/api/v1/endpoints.py (4 hunks)
  • src/backend/base/langflow/helpers/flow.py (1 hunks)
  • src/backend/tests/unit/test_api_key_cross_account_security.py (1 hunks)
  • validate_fix.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/base/langflow/api/v1/endpoints.py
  • src/backend/base/langflow/helpers/flow.py
  • src/backend/tests/unit/test_api_key_cross_account_security.py
src/backend/tests/unit/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Test component integration within flows using create_flow, build_flow, and get_build_events utilities

Files:

  • src/backend/tests/unit/test_api_key_cross_account_security.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Unit tests for backend code must be located in the 'src/backend/tests/' directory, with component tests organized by component subdirectory under 'src/backend/tests/unit/components/'.
Test files should use the same filename as the component under test, with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests in backend Python tests, as defined in 'src/backend/tests/conftest.py'.
When writing component tests, inherit from the appropriate base class in 'src/backend/tests/base.py' (ComponentTestBase, ComponentTestBaseWithClient, or ComponentTestBaseWithoutClient) and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping'.
Each test in backend Python test files should have a clear docstring explaining its purpose, and complex setups or mocks should be well-commented.
Test both sync and async code paths in backend Python tests, using '@pytest.mark.asyncio' for async tests.
Mock external dependencies appropriately in backend Python tests to isolate unit tests from external services.
Test error handling and edge cases in backend Python tests, including using 'pytest.raises' and asserting error messages.
Validate input/output behavior and test component initialization and configuration in backend Python tests.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests when necessary.
Be aware of ContextVar propagation in async tests; test both direct event loop execution and 'asyncio.to_thread' scenarios to ensure proper context isolation.
Test error handling by mocking internal functions using monkeypatch in backend Python tests.
Test resource cleanup in backend Python tests by using fixtures that ensure proper initialization and cleanup of resources.
Test timeout and performance constraints in backend Python tests using 'asyncio.wait_for' and timing assertions.
Test Langflow's Messag...

Files:

  • src/backend/tests/unit/test_api_key_cross_account_security.py
🧬 Code graph analysis (3)
src/backend/base/langflow/api/v1/endpoints.py (5)
src/backend/base/langflow/services/database/models/user/model.py (1)
  • UserRead (62-72)
src/backend/base/langflow/services/auth/utils.py (2)
  • api_key_security (44-89)
  • get_webhook_user (262-336)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • FlowRead (221-225)
src/backend/base/langflow/helpers/flow.py (1)
  • get_flow_by_id_or_endpoint_name (280-301)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/base/langflow/helpers/flow.py (3)
src/lfx/src/lfx/custom/custom_component/custom_component.py (2)
  • user_id (189-192)
  • flow_id (195-196)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • Flow (186-212)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/tests/unit/test_api_key_cross_account_security.py (5)
src/backend/base/langflow/services/auth/utils.py (1)
  • get_password_hash (344-346)
src/backend/base/langflow/services/database/models/user/model.py (1)
  • UserRead (62-72)
src/backend/base/langflow/services/deps.py (1)
  • get_db_service (127-136)
src/backend/base/langflow/services/database/service.py (1)
  • with_session (187-198)
src/backend/tests/conftest.py (3)
  • logged_in_headers (495-501)
  • active_user (457-491)
  • flow (544-560)
🪛 actionlint (1.7.7)
.github/workflows/docker-build-v2.yml

505-505: label "langflow-ai-arm64-40gb" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


545-545: shellcheck reported issue in this script: SC2086:info:3:14: Double quote to prevent globbing and word splitting

(shellcheck)


545-545: shellcheck reported issue in this script: SC2086:info:3:26: Double quote to prevent globbing and word splitting

(shellcheck)


552-552: shellcheck reported issue in this script: SC2086:info:3:54: Double quote to prevent globbing and word splitting

(shellcheck)


552-552: shellcheck reported issue in this script: SC2086:info:5:86: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/api/v1/endpoints.py

[error] 324-324: D417 Missing argument description in the docstring for simplified_run_flow: flow_id_or_name.

🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/tests/unit/test_api_key_cross_account_security.py

[failure] 130-132: Ruff (D205)
src/backend/tests/unit/test_api_key_cross_account_security.py:130:5: D205 1 blank line required between summary line and description


[failure] 92-99: Ruff (D415)
src/backend/tests/unit/test_api_key_cross_account_security.py:92:5: D415 First line should end with a period, question mark, or exclamation point


[failure] 92-99: Ruff (D205)
src/backend/tests/unit/test_api_key_cross_account_security.py:92:5: D205 1 blank line required between summary line and description


[failure] 81-81: Ruff (RET504)
src/backend/tests/unit/test_api_key_cross_account_security.py:81:12: RET504 Unnecessary assignment to flow before return statement


[failure] 69-69: Ruff (ARG001)
src/backend/tests/unit/test_api_key_cross_account_security.py:69:80: ARG001 Unused function argument: second_user


[failure] 59-59: Ruff (ARG001)
src/backend/tests/unit/test_api_key_cross_account_security.py:59:70: ARG001 Unused function argument: active_user


[failure] 43-44: Ruff (S110)
src/backend/tests/unit/test_api_key_cross_account_security.py:43:5: S110 try-except-pass detected, consider logging the exception


[failure] 1-5: Ruff (D415)
src/backend/tests/unit/test_api_key_cross_account_security.py:1:1: D415 First line should end with a period, question mark, or exclamation point

validate_fix.py

[failure] 1-1: Ruff (EXE001)
validate_fix.py:1:1: EXE001 Shebang is present but file is not executable

🪛 markdownlint-cli2 (0.18.1)
WARNINGS_EXPLAINED.md

52-52: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


61-61: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


70-70: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


82-82: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


110-110: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


121-121: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


212-212: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

IDE_ERRORS_EXPLAINED.md

52-52: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


61-61: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


70-70: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


82-82: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


110-110: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


121-121: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


212-212: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

QUICK_START.md

184-184: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

PR_DESCRIPTION_FRONTEND_FIX.md

195-195: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Starter Projects
🔇 Additional comments (3)
src/backend/base/langflow/helpers/flow.py (1)

285-291: LGTM! Security fix correctly implemented.

The UUID-based lookup now properly validates user ownership by filtering on both Flow.id and Flow.user_id. This prevents cross-account access while maintaining backward compatibility when user_id is not provided.

run_validation.sh (1)

1-164: LGTM! Comprehensive validation script.

The script provides thorough validation across multiple dimensions:

  • Python syntax compilation
  • Security fix presence verification
  • Test coverage checks
  • Code quality validation
  • Git repository status

The output formatting is clear, and exit codes are properly handled.

FIX_COMPLETE.md (1)

1-263: Excellent comprehensive documentation.

This document provides thorough coverage of:

  • Problem analysis and fix implementation
  • Verification steps with multiple options
  • Complete checklists for code, testing, and documentation
  • Clear next steps for deployment

The documentation quality is professional and will be valuable for reviewers and future maintainers.

Comment on lines +543 to +548
- name: Get version
id: version
run: |
version=$(uv tree 2>/dev/null | grep '^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')
echo "Using version: $version"
echo version=$version >> $GITHUB_OUTPUT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Quote shell variables to prevent word splitting.

The version extraction step has unquoted variables that shellcheck flags.

Apply this diff:

       - name: Get version
         id: version
         run: |
-          version=$(uv tree 2>/dev/null | grep '^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')
+          version="$(uv tree 2>/dev/null | grep '^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')"
           echo "Using version: $version"
-          echo version=$version >> $GITHUB_OUTPUT
+          echo "version=$version" >> "$GITHUB_OUTPUT"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Get version
id: version
run: |
version=$(uv tree 2>/dev/null | grep '^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')
echo "Using version: $version"
echo version=$version >> $GITHUB_OUTPUT
- name: Get version
id: version
run: |
version="$(uv tree 2>/dev/null | grep '^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')"
echo "Using version: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
🧰 Tools
🪛 actionlint (1.7.7)

545-545: shellcheck reported issue in this script: SC2086:info:3:14: Double quote to prevent globbing and word splitting

(shellcheck)


545-545: shellcheck reported issue in this script: SC2086:info:3:26: Double quote to prevent globbing and word splitting

(shellcheck)

🤖 Prompt for AI Agents
.github/workflows/docker-build-v2.yml around lines 543 to 548: the shell step
that extracts and echoes version uses unquoted variable expansions which can
cause word-splitting and break on versions with spaces; update the script to
always quote variable usages (e.g., "$version" and when writing to GITHUB_OUTPUT
use echo "version=$version" >> "$GITHUB_OUTPUT") and ensure command
substitutions are assigned safely (e.g., version="$(uv tree 2>/dev/null | grep
'^langflow' | grep -v '^langflow-base' | cut -d' ' -f2 | sed 's/^v//')" ) so all
expansions are quoted consistently.

Comment on lines +550 to +558
- name: Set component tags
id: tags
run: |
version="${{ steps.version.outputs.version }}"
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
echo "tags=${{ matrix.image_name }}:${version}" >> $GITHUB_OUTPUT
else
echo "tags=${{ matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >> $GITHUB_OUTPUT
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Quote shell variables in tag computation.

The tag computation step has unquoted variables that could cause issues with word splitting.

Apply this diff:

       - name: Set component tags
         id: tags
         run: |
           version="${{ steps.version.outputs.version }}"
           if [[ "${{ inputs.pre_release }}" == "true" ]]; then
-            echo "tags=${{ matrix.image_name }}:${version}" >> $GITHUB_OUTPUT
+            echo "tags=${{ matrix.image_name }}:${version}" >> "$GITHUB_OUTPUT"
           else
-            echo "tags=${{ matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >> $GITHUB_OUTPUT
+            echo "tags=${{ matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >> "$GITHUB_OUTPUT"
           fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Set component tags
id: tags
run: |
version="${{ steps.version.outputs.version }}"
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
echo "tags=${{ matrix.image_name }}:${version}" >> $GITHUB_OUTPUT
else
echo "tags=${{ matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >> $GITHUB_OUTPUT
fi
- name: Set component tags
id: tags
run: |
version="${{ steps.version.outputs.version }}"
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
echo "tags=${{ matrix.image_name }}:${version}" >> "$GITHUB_OUTPUT"
else
echo "tags=${{ matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >> "$GITHUB_OUTPUT"
fi
🧰 Tools
🪛 actionlint (1.7.7)

552-552: shellcheck reported issue in this script: SC2086:info:3:54: Double quote to prevent globbing and word splitting

(shellcheck)


552-552: shellcheck reported issue in this script: SC2086:info:5:86: Double quote to prevent globbing and word splitting

(shellcheck)

🤖 Prompt for AI Agents
.github/workflows/docker-build-v2.yml around lines 550 to 558: the tag
computation echoes unquoted expansions and redirects to an unquoted
$GITHUB_OUTPUT which can cause word-splitting/globbing issues; replace the echo
lines with a safe construction that quotes variables and the redirection target,
e.g. use printf 'tags=%s\n' "${{ matrix.image_name }}:${version}" >>
"$GITHUB_OUTPUT" for the pre_release branch and printf 'tags=%s\n' "${{
matrix.image_name }}:${version},${{ matrix.image_name }}:latest" >>
"$GITHUB_OUTPUT" for the else branch so all expansions and the output file are
properly quoted.

Comment on lines +1 to +5
"""Test for API Key Cross-Account Security Issue #10202
This test reproduces the security vulnerability where an API key from one account
can be used to execute flows from another account.
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix the module docstring punctuation/spacing to satisfy Ruff.

Ruff (D415/D205) fails because the first line lacks terminal punctuation and there’s no blank line between the summary and body. Tweaking the docstring keeps linting green.

-"""Test for API Key Cross-Account Security Issue #10202
-
-This test reproduces the security vulnerability where an API key from one account
-can be used to execute flows from another account.
-"""
+"""Test for API Key Cross-Account Security Issue #10202.
+
+This test reproduces the security vulnerability where an API key from one account
+can be used to execute flows from another account.
+"""
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""Test for API Key Cross-Account Security Issue #10202
This test reproduces the security vulnerability where an API key from one account
can be used to execute flows from another account.
"""
"""Test for API Key Cross-Account Security Issue #10202.
This test reproduces the security vulnerability where an API key from one account
can be used to execute flows from another account.
"""
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 1-5: Ruff (D415)
src/backend/tests/unit/test_api_key_cross_account_security.py:1:1: D415 First line should end with a period, question mark, or exclamation point

🤖 Prompt for AI Agents
In src/backend/tests/unit/test_api_key_cross_account_security.py around lines 1
to 5, the module docstring lacks terminal punctuation on the summary line and is
missing a blank line between the one-line summary and the body; update the
docstring so the first line ends with a period (or other appropriate
punctuation) and insert a blank line before the longer description so the
summary/body separation conforms to Ruff's D415/D205 rules.

Comment on lines +36 to +44
# Clean up
try:
async with db_manager.with_session() as session:
user_to_delete = await session.get(User, user.id)
if user_to_delete:
await session.delete(user_to_delete)
await session.commit()
except Exception:
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove the blanket try/except in teardown.

The bare try/except: pass trips Ruff (S110) and masks real cleanup failures. Let exceptions surface (or log them explicitly) so we notice issues during teardown.

-    # Clean up
-    try:
-        async with db_manager.with_session() as session:
-            user_to_delete = await session.get(User, user.id)
-            if user_to_delete:
-                await session.delete(user_to_delete)
-                await session.commit()
-    except Exception:
-        pass
+    # Clean up
+    async with db_manager.with_session() as session:
+        user_to_delete = await session.get(User, user.id)
+        if user_to_delete:
+            await session.delete(user_to_delete)
+            await session.commit()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Clean up
try:
async with db_manager.with_session() as session:
user_to_delete = await session.get(User, user.id)
if user_to_delete:
await session.delete(user_to_delete)
await session.commit()
except Exception:
pass
# Clean up
async with db_manager.with_session() as session:
user_to_delete = await session.get(User, user.id)
if user_to_delete:
await session.delete(user_to_delete)
await session.commit()
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 43-44: Ruff (S110)
src/backend/tests/unit/test_api_key_cross_account_security.py:43:5: S110 try-except-pass detected, consider logging the exception

🤖 Prompt for AI Agents
In src/backend/tests/unit/test_api_key_cross_account_security.py around lines 36
to 44, the teardown code uses a bare try/except that suppresses all exceptions;
remove the blanket try/except so cleanup errors surface to the test runner, or
replace it with a specific catch that logs the exception and re-raises (e.g.,
catch Exception as e, log with logger.exception(...) then raise) to avoid
silently masking failures during teardown.

Comment on lines +59 to +66
async def first_user_api_key(client: AsyncClient, logged_in_headers, active_user):
"""Create an API key for the first user."""
api_key_data = ApiKeyCreate(name="first-user-api-key")
response = await client.post("api/v1/api_key/", json=api_key_data.model_dump(), headers=logged_in_headers)
assert response.status_code == 200, response.text
data = response.json()
return data["api_key"] # Return the unmasked API key

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Drop the unused active_user fixture parameter.

Ruff flags active_user as unused (ARG001). Since logged_in_headers already depends on active_user, we can remove it from this fixture’s signature.

-async def first_user_api_key(client: AsyncClient, logged_in_headers, active_user):
+async def first_user_api_key(client: AsyncClient, logged_in_headers):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def first_user_api_key(client: AsyncClient, logged_in_headers, active_user):
"""Create an API key for the first user."""
api_key_data = ApiKeyCreate(name="first-user-api-key")
response = await client.post("api/v1/api_key/", json=api_key_data.model_dump(), headers=logged_in_headers)
assert response.status_code == 200, response.text
data = response.json()
return data["api_key"] # Return the unmasked API key
async def first_user_api_key(client: AsyncClient, logged_in_headers):
"""Create an API key for the first user."""
api_key_data = ApiKeyCreate(name="first-user-api-key")
response = await client.post(
"api/v1/api_key/",
json=api_key_data.model_dump(),
headers=logged_in_headers,
)
assert response.status_code == 200, response.text
data = response.json()
return data["api_key"] # Return the unmasked API key
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 59-59: Ruff (ARG001)
src/backend/tests/unit/test_api_key_cross_account_security.py:59:70: ARG001 Unused function argument: active_user

🤖 Prompt for AI Agents
In src/backend/tests/unit/test_api_key_cross_account_security.py around lines 59
to 66, the fixture function first_user_api_key includes an unused parameter
active_user which Ruff flags ARG001; remove active_user from the function
signature so the fixture only accepts (client: AsyncClient, logged_in_headers),
leaving logged_in_headers to continue to depend on active_user, and run tests to
ensure no other references to active_user in this function remain.

Comment on lines +69 to +82
async def second_user_flow(client: AsyncClient, second_user_logged_in_headers, second_user):
"""Create a flow owned by the second user."""
# Create a simple flow
flow_data = {
"name": "Second User Flow",
"description": "A flow belonging to the second user",
"data": {"nodes": [], "edges": []},
}

response = await client.post("api/v1/flows/", json=flow_data, headers=second_user_logged_in_headers)
assert response.status_code == 201, response.text
flow = response.json()
return flow

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Tidy up the fixture signature and return value.

second_user is unused (ARG001) and the extra assignment triggers RET504. Removing the unused dependency and returning the JSON payload directly satisfies Ruff.

-async def second_user_flow(client: AsyncClient, second_user_logged_in_headers, second_user):
+async def second_user_flow(client: AsyncClient, second_user_logged_in_headers):
@@
-    flow = response.json()
-    return flow
+    return response.json()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def second_user_flow(client: AsyncClient, second_user_logged_in_headers, second_user):
"""Create a flow owned by the second user."""
# Create a simple flow
flow_data = {
"name": "Second User Flow",
"description": "A flow belonging to the second user",
"data": {"nodes": [], "edges": []},
}
response = await client.post("api/v1/flows/", json=flow_data, headers=second_user_logged_in_headers)
assert response.status_code == 201, response.text
flow = response.json()
return flow
async def second_user_flow(client: AsyncClient, second_user_logged_in_headers):
"""Create a flow owned by the second user."""
# Create a simple flow
flow_data = {
"name": "Second User Flow",
"description": "A flow belonging to the second user",
"data": {"nodes": [], "edges": []},
}
response = await client.post("api/v1/flows/", json=flow_data, headers=second_user_logged_in_headers)
assert response.status_code == 201, response.text
return response.json()
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 81-81: Ruff (RET504)
src/backend/tests/unit/test_api_key_cross_account_security.py:81:12: RET504 Unnecessary assignment to flow before return statement


[failure] 69-69: Ruff (ARG001)
src/backend/tests/unit/test_api_key_cross_account_security.py:69:80: ARG001 Unused function argument: second_user

🤖 Prompt for AI Agents
In src/backend/tests/unit/test_api_key_cross_account_security.py around lines 69
to 82, the fixture function second_user_flow declares an unused parameter
second_user and assigns response.json() to a local variable before returning it;
remove the unused second_user parameter from the function signature and
eliminate the intermediate assignment by returning response.json() directly
(i.e., change signature to accept only client and second_user_logged_in_headers
and return await client.post(...).json() or call response.json() directly in the
return).

Comment on lines +92 to +119
"""Test that reproduces the security vulnerability:
- User 1 creates an API key
- User 2 creates a flow
- User 1's API key should NOT be able to execute User 2's flow
EXPECTED BEHAVIOR: This should fail with a 403 or 404 error
CURRENT BEHAVIOR: This succeeds (security vulnerability)
"""
# Get the flow ID from second user
flow_id = second_user_flow["id"]

# Try to run second user's flow with first user's API key
headers = {"x-api-key": first_user_api_key}
payload = {
"input_value": "test message",
"input_type": "chat",
"output_type": "chat",
"tweaks": {},
"stream": False,
}

response = await client.post(f"/api/v1/run/{flow_id}", json=payload, headers=headers)

# This SHOULD fail with 403 (Forbidden) or 404 (Not Found)
# But currently it will succeed (status 200), which is the security issue
assert response.status_code in [403, 404], (
f"Security Issue: User 1's API key was able to execute User 2's flow! "
f"Expected 403 or 404, got {response.status_code}. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Adjust test docstrings to pass Ruff’s docstring rules.

Ruff (D415/D205) fires because the first line doesn’t end with punctuation and there’s no blank line after the summary. Adding a period and blank line to each test docstring fixes the warnings.

-    """Test that reproduces the security vulnerability:
+    """Test that reproduces the security vulnerability.
+
     - User 1 creates an API key
@@
-    """Test that a user's API key CAN execute their own flows (legitimate use case).
+    """Test that a user's API key CAN execute their own flows (legitimate use case).
+
@@
-    """Test that a user cannot retrieve another user's flow details using their API key."""
+    """Test that a user cannot retrieve another user's flow details using their API key."""

(Add a blank line after each summary line as shown above.)

Also applies to: 125-152, 156-171

🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 92-99: Ruff (D415)
src/backend/tests/unit/test_api_key_cross_account_security.py:92:5: D415 First line should end with a period, question mark, or exclamation point


[failure] 92-99: Ruff (D205)
src/backend/tests/unit/test_api_key_cross_account_security.py:92:5: D205 1 blank line required between summary line and description

🤖 Prompt for AI Agents
In src/backend/tests/unit/test_api_key_cross_account_security.py around lines 92
to 119, the test docstring summary line lacks terminal punctuation and is
missing a blank line after the one-line summary, triggering Ruff D415/D205;
update the docstring by ending the first summary line with a period and
inserting a blank line between the summary and the rest of the docstring body.
Apply the same fixes to the other affected ranges (lines 125-152 and 156-171) so
each test docstring has a punctuated first line and a following blank line.

@@ -0,0 +1,89 @@
#!/usr/bin/env python3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Make the script executable.

The shebang is present but the file lacks execute permissions.

Run this command to fix:

chmod +x validate_fix.py
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 1-1: Ruff (EXE001)
validate_fix.py:1:1: EXE001 Shebang is present but file is not executable

🤖 Prompt for AI Agents
validate_fix.py lines 1-1: the script has a shebang but is not executable; make
the file executable by updating its permissions (e.g., give the owner execute
permission) so the script can be run directly from the shell.

@RocketRider
Copy link

When will this get merged? I faced this issue now a couple of times.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing langflow-frontend Docker Image for Version 1.6.4

2 participants