Skip to content

feat: Add configurable API key validation source (db/env)#10783

Merged
Cristhianzl merged 15 commits intomainfrom
cz/add-xapikey-env
Dec 3, 2025
Merged

feat: Add configurable API key validation source (db/env)#10783
Cristhianzl merged 15 commits intomainfrom
cz/add-xapikey-env

Conversation

@Cristhianzl
Copy link
Member

@Cristhianzl Cristhianzl commented Nov 28, 2025

This pull request introduces a new configurable method for API key validation in Langflow, allowing users to choose between database-backed and environment variable-based authentication. The changes include updates to documentation, environment configuration, backend logic, and tests to support and describe this feature.

API Key Validation Configuration:

  • Added the LANGFLOW_API_KEY_SOURCE setting to .env.example to allow switching API key validation between database (db) and environment variable (env) modes. Also added LANGFLOW_API_KEY for environment-based authentication.

  • Updated documentation (api-keys-and-authentication.mdx) to explain the new LANGFLOW_API_KEY_SOURCE setting, usage scenarios, and configuration examples for Kubernetes and Docker Compose deployments. Added a comparison table for both validation methods. [1] [2]

Backend Logic:

  • Refactored API key validation in crud.py to support both database and environment variable methods, returning the superuser for environment-based authentication. [1] [2]

Settings and Tests:

  • Added API_KEY_SOURCE to the AuthSettings class, enforcing allowed values (db, env) and providing descriptive documentation.
  • Implemented comprehensive unit tests for the new setting, including validation, environment variable precedence, and error handling for invalid values. [1] [2]

Summary by CodeRabbit

  • New Features

    • Added environment variable-based API key authentication as an option alongside database validation
    • Enhanced file components with improved descriptions and content loading capabilities
  • Documentation

    • Extended API key authentication guide with configuration examples and deployment scenarios
  • Tests

    • Added comprehensive test suite for API key validation from both sources

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR adds environment-based API key validation as an alternative to database-backed validation, controlled via a new LANGFLOW_API_KEY_SOURCE configuration setting. It updates configuration examples, adds documentation, modifies CRUD logic to support both sources, and introduces comprehensive unit tests. Additionally, all starter project File components are updated to support dynamic tool descriptions and Docling-based processing with subprocess isolation.

Changes

Cohort / File(s) Summary
Configuration & Settings
.env.example, src/lfx/src/lfx/services/settings/auth.py
Added LANGFLOW_API_KEY_SOURCE configuration field (values: "db" or "env", default: "db") and corresponding environment variable with documentation of each validation mode.
Documentation
docs/docs/Develop/api-keys-and-authentication.mdx
Added comprehensive section documenting LANGFLOW_API_KEY_SOURCE including feature comparison table, usage examples, deployment configurations (Kubernetes, Docker Compose), security warnings, and step-by-step enablement instructions.
API Key CRUD Logic
src/backend/base/langflow/services/database/models/api_key/crud.py
Refactored check_key() to dispatch conditionally to _check_key_from_db() or _check_key_from_env() based on LANGFLOW_API_KEY_SOURCE setting; env-based validation checks against LANGFLOW_API_KEY environment variable and returns configured superuser.
Unit Tests
src/backend/tests/unit/test_api_key_source.py, src/backend/tests/unit/test_auth_settings.py
Added comprehensive test suites covering: routing logic by source, database validation with usage tracking, environment-based validation, settings validation with ValidationError handling, edge cases (empty keys, invalid sources, missing env vars, case sensitivity), and integration flows.
Starter Project File Components
src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json, Portfolio Website Code Generator.json, Text Sentiment Analysis.json, Vector Store RAG.json
Updated FileComponent in each starter project: added dynamic description property via get_tool_description(), introduced Docling-based subprocess processing (_process_docling_in_subprocess), added extensive new inputs/outputs/methods for advanced parsing and tool-based file reading, expanded dependency set (added langchain_core 0.3.79, pydantic 2.11.10), updated code hash.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant CRUD as API Key CRUD
    participant Settings as Settings Service
    participant DB as Database
    participant Env as Environment

    Client->>CRUD: check_key(api_key)
    CRUD->>Settings: Read API_KEY_SOURCE
    
    alt API_KEY_SOURCE = "db"
        CRUD->>DB: Query API key record
        DB-->>CRUD: User & API key record
        CRUD->>DB: Increment usage count (if tracking enabled)
        DB-->>CRUD: Success
        CRUD-->>Client: User object
    else API_KEY_SOURCE = "env"
        CRUD->>Env: Read LANGFLOW_API_KEY
        Env-->>CRUD: Environment value
        CRUD->>CRUD: Compare provided key with env var
        alt Keys match
            CRUD->>DB: Retrieve superuser
            DB-->>CRUD: Superuser record
            CRUD-->>Client: Superuser object
        else Keys don't match
            CRUD-->>Client: None (invalid)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Settings & Configuration Changes: Straightforward new field addition with validation
  • CRUD Logic: Clear conditional routing between two validation paths; well-structured with helper methods
  • Test Coverage: Comprehensive test suite with good edge case coverage; reduces review risk
  • Starter Project JSON Updates: Large files with repetitive pattern changes across four projects; requires spot-checking but follows consistent enhancement pattern
  • Areas requiring extra attention:
    • CRUD dispatch logic in check_key() to ensure both paths handle all edge cases correctly
    • Superuser resolution in _check_key_from_env() for potential None returns
    • Consistency of FileComponent changes across the four starter projects to verify they all received identical enhancements

Possibly related PRs

Suggested labels

authentication, configuration, documentation, backend

Suggested reviewers

  • erichare
  • ogabrielluiz
  • jordanrfrazier

Pre-merge checks and finishing touches

✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and concisely summarizes the main change: adding configurable API key validation with database or environment sources. It clearly conveys the primary objective without unnecessary details.
Docstring Coverage ✅ Passed Docstring coverage is 97.56% which is sufficient. The required threshold is 80.00%.
Test Quality And Coverage ✅ Passed Test suite provides comprehensive coverage with proper mocking, parametrization, and realistic assertions validating both success and error scenarios for API key validation functionality.
Test File Naming And Structure ✅ Passed Test files follow correct pytest patterns with proper naming, organization, structure, fixtures, async decorators, mocking, and comprehensive edge case coverage.
Excessive Mock Usage Warning ✅ Passed Test files demonstrate appropriate mock usage with 0.59 mocks per test across 34 tests, strategically targeting external dependencies while preserving real business logic validation.

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.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 28, 2025
@github-actions

This comment has been minimized.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 28, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 28, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 28, 2025

Build successful! ✅
Deploying docs draft.
Deploy successful! View draft

@github-actions
Copy link
Contributor

github-actions bot commented Nov 28, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 15%
15.43% (4244/27499) 8.61% (1811/21013) 9.69% (587/6057)

Unit Test Results

Tests Skipped Failures Errors Time
1671 0 💤 0 ❌ 0 🔥 21.608s ⏱️

@codecov
Copy link

codecov bot commented Nov 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 32.54%. Comparing base (7f07356) to head (e46de7e).
⚠️ Report is 3 commits behind head on main.

❌ Your project status has failed because the head coverage (39.99%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10783      +/-   ##
==========================================
+ Coverage   32.50%   32.54%   +0.04%     
==========================================
  Files        1370     1370              
  Lines       63494    63514      +20     
  Branches     9391     9391              
==========================================
+ Hits        20636    20668      +32     
+ Misses      41819    41806      -13     
- Partials     1039     1040       +1     
Flag Coverage Δ
backend 51.52% <100.00%> (+0.14%) ⬆️
frontend 14.28% <ø> (-0.01%) ⬇️
lfx 39.99% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../langflow/services/database/models/api_key/crud.py 93.44% <100.00%> (+25.14%) ⬆️
src/lfx/src/lfx/services/settings/auth.py 75.29% <100.00%> (+0.29%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 28, 2025
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: 3

Caution

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

⚠️ Outside diff range comments (8)
src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (4)

2418-2600: Subprocess command injection risk: Consider using list-based arguments instead of string script.

Lines 2449–2451 execute a subprocess with a child script passed via -c. While the file path validation at line 2436 provides basic protection, this approach is less safe than structured subprocess invocation. Even though validation checks for common shell metacharacters, the validation logic is basic and may not cover all injection vectors.

Recommendation: Use subprocess.run() with explicit argument lists or serialized JSON files instead of inline Python code passed via -c. This is more maintainable, testable, and secure.

# Current (risky):
proc = subprocess.run([sys.executable, "-u", "-c", child_script], ...)

# Better approach (example):
# Write child script to a temp file or use a proper subprocess library
# that handles argument marshalling securely

2436-2437: File path validation is incomplete; may not catch all injection patterns.

The validation at line 2436 checks for a fixed list of characters ([";", "|", "&", "$", ""]), but additional shell metacharacters (e.g., >, <, *, ?, (, ), ', ", \n`) could potentially be exploited. More robust validation is needed.

Recommendation: Use Path(args["file_path"]).resolve() to canonicalize and validate the path, or use a whitelist-based validation that ensures the path is within an allowed directory.

# Current (incomplete validation):
if not isinstance(args["file_path"], str) or any(c in args["file_path"] for c in [";", "|", "&", "$", "`"]):
    return Data(data={"error": "Unsafe file path detected.", "file_path": args["file_path"]})

# Better approach:
from pathlib import Path
try:
    safe_path = Path(args["file_path"]).resolve()
    # Optionally check if path is within allowed directories
    if not str(safe_path).startswith(str(allowed_base)):
        raise ValueError("Path outside allowed directory")
except Exception as e:
    return Data(data={"error": f"Invalid file path: {e}", "file_path": args["file_path"]})

2351-2382: Temporary file cleanup on S3 storage may silently fail; consider logging.

Lines 2351–2382 (_get_local_file_for_docling) download S3 files to temp files. The cleanup in finally block (line 2408) uses contextlib.suppress(Exception), which silently swallows all errors. This could leave orphaned temp files if the path is invalid or permissions are denied.

Recommendation: Log cleanup failures at DEBUG level to aid troubleshooting, and consider more explicit error handling.

# Current:
finally:
    if should_delete:
        with contextlib.suppress(Exception):
            Path(local_path).unlink()  # Ignore cleanup errors

# Better:
finally:
    if should_delete:
        try:
            Path(local_path).unlink()
        except Exception as e:
            self.log(f"Warning: Failed to clean up temp file {local_path}: {e}", level="debug")

2402-2406: Error handling in Docling conversion covers most cases, but consider adding timeout.

The Docling subprocess does not have a timeout parameter. If Docling hangs on a malformed or adversarial file, the entire component will block indefinitely.

Recommendation: Add a timeout to subprocess.run() to prevent indefinite hangs.

# Current:
proc = subprocess.run(
    [sys.executable, "-u", "-c", child_script],
    input=json.dumps(args).encode("utf-8"),
    capture_output=True,
    check=False,
)

# Better:
proc = subprocess.run(
    [sys.executable, "-u", "-c", child_script],
    input=json.dumps(args).encode("utf-8"),
    capture_output=True,
    check=False,
    timeout=300,  # 5-minute timeout; adjust as needed
)
src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (2)

1010-1215: Add timeout, output cap, and a constrained env to the Docling subprocess.

Long/hostile files can hang workers and exhaust memory. subprocess.run has no timeout or stdout bound; full env is inherited.

Apply something like:

-from lfx.utils.async_helpers import run_until_complete
+from lfx.utils.async_helpers import run_until_complete
+import os
+
+MAX_CHILD_STDOUT = 10 * 1024 * 1024  # 10MB cap
+CHILD_TIMEOUT_SECS = int(os.getenv("LF_DOCLING_TIMEOUT_SECS", "300"))

@@
-        proc = subprocess.run(  # noqa: S603
-            [sys.executable, "-u", "-c", child_script],
-            input=json.dumps(args).encode("utf-8"),
-            capture_output=True,
-            check=False,
-        )
+        env = {
+            "PATH": os.environ.get("PATH", ""),
+            "PYTHONPATH": "",  # avoid untrusted module injection
+            "LC_ALL": "C.UTF-8",
+            "LANG": "C.UTF-8",
+        }
+        proc = subprocess.run(  # noqa: S603
+            [sys.executable, "-u", "-c", child_script],
+            input=json.dumps(args).encode("utf-8"),
+            capture_output=True,
+            check=False,
+            timeout=CHILD_TIMEOUT_SECS,
+            env=env,
+        )
+        if proc.stdout and len(proc.stdout) > MAX_CHILD_STDOUT:
+            return Data(data={"error": "Docling output too large", "file_path": original_file_path})

1100-1145: Harden tool mode path handling (file_path_str).

Currently any resolved path is accepted; no extension/workspace guard. Prevent unintended local file reads.

-        if file_path_str:
+        if file_path_str:
             # Use the string path from tool mode
             from pathlib import Path
-
-            from lfx.schema.data import Data
+            from lfx.schema.data import Data
+            # Enforce extension allowlist and workspace root
+            allowed_exts = tuple(f".{ext.lower()}" for ext in self.VALID_EXTENSIONS)
+            if not file_path_str.lower().endswith(allowed_exts):
+                msg = f"Unsupported extension for tool path: {file_path_str}"
+                if not self.silent_errors:
+                    raise ValueError(msg)
+                self.log(msg)
+                return []
 
             resolved_path = Path(self.resolve_path(file_path_str))
             if not resolved_path.exists():
                 msg = f"File or directory not found: {file_path_str}"
                 self.log(msg)
                 if not self.silent_errors:
                     raise ValueError(msg)
                 return []
+            # Optional: ensure inside workspace
+            workspace = Path(self.resolve_path(".")).resolve()
+            if workspace not in resolved_path.resolve().parents and resolved_path.resolve() != workspace:
+                msg = "Access outside workspace is not allowed"
+                if not self.silent_errors:
+                    raise ValueError(msg)
+                self.log(msg)
+                return []
src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (2)

1286-1495: Same subprocess hardening needed here.

Apply the timeout/env/output-cap changes as in the Portfolio template to the subprocess.run call in this file’s FileComponent.


1250-1315: Harden file_path_str handling and workspace/extension checks.

Mirror the allowlist and workspace checks suggested in the other file.

🧹 Nitpick comments (11)
src/backend/base/langflow/services/database/models/api_key/crud.py (1)

81-102: Consider using constant-time comparison for API key validation.

While timing attacks are less critical for environment-based API keys than for password hashing, using secrets.compare_digest() for secret comparison is a security best practice that prevents potential timing attacks.

Apply this diff to use constant-time comparison:

+    import secrets
+
     env_api_key = os.getenv("LANGFLOW_API_KEY")
     if not env_api_key:
         return None
 
     # Compare the provided API key with the environment variable
-    if api_key != env_api_key:
+    if not secrets.compare_digest(api_key, env_api_key):
         return None
src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (3)

2754-2754: Unify extension gating to avoid drift.

TEXT_EXTENSIONS/DOCLING_ONLY_EXTENSIONS and _is_docling_compatible maintain overlapping lists (csv/json). Single source of truth reduces mismatches between UI gating and runtime.

Refactor:

-    def _is_docling_compatible(self, file_path: str) -> bool:
-        """Lightweight extension gate for Docling-compatible types."""
-        docling_exts = (
-            ".adoc",
-            ".asciidoc",
-            ".asc",
-            ".bmp",
-            ".csv",
-            ...
-        )
-        return file_path.lower().endswith(docling_exts)
+    def _is_docling_compatible(self, file_path: str) -> bool:
+        """Gate using VALID_EXTENSIONS; CSV/Parquet handled by UI toggles."""
+        return any(file_path.lower().endswith(f".{ext}") for ext in self.VALID_EXTENSIONS)

And ensure update_build_config uses the same VALID_EXTENSIONS-derived logic for showing advanced_mode.


2754-2754: Avoid logging full file paths at info level.

Current self.log(...) includes local/S3-resolved paths. Prefer debug and/or redact basename to reduce PII leakage in multi-tenant logs.

Minimal change:

-        self.log(f"Starting Docling subprocess for file: {local_file_path}")
+        self.debug(f"Starting Docling subprocess for file: {Path(local_file_path).name}")

2754-2754: Dynamic tool description is a nice UX win.

get_tool_description() and _get_tools() design look solid; zero-arg StructuredTool matches the flow.

Optional: cap returned string length (e.g., join first N filenames + “and X more”) for very large file lists.

src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (2)

2418-2420: Docling subprocess child script is complex and hard to test; consider extracting to a module.

The child script embedded in child_script (lines 2420+) is a large, multi-hundred-line Python string. This makes it difficult to:

  • Unit test in isolation
  • Debug and maintain
  • Reuse in other contexts

Recommendation: Extract the subprocess logic to a separate, standalone module that can be imported and tested independently.


2442-2448: Missing bounds check on concurrency parameter; could cause performance issues.

Line 2447 accepts self.concurrency_multithreading without upper bounds validation. If a user sets a very large value (e.g., 1000), it could spawn excessive threads and degrade system performance or cause resource exhaustion.

Recommendation: Clamp or validate the concurrency parameter to a sensible range (e.g., 1–32).

concurrency = max(1, min(self.concurrency_multithreading or 1, 32))
src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (2)

1122-1132: Avoid logging full args (leaks paths); log keys or redact.

self.log(args) can expose internal server paths in logs.

-        self.log(args)
+        self.log({k: ("<redacted>" if k == "file_path" else v) for k, v in args.items()})

1010-1215: Deduplicate FileComponent code shared across starter projects.

Same large component appears in multiple templates. Extract into a single Python component and reference it to reduce drift.

src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (3)

1420-1435: Don’t log full arg dict with paths.

Redact file_path before logging.


1510-1605: Advanced mode gating vs compatibility: verify UX.

update_build_config hides Advanced Parser for csv/xlsx/parquet, but _is_docling_compatible allows .csv/.xlsx. Confirm intended behavior or align both to avoid user confusion.

Would you like me to scan the codebase for other FileComponents and open a follow-up PR to align gating rules?


1188-1230: Component duplication across templates.

Consider centralizing FileComponent into a single source to avoid divergence.

📜 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 271c7ff and 0d51adf.

📒 Files selected for processing (10)
  • .env.example (1 hunks)
  • docs/docs/Develop/api-keys-and-authentication.mdx (2 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (3 hunks)
  • src/backend/base/langflow/services/database/models/api_key/crud.py (2 hunks)
  • src/backend/tests/unit/test_api_key_source.py (1 hunks)
  • src/backend/tests/unit/test_auth_settings.py (2 hunks)
  • src/lfx/src/lfx/services/settings/auth.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
src/backend/**/*.py

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

src/backend/**/*.py: Use FastAPI async patterns with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
  • src/backend/base/langflow/services/database/models/api_key/crud.py
src/backend/tests/**/*.py

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

src/backend/tests/**/*.py: Place backend unit tests in src/backend/tests/ directory, component tests in src/backend/tests/unit/components/ organized by component subdirectory, and integration tests accessible via make integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g., my_component.pytest_my_component.py)
Use the client fixture (FastAPI Test Client) defined in src/backend/tests/conftest.py for API tests; it provides an async httpx.AsyncClient with automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with @pytest.mark.noclient
Inherit from the correct ComponentTestBase family class located in src/backend/tests/base.py based on API access needs: ComponentTestBase (no API), ComponentTestBaseWithClient (needs API), or ComponentTestBaseWithoutClient (pure logic). Provide three required fixtures: component_class, default_kwargs, and file_names_mapping
Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Use @pytest.mark.asyncio decorator for async component tests and ensure async methods are properly awaited
Test background tasks using asyncio.create_task() and verify completion with asyncio.wait_for() with appropriate timeout constraints
Test queue operations using non-blocking queue.put_nowait() and asyncio.wait_for(queue.get(), timeout=...) to verify queue processing without blocking
Use @pytest.mark.no_blockbuster marker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially using uv run pytest src/backend/tests/unit/test_database.py r...

Files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (Custom checks)

Check that test files follow the project's naming conventions (test_*.py for backend, *.test.ts for frontend)

Files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
**/test_*.py

📄 CodeRabbit inference engine (Custom checks)

**/test_*.py: Backend tests should follow pytest structure with proper test_*.py naming
For async functions, ensure proper async testing patterns are used with pytest for backend

Files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
docs/docs/**/*.{md,mdx}

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

docs/docs/**/*.{md,mdx}: Markdown files must include YAML frontmatter with title, description, and sidebar_position
Use Docusaurus admonitions (:::tip, :::warning, :::danger) for important information, warnings, and critical alerts
Code blocks must include a title attribute and specify the language (e.g., ```python title="filename.py")
All images must use descriptive alt text that clearly explains what the image shows
Use sentence case for headers and proper capitalization for terminology: Langflow, Component, Flow, API, JSON
Use bold formatting for UI elements, italic for emphasis, and backticks for inline code
Use second person ('you') for instructions and present tense for current features in documentation content
Tables in documentation must include columns for Input/Output name, Type, Required (if applicable), and Description
Internal links between documentation pages must be functional and properly formatted using Docusaurus link syntax

Files:

  • docs/docs/Develop/api-keys-and-authentication.mdx
src/backend/base/langflow/services/database/models/**/*.py

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

Database models should be organized by domain (api_key/, flow/, folder/, user/, etc.) under src/backend/base/langflow/services/database/models/

Files:

  • src/backend/base/langflow/services/database/models/api_key/crud.py
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use `pytest.mark.api_key_required` and `pytest.mark.no_blockbuster` markers for components that need external APIs; use `MockLanguageModel` from `tests.unit.mock_language_model` for testing without external API keys
Learnt from: iann0036
Repo: langflow-ai/langflow PR: 9935
File: src/lfx/src/lfx/components/amazon/aws_api_call.py:35-48
Timestamp: 2025-09-21T09:46:44.276Z
Learning: Amazon components in the Langflow bundle consistently require explicit AWS credentials (aws_access_key_id and aws_secret_access_key with required=True) rather than falling back to environment/machine credentials for security reasons in hosted environments.
Learnt from: iann0036
Repo: langflow-ai/langflow PR: 9935
File: src/lfx/src/lfx/components/amazon/aws_api_call.py:35-48
Timestamp: 2025-09-21T09:46:44.276Z
Learning: Amazon components in the Langflow bundle consistently require explicit AWS credentials (aws_access_key_id and aws_secret_access_key with required=True) rather than falling back to environment/machine credentials for security reasons in hosted environments.
📚 Learning: 2025-09-21T09:46:44.276Z
Learnt from: iann0036
Repo: langflow-ai/langflow PR: 9935
File: src/lfx/src/lfx/components/amazon/aws_api_call.py:35-48
Timestamp: 2025-09-21T09:46:44.276Z
Learning: Amazon components in the Langflow bundle consistently require explicit AWS credentials (aws_access_key_id and aws_secret_access_key with required=True) rather than falling back to environment/machine credentials for security reasons in hosted environments.

Applied to files:

  • .env.example
  • docs/docs/Develop/api-keys-and-authentication.mdx
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use `pytest.mark.api_key_required` and `pytest.mark.no_blockbuster` markers for components that need external APIs; use `MockLanguageModel` from `tests.unit.mock_language_model` for testing without external API keys

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use `monkeypatch` fixture to mock internal functions for testing error handling scenarios; validate error status codes and error message content in responses

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-08-05T22:51:27.961Z
Learnt from: edwinjosechittilappilly
Repo: langflow-ai/langflow PR: 0
File: :0-0
Timestamp: 2025-08-05T22:51:27.961Z
Learning: The TestComposioComponentAuth test in src/backend/tests/unit/components/bundles/composio/test_base_composio.py demonstrates proper integration testing patterns for external API components, including real API calls with mocking for OAuth completion, comprehensive resource cleanup, and proper environment variable handling with pytest.skip() fallbacks.

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
  • src/backend/tests/unit/test_auth_settings.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use predefined JSON flows and utility functions from `tests.unit.build_utils` (create_flow, build_flow, get_build_events, consume_and_assert_stream) for flow execution testing

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to tests/**/*.py : Use `pytest.mark.api_key_required` and `pytest.mark.no_blockbuster` pytest markers for external API tests and blockbuster plugin tests

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow REST API endpoints using the `client` fixture with appropriate HTTP methods (GET, POST, etc.), headers (logged_in_headers), and payload validation

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Each test should have a clear docstring explaining its purpose; complex test setups should be commented; mock usage should be documented; expected behaviors should be explicitly stated

Applied to files:

  • src/backend/tests/unit/test_api_key_source.py
📚 Learning: 2025-10-29T03:55:50.216Z
Learnt from: ricofurtado
Repo: langflow-ai/langflow PR: 10430
File: src/backend/base/langflow/api/v2/registration.py:0-0
Timestamp: 2025-10-29T03:55:50.216Z
Learning: In the langflow project, user registration endpoints in API v2 (`src/backend/base/langflow/api/v2/registration.py`) are intentionally designed to be unauthenticated to support Desktop application initialization and onboarding flows.

Applied to files:

  • docs/docs/Develop/api-keys-and-authentication.mdx
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new components to the appropriate subdirectory under `src/backend/base/langflow/components/` (agents/, data/, embeddings/, input_output/, models/, processing/, prompts/, tools/, or vectorstores/)

Applied to files:

  • src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json
  • src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json
  • src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component versioning and backward compatibility using `file_names_mapping` fixture with `VersionComponentMapping` objects mapping component files across Langflow versions

Applied to files:

  • src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/services/database/models/**/*.py : Database models should be organized by domain (api_key/, flow/, folder/, user/, etc.) under `src/backend/base/langflow/services/database/models/`

Applied to files:

  • src/backend/base/langflow/services/database/models/api_key/crud.py
🧬 Code graph analysis (3)
src/backend/tests/unit/test_api_key_source.py (1)
src/backend/base/langflow/services/database/models/api_key/crud.py (3)
  • _check_key_from_db (67-78)
  • _check_key_from_env (81-102)
  • check_key (52-64)
src/backend/tests/unit/test_auth_settings.py (1)
src/lfx/src/lfx/services/settings/auth.py (1)
  • AuthSettings (14-143)
src/backend/base/langflow/services/database/models/api_key/crud.py (3)
src/backend/base/langflow/services/deps.py (1)
  • get_settings_service (120-133)
src/lfx/src/lfx/services/deps.py (1)
  • get_settings_service (86-90)
src/backend/base/langflow/services/database/models/user/crud.py (1)
  • get_user_by_username (14-16)
🪛 Gitleaks (8.29.1)
docs/docs/Develop/api-keys-and-authentication.mdx

[high] 330-333: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

⏰ 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). (59)
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 37/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 41/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 46/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 42/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 45/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 48/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 43/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 49/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 47/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 44/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 33/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 50/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 40/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 36/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 38/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 34/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 39/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 35/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 31/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 30/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 29/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 32/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 25/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 23/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 28/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 26/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 24/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 27/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 18/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 22/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 21/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 6/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 14/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 19/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 15/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 20/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 17/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 16/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 11/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 12/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 13/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 7/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 5/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 9/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 10/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 1/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 3/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 2/50
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: test-starter-projects

@Cristhianzl Cristhianzl requested a review from mendonk November 28, 2025 18:47
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 2, 2025
settings_service = get_settings_service()
api_key_source = settings_service.auth_settings.API_KEY_SOURCE

if api_key_source == "env":
Copy link
Collaborator

Choose a reason for hiding this comment

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

will there be any scenario where both of them are None? if yes, then what would be the fallback option?

Copy link
Member Author

Choose a reason for hiding this comment

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

nice catch! thank you :)

@github-actions github-actions bot added the enhancement New feature or request label Dec 2, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 2, 2025
…r more scenarios and improve reliability

- Add tests to verify routing to environment and database based on API_KEY_SOURCE.
- Implement fallback logic tests when environment validation fails.
- Ensure correct behavior when both environment and database validations fail.
- Refactor existing tests to improve clarity and coverage of edge cases.
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 2, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 2, 2025
@Cristhianzl Cristhianzl added this pull request to the merge queue Dec 3, 2025
github-merge-queue bot pushed a commit that referenced this pull request Dec 3, 2025
* add xapikey to env authentication

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* remove-docs-for-1.8-release

* add fallback to db

* [autofix.ci] apply automated fixes

* test(api_key_source.py): enhance tests for check_key function to cover more scenarios and improve reliability

- Add tests to verify routing to environment and database based on API_KEY_SOURCE.
- Implement fallback logic tests when environment validation fails.
- Ensure correct behavior when both environment and database validations fail.
- Refactor existing tests to improve clarity and coverage of edge cases.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 3, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 3, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 3, 2025
@Cristhianzl Cristhianzl enabled auto-merge December 3, 2025 17:01
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 3, 2025
@Cristhianzl Cristhianzl added this pull request to the merge queue Dec 3, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Dec 3, 2025
@Cristhianzl Cristhianzl added this pull request to the merge queue Dec 3, 2025
Merged via the queue into main with commit b05d0eb Dec 3, 2025
93 of 94 checks passed
@Cristhianzl Cristhianzl deleted the cz/add-xapikey-env branch December 3, 2025 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants