Skip to content

feat: Add asymmetric JWT authentication with RS256/RS512 support#10755

Merged
Cristhianzl merged 64 commits into
mainfrom
cz/algorithm-signin
Jan 6, 2026
Merged

feat: Add asymmetric JWT authentication with RS256/RS512 support#10755
Cristhianzl merged 64 commits into
mainfrom
cz/algorithm-signin

Conversation

@Cristhianzl
Copy link
Copy Markdown
Member

@Cristhianzl Cristhianzl commented Nov 27, 2025

This pull request introduces support for asymmetric JWT authentication using RS256/RS512 algorithms, in addition to the existing HS256 support. It adds new configuration options for RSA private and public keys, automates key generation and management, and updates authentication logic to handle both symmetric and asymmetric signing. Additionally, it improves documentation setup and adds a sidebar entry for JWT authentication documentation.

Authentication and JWT enhancements:

  • Added support for RS256/RS512 JWT algorithms in AuthSettings, including new fields for PRIVATE_KEY and PUBLIC_KEY, with logic to generate, load, and persist RSA key pairs automatically if not provided. (src/lfx/src/lfx/services/settings/auth.py, src/lfx/src/lfx/services/settings/utils.py) [1] [2] [3]
  • Updated JWT token creation and verification logic to use the appropriate key (RSA or secret) based on the selected algorithm, ensuring compatibility with both symmetric and asymmetric authentication. (src/backend/base/langflow/services/auth/utils.py) [1] [2] [3]

Documentation improvements:

  • Added new Makefile targets to install, build, and serve documentation, including a check for the presence of yarn, and updated help output to include documentation commands. (Makefile) [1] [2] [3]
  • Added a sidebar entry for JWT authentication documentation in the docs site. (docs/sidebars.js)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for RS256 and RS512 JWT signing algorithms in addition to HS256, enabling asymmetric key-based authentication configurations.
    • Implemented automatic RSA key generation and management for secure deployments.
  • Documentation

    • New comprehensive JWT authentication deployment guide including algorithm comparisons, environment configuration, Docker and Kubernetes examples, and security best practices.
  • Chores

    • Added documentation development workflow to build system.

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

@Cristhianzl Cristhianzl self-assigned this Nov 27, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 27, 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 extends JWT authentication to support RSA-based algorithms (RS256, RS512) alongside HMAC-based HS256. Changes include RSA key management in AuthSettings with automatic generation/loading, algorithm-dependent key selection in token creation/verification, comprehensive unit tests, and deployment documentation with configuration guidance.

Changes

Cohort / File(s) Change Summary
Documentation & Build System
Makefile, docs/sidebars.js, docs/docs/Deployment/deployment-jwt-authentication.mdx
Adds documentation development infrastructure (docs_port variable, docs_install/docs_build/docs_serve targets) and introduces new JWT authentication deployment guide covering algorithm selection, key management, security practices, and troubleshooting.
Core Auth Logic
src/backend/base/langflow/services/auth/utils.py
Replaces hardcoded SECRET_KEY/algorithm with algorithm-based key selection: RS256/RS512 use PUBLIC_KEY/PRIVATE_KEY; others use SECRET_KEY. Updates JWT decode/encode and refresh-token flows with proper key and algorithm variables.
Auth Settings & Key Management
src/lfx/src/lfx/services/settings/auth.py, src/lfx/src/lfx/services/settings/utils.py
Adds PRIVATE_KEY and PUBLIC_KEY fields to AuthSettings, expands ALGORITHM to support HS256/RS256/RS512, implements model_validator for automatic RSA key generation/loading with filesystem or in-memory storage, and introduces generate_rsa_key_pair() utility function.
Test Coverage
src/backend/tests/unit/test_auth_jwt_algorithms.py
Adds comprehensive unit tests for JWT algorithm support covering AuthSettings initialization, RSA key persistence, token creation/verification across algorithms, refresh-token handling, algorithm mismatches, and error conditions.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application Startup
    participant AuthSettings as AuthSettings
    participant Utils as Key Utils
    participant FS as Filesystem
    participant TokenSvc as Token Service

    App->>AuthSettings: Initialize with ALGORITHM
    activate AuthSettings
    alt Algorithm is RS256/RS512
        alt CONFIG_DIR exists
            AuthSettings->>FS: Check for private_key file
            FS-->>AuthSettings: Key found or not
            alt Key not found
                AuthSettings->>Utils: generate_rsa_key_pair()
                Utils-->>AuthSettings: (private_key_pem, public_key_pem)
                AuthSettings->>FS: Save keys to files
            else Key found
                AuthSettings->>FS: Load private_key and public_key
            end
        else No CONFIG_DIR
            AuthSettings->>Utils: generate_rsa_key_pair()
            Utils-->>AuthSettings: (private_key_pem, public_key_pem)
            Note over AuthSettings: Keys stored in-memory
        end
        Note over AuthSettings: PRIVATE_KEY and PUBLIC_KEY set
    else Algorithm is HS256
        Note over AuthSettings: Use SECRET_KEY only
    end
    deactivate AuthSettings
    AuthSettings-->>App: Ready

    App->>TokenSvc: create_token(user_id)
    activate TokenSvc
    alt Algorithm is RS256/RS512
        TokenSvc->>TokenSvc: Select PRIVATE_KEY for signing
    else
        TokenSvc->>TokenSvc: Select SECRET_KEY for signing
    end
    TokenSvc-->>App: JWT token
    deactivate TokenSvc

    App->>TokenSvc: verify_token(jwt_token)
    activate TokenSvc
    alt Algorithm is RS256/RS512
        TokenSvc->>TokenSvc: Select PUBLIC_KEY for verification
    else
        TokenSvc->>TokenSvc: Select SECRET_KEY for verification
    end
    TokenSvc-->>App: Verified payload or error
    deactivate TokenSvc
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring attention:

  • RSA key generation, derivation, and filesystem persistence logic in AuthSettings.setup_rsa_keys() validator—verify correct handling of all initialization paths (in-memory, filesystem, derived public keys)
  • Algorithm-based key selection branching in src/backend/base/langflow/services/auth/utils.py for token creation and verification—ensure correct key/algorithm pairing for each algorithm type
  • Error handling for missing keys (HTTP 401, WWW-Authenticate header compliance) across token validation flows
  • Test coverage adequacy for edge cases (empty config directories, key derivation failures, algorithm mismatches, long user IDs)

Suggested labels

documentation, size:XL, lgtm

Suggested reviewers

  • ogabrielluiz
  • jordanrfrazier
  • mendonk

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Test Quality And Coverage ⚠️ Warning Test file has solid coverage of JWT algorithms and token operations, but contains critical code quality issues preventing Ruff pipeline validation. Fix Yoda conditions at lines 104-105 and 122; import JWTError from jose.exceptions; replace Exception with JWTError in pytest.raises at lines 685-686 and 705-706.
Test File Naming And Structure ⚠️ Warning Test file has unresolved code quality issues: Yoda conditions at lines 105 and 122, and bare Exception catches at lines 685 and 705 that should be JWTError. Fix Yoda conditions by reversing assertion order and replace bare except Exception with except JWTError at lines 685 and 705.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Add asymmetric JWT authentication with RS256/RS512 support' directly and specifically describes the main change: adding RS256/RS512 asymmetric JWT support to the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
Test Coverage For New Implementations ✅ Passed PR includes comprehensive test coverage with 39+ test methods across 9 test classes covering all new implementations.
Excessive Mock Usage Warning ✅ Passed Mock usage is justified for external dependencies like database queries and user lookups in verify_token_async tests; pure functions tested with real implementations.

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 the enhancement New feature or request label Nov 27, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 27, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 27, 2025
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
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

🧹 Nitpick comments (10)
docs/docs/Deployment/deployment-jwt-authentication.mdx (1)

168-178: Add title attributes to code blocks.

Per documentation guidelines, code blocks should include a title attribute. Consider adding titles to key configuration examples throughout the document.

-```bash
+```bash title="HS256 Configuration"
 # The secret key will be automatically generated and persisted
 export LANGFLOW_ALGORITHM="HS256"

Apply similar changes to other significant code blocks (Docker compose files, Kubernetes manifests, key generation commands).

</blockquote></details>
<details>
<summary>Makefile (1)</summary><blockquote>

`1-1`: **Add `docs_serve` to `.PHONY` declaration.**

The `docs_serve` target is missing from the `.PHONY` declaration, though `docs`, `docs_build`, and `docs_install` are included.



```diff
-.PHONY: all init format_backend format lint build run_backend dev help tests coverage clean_python_cache clean_npm_cache clean_frontend_build clean_all run_clic load_test_setup load_test_setup_basic load_test_list_flows load_test_run load_test_langflow_quick load_test_stress load_test_example load_test_clean load_test_remote_setup load_test_remote_run load_test_help docs docs_build docs_install
+.PHONY: all init format_backend format lint build run_backend dev help tests coverage clean_python_cache clean_npm_cache clean_frontend_build clean_all run_clic load_test_setup load_test_setup_basic load_test_list_flows load_test_run load_test_langflow_quick load_test_stress load_test_example load_test_clean load_test_remote_setup load_test_remote_run load_test_help docs docs_build docs_install docs_serve
src/backend/base/langflow/services/auth/utils.py (2)

368-380: Add validation for PRIVATE_KEY before signing.

Unlike get_current_user_by_jwt which validates the public key before use, this function doesn't validate that PRIVATE_KEY is set before calling .get_secret_value(). If RS256/RS512 is configured but the private key is missing, this will raise an AttributeError rather than a clear authentication configuration error.

     # Use appropriate key based on algorithm
     if algorithm in ("RS256", "RS512"):
+        if not settings_service.auth_settings.PRIVATE_KEY:
+            msg = "Private key is not configured for RS256/RS512 signing"
+            raise ValueError(msg)
         signing_key = settings_service.auth_settings.PRIVATE_KEY.get_secret_value()
     else:
         signing_key = settings_service.auth_settings.SECRET_KEY.get_secret_value()

496-512: Add validation for PUBLIC_KEY to match get_current_user_by_jwt.

The get_current_user_by_jwt function (lines 175-183) validates that PUBLIC_KEY is set before using it, but this function doesn't. Consider adding consistent validation here.

     # Use appropriate key based on algorithm
     if algorithm in ("RS256", "RS512"):
         verification_key = settings_service.auth_settings.PUBLIC_KEY
+        if not verification_key:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail="Authentication failure: Verify authentication settings.",
+            )
     else:
         verification_key = settings_service.auth_settings.SECRET_KEY.get_secret_value()
src/backend/tests/unit/test_auth_jwt_algorithms.py (4)

138-146: Remove unused variable assignment.

The settings variable is assigned but never used, which triggers Ruff F841.

 def test_hs256_does_not_generate_rsa_keys(self):
     """HS256 should not trigger RSA key generation."""
     from lfx.services.settings.auth import AuthSettings

     with tempfile.TemporaryDirectory() as tmpdir:
-        settings = AuthSettings(CONFIG_DIR=tmpdir, ALGORITHM="HS256")
+        AuthSettings(CONFIG_DIR=tmpdir, ALGORITHM="HS256")

         private_key_path = Path(tmpdir) / "private_key.pem"

148-156: Combine nested with statements and fix import ordering.

Ruff flags nested with statements (SIM117) and unsorted imports (I001).

 def test_invalid_algorithm_rejected(self):
     """Invalid algorithm should be rejected by pydantic."""
-    from pydantic import ValidationError
-
     from lfx.services.settings.auth import AuthSettings
+    from pydantic import ValidationError

-    with tempfile.TemporaryDirectory() as tmpdir:
-        with pytest.raises(ValidationError):
+    with tempfile.TemporaryDirectory() as tmpdir, pytest.raises(ValidationError):
             AuthSettings(CONFIG_DIR=tmpdir, ALGORITHM="INVALID")

494-496: Break long line to satisfy line length limit.

Line exceeds 120 characters. Consider splitting it.

-                # jose library raises JWTError for expired tokens before our custom check
-                assert "expired" in exc_info.value.detail.lower() or "could not validate" in exc_info.value.detail.lower()
+                # jose library raises JWTError for expired tokens before our custom check
+                detail_lower = exc_info.value.detail.lower()
+                assert "expired" in detail_lower or "could not validate" in detail_lower

769-805: Use @pytest.mark.asyncio instead of deprecated run_until_complete.

Using asyncio.get_event_loop().run_until_complete() is deprecated. Since other tests in this file properly use @pytest.mark.asyncio, this test should follow the same pattern for consistency.

+    @pytest.mark.asyncio
-    def test_token_with_extra_claims(self):
+    async def test_token_with_extra_claims(self):
         """Token with extra claims should still work."""
         from langflow.services.auth.utils import get_current_user_by_jwt
         # ... setup code ...

         with (
             patch("langflow.services.auth.utils.get_settings_service", return_value=mock_service),
             patch("langflow.services.auth.utils.get_user_by_id", return_value=mock_user),
         ):
-            import asyncio
-
-            user = asyncio.get_event_loop().run_until_complete(get_current_user_by_jwt(token, mock_db))
+            user = await get_current_user_by_jwt(token, mock_db)
             assert user == mock_user
src/lfx/src/lfx/services/settings/auth.py (2)

163-173: Add error handling for invalid private key format.

If an invalid private key is provided, load_pem_private_key will raise an exception (ValueError/TypeError) that propagates up without a helpful error message. Consider wrapping this in a try/except to provide clearer guidance.

             elif not self.PUBLIC_KEY:
                 # Derive public key from private key
                 from cryptography.hazmat.primitives import serialization
                 from cryptography.hazmat.primitives.serialization import load_pem_private_key

-                private_key = load_pem_private_key(private_key_value.encode(), password=None)
+                try:
+                    private_key = load_pem_private_key(private_key_value.encode(), password=None)
+                except (ValueError, TypeError) as e:
+                    msg = f"Invalid RSA private key format: {e}"
+                    raise ValueError(msg) from e
                 public_key_pem = private_key.public_key().public_bytes(

Apply similar error handling at lines 188 and 210 where load_pem_private_key is called.


194-194: Consider consistent file writing approach.

The private key uses write_secret_to_file (which sets secure permissions), while the public key uses direct write_text. This is acceptable since public keys don't need protection, but for consistency in error handling and encoding, you might consider a utility function or adding a brief comment explaining the intentional difference.

Also applies to: 216-216, 222-222

📜 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 0ddfed3 and 973f65a.

⛔ Files ignored due to path filters (1)
  • docs/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • Makefile (3 hunks)
  • docs/docs/Deployment/deployment-jwt-authentication.mdx (1 hunks)
  • docs/sidebars.js (1 hunks)
  • src/backend/base/langflow/services/auth/utils.py (3 hunks)
  • src/backend/tests/unit/test_auth_jwt_algorithms.py (1 hunks)
  • src/lfx/src/lfx/services/settings/auth.py (2 hunks)
  • src/lfx/src/lfx/services/settings/utils.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
docs/sidebars.js

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

Sidebar configuration in sidebars.js must use category types to organize documentation into logical sections

Files:

  • docs/sidebars.js
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/base/langflow/services/auth/utils.py
  • src/backend/tests/unit/test_auth_jwt_algorithms.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/Deployment/deployment-jwt-authentication.mdx
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_auth_jwt_algorithms.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

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

Files:

  • src/backend/tests/unit/test_auth_jwt_algorithms.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/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_auth_jwt_algorithms.py
Makefile

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

Update Makefile targets to coordinate build and development tasks like make backend, make format_backend, make lint, and make unit_tests

Files:

  • Makefile
🧠 Learnings (12)
📚 Learning: 2025-11-24T19:46:26.770Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/docs_development.mdc:0-0
Timestamp: 2025-11-24T19:46:26.770Z
Learning: Applies to docs/sidebars.js : Sidebar configuration in sidebars.js must use category types to organize documentation into logical sections

Applied to files:

  • docs/sidebars.js
📚 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_auth_jwt_algorithms.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 Makefile : Update `Makefile` targets to coordinate build and development tasks like `make backend`, `make format_backend`, `make lint`, and `make unit_tests`

Applied to files:

  • Makefile
📚 Learning: 2025-11-24T19:46:26.770Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/docs_development.mdc:0-0
Timestamp: 2025-11-24T19:46:26.770Z
Learning: Documentation must be tested by running yarn build and yarn serve to check for broken links and content accuracy

Applied to files:

  • Makefile
📚 Learning: 2025-06-23T12:46:29.953Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/docs_development.mdc:0-0
Timestamp: 2025-06-23T12:46:29.953Z
Learning: The documentation site is built and served locally using 'yarn build' and 'yarn serve', and is automatically deployed on commit to the main branch.

Applied to files:

  • Makefile
📚 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: Organize backend test files by running `make unit_tests` for all unit tests, `make integration_tests` for integration tests, `make coverage` for coverage reports, and `make tests_frontend` for frontend tests

Applied to files:

  • Makefile
📚 Learning: 2025-11-24T19:47:40.400Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2025-11-24T19:47:40.400Z
Learning: Applies to **/*.{test.ts,test.tsx,spec.ts,spec.tsx,test_*.py} : Ensure tests follow the project's testing patterns (pytest for backend, Playwright for frontend)

Applied to files:

  • Makefile
📚 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:

  • Makefile
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Run make format_frontend before committing to format TypeScript/JavaScript code

Applied to files:

  • Makefile
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-23T12:46:42.048Z
Learning: Frontend code must be formatted using the make format_frontend command and linted with make lint before committing changes.

Applied to files:

  • Makefile
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Hot-reload frontend changes during development with the make frontend command

Applied to files:

  • Makefile
📚 Learning: 2025-11-24T19:46:26.770Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/docs_development.mdc:0-0
Timestamp: 2025-11-24T19:46:26.770Z
Learning: Node.js v22.12 LTS and Yarn package manager must be used for documentation environment setup

Applied to files:

  • Makefile
🧬 Code graph analysis (1)
src/lfx/src/lfx/services/settings/auth.py (1)
src/lfx/src/lfx/services/settings/utils.py (3)
  • generate_rsa_key_pair (10-32)
  • read_secret_from_file (67-68)
  • write_secret_to_file (59-64)
🪛 ast-grep (0.40.0)
src/backend/tests/unit/test_auth_jwt_algorithms.py

[warning] 459-463: Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables).
Context: wrong_token = jwt.encode(
{"sub": "user-123", "type": "access"},
"different-secret-key",
algorithm="HS256",
)
Note: [CWE-522] Insufficiently Protected Credentials. [REFERENCES]
- https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/

(jwt-python-hardcoded-secret-python)


[warning] 459-463: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. Use environment variables to securely provide credentials and other secrets or retrieve them from a secure vault or Hardware Security Module (HSM).
Context: jwt.encode(
{"sub": "user-123", "type": "access"},
"different-secret-key",
algorithm="HS256",
)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A01:2021]: Identification and Authentication Failures [REFERENCES]
https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html

(python-pyjwt-hardcoded-secret-python)

🪛 checkmake (0.2.2)
Makefile

[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

🪛 GitHub Actions: Ruff Style Check
src/backend/tests/unit/test_auth_jwt_algorithms.py

[error] 105-105: Ruff SIM300: Yoda condition detected. Command: 'uv run --only-dev ruff check --output-format=github .'

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

[failure] 705-705: Ruff (B017)
src/backend/tests/unit/test_auth_jwt_algorithms.py:705:18: B017 Do not assert blind exception: Exception


[failure] 685-685: Ruff (PT011)
src/backend/tests/unit/test_auth_jwt_algorithms.py:685:32: PT011 pytest.raises(Exception) is too broad, set the match parameter or use a more specific exception


[failure] 685-685: Ruff (B017)
src/backend/tests/unit/test_auth_jwt_algorithms.py:685:18: B017 Do not assert blind exception: Exception


[failure] 640-640: Ruff (S105)
src/backend/tests/unit/test_auth_jwt_algorithms.py:640:52: S105 Possible hardcoded password assigned to: "token_type"


[failure] 495-495: Ruff (E501)
src/backend/tests/unit/test_auth_jwt_algorithms.py:495:121: E501 Line too long (122 > 120)


[failure] 154-155: Ruff (SIM117)
src/backend/tests/unit/test_auth_jwt_algorithms.py:154:9: SIM117 Use a single with statement with multiple contexts instead of nested with statements


[failure] 150-152: Ruff (I001)
src/backend/tests/unit/test_auth_jwt_algorithms.py:150:9: I001 Import block is un-sorted or un-formatted


[failure] 139-139: Ruff (F841)
src/backend/tests/unit/test_auth_jwt_algorithms.py:139:13: F841 Local variable settings is assigned to but never used


[failure] 122-122: Ruff (SIM300)
src/backend/tests/unit/test_auth_jwt_algorithms.py:122:20: SIM300 Yoda condition detected


[failure] 105-105: Ruff (SIM300)
src/backend/tests/unit/test_auth_jwt_algorithms.py:105:20: SIM300 Yoda condition detected

🪛 Gitleaks (8.29.1)
docs/docs/Deployment/deployment-jwt-authentication.mdx

[high] 219-229: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)


[high] 267-359: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)

src/backend/tests/unit/test_auth_jwt_algorithms.py

[high] 56-71: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)


[high] 132-168: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)

⏰ 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). (33)
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 10/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 17/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 16/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 15/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 9/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 14/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 13/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 11/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 5/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 3/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 7/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 6/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 12/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 2/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/17
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 1/17
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Test Docs Build / Test Docs Build
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • 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 / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: build-and-deploy
  • GitHub Check: Update Component Index
  • GitHub Check: Optimize new Python code in this PR
🔇 Additional comments (7)
src/lfx/src/lfx/services/settings/utils.py (1)

10-32: LGTM! Clean RSA key generation implementation.

The implementation correctly uses standard parameters (public exponent 65537, 2048-bit key size) and proper PEM serialization formats. One minor note: the docstring mentions "RS256" specifically, but this function works equally well for RS512 since both use RSA keys.

docs/sidebars.js (1)

253-257: LGTM!

The sidebar entry correctly follows the existing pattern and is appropriately placed within the Deploy category before the Security documentation.

Makefile (1)

998-1029: LGTM! Well-structured documentation targets.

The documentation workflow is well-organized with proper dependency chaining, configurable port, and helpful error messages when yarn is missing. This aligns with the project's documentation development requirements.

src/backend/base/langflow/services/auth/utils.py (1)

172-197: LGTM! Proper algorithm-based key selection for JWT verification.

The implementation correctly selects the verification key based on the configured algorithm (PUBLIC_KEY for RS256/RS512, SECRET_KEY for HS256) with appropriate error handling and WWW-Authenticate headers.

src/backend/tests/unit/test_auth_jwt_algorithms.py (1)

1-9: Comprehensive test coverage for JWT algorithm support.

The test suite provides thorough coverage across all algorithms (HS256, RS256, RS512), including key generation, token lifecycle, error scenarios, and edge cases. The structure is well-organized with clear separation of concerns.

src/lfx/src/lfx/services/settings/auth.py (2)

22-34: Well-structured field definitions for RSA support.

The field types are appropriate: SecretStr for the private key to prevent accidental exposure, and plain str for the public key since it's meant to be shared. The algorithm literal properly restricts valid values.


147-227: RSA key management logic is well-structured.

The validator properly handles all key management scenarios:

  • In-memory generation when no CONFIG_DIR
  • Key derivation when only private key is provided
  • File-based persistence with proper loading/saving
  • Automatic key pair generation when nothing is provided

The use of object.__setattr__ is appropriate for modifying frozen pydantic fields within a validator.

Comment thread docs/docs/Deployment/deployment-jwt-authentication.mdx Outdated
Comment thread src/backend/tests/unit/test_auth_jwt_algorithms.py Outdated
Comment thread src/backend/tests/unit/test_auth_jwt_algorithms.py Outdated
@Cristhianzl Cristhianzl requested a review from mendonk November 27, 2025 13:51
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 27, 2025
@github-actions

This comment has been minimized.

@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 27, 2025

Codecov Report

❌ Patch coverage is 48.18182% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 33.38%. Comparing base (fdc1b3b) to head (64cfbf4).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/lfx/src/lfx/services/settings/auth.py 27.27% 39 Missing and 1 partial ⚠️
src/lfx/src/lfx/services/settings/utils.py 29.16% 17 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10755      +/-   ##
==========================================
+ Coverage   33.36%   33.38%   +0.01%     
==========================================
  Files        1399     1399              
  Lines       66229    66331     +102     
  Branches     9785     9794       +9     
==========================================
+ Hits        22100    22142      +42     
- Misses      43005    43064      +59     
- Partials     1124     1125       +1     
Flag Coverage Δ
backend 52.92% <100.00%> (+0.05%) ⬆️
frontend 15.35% <ø> (ø)
lfx 39.47% <27.84%> (-0.06%) ⬇️

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

Files with missing lines Coverage Δ
src/backend/base/langflow/services/auth/utils.py 65.31% <100.00%> (+5.63%) ⬆️
src/lfx/src/lfx/services/settings/utils.py 34.69% <29.16%> (-5.31%) ⬇️
src/lfx/src/lfx/services/settings/auth.py 55.14% <27.27%> (-19.86%) ⬇️

... and 4 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 27, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 27, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 27, 2025
@github-actions

This comment has been minimized.

@github-actions github-actions Bot removed the enhancement New feature or request label Dec 15, 2025
@github-actions github-actions Bot added the enhancement New feature or request label Dec 15, 2025
Comment thread src/backend/base/langflow/services/auth/utils.py Outdated
Comment thread src/backend/base/langflow/services/auth/utils.py Outdated
algorithm = settings_service.auth_settings.ALGORITHM

# Use appropriate key based on algorithm
if algorithm.is_asymmetric():
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I noticed this check is repeated in a few places would it make sense to extract it into a helper function and call it wherever we need to determine the algorithm type? Not sure if there’s a reason it was done this way.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks @Jkavia good catch! I've refactored this to extract the repeated logic into two helper functions.

Copy link
Copy Markdown
Collaborator

@Jkavia Jkavia left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@Adam-Aghili Adam-Aghili left a comment

Choose a reason for hiding this comment

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

LGTM!

But id still like other eyes on this

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

Labels

enhancement New feature or request fast-track Skip tests and sends PR into the merge queue lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants