feat: Add asymmetric JWT authentication with RS256/RS512 support#10755
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Areas requiring attention:
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (5 passed)
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. Comment |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
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
titleattribute. 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_servesrc/backend/base/langflow/services/auth/utils.py (2)
368-380: Add validation for PRIVATE_KEY before signing.Unlike
get_current_user_by_jwtwhich validates the public key before use, this function doesn't validate thatPRIVATE_KEYis set before calling.get_secret_value(). If RS256/RS512 is configured but the private key is missing, this will raise anAttributeErrorrather 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 matchget_current_user_by_jwt.The
get_current_user_by_jwtfunction (lines 175-183) validates thatPUBLIC_KEYis 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
settingsvariable 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 nestedwithstatements and fix import ordering.Ruff flags nested
withstatements (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.asyncioinstead of deprecatedrun_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_usersrc/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_keywill 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_keyis 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 directwrite_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
⛔ Files ignored due to path filters (1)
docs/yarn.lockis 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 withawaitfor async operations in component execution methods
Useasyncio.create_task()for background tasks and implement proper cleanup with try/except forasyncio.CancelledError
Usequeue.put_nowait()for non-blocking queue operations andasyncio.wait_for()with timeouts for controlled get operations
Files:
src/backend/base/langflow/services/auth/utils.pysrc/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 insrc/backend/tests/directory, component tests insrc/backend/tests/unit/components/organized by component subdirectory, and integration tests accessible viamake integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g.,my_component.py→test_my_component.py)
Use theclientfixture (FastAPI Test Client) defined insrc/backend/tests/conftest.pyfor API tests; it provides an asynchttpx.AsyncClientwith automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with@pytest.mark.noclient
Inherit from the correctComponentTestBasefamily class located insrc/backend/tests/base.pybased on API access needs:ComponentTestBase(no API),ComponentTestBaseWithClient(needs API), orComponentTestBaseWithoutClient(pure logic). Provide three required fixtures:component_class,default_kwargs, andfile_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.asynciodecorator for async component tests and ensure async methods are properly awaited
Test background tasks usingasyncio.create_task()and verify completion withasyncio.wait_for()with appropriate timeout constraints
Test queue operations using non-blockingqueue.put_nowait()andasyncio.wait_for(queue.get(), timeout=...)to verify queue processing without blocking
Use@pytest.mark.no_blockbustermarker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially usinguv run pytest src/backend/tests/unit/test_database.pyr...
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
Makefiletargets to coordinate build and development tasks likemake backend,make format_backend,make lint, andmake 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:
SecretStrfor the private key to prevent accidental exposure, and plainstrfor 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.
This comment has been minimized.
This comment has been minimized.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This comment has been minimized.
This comment has been minimized.
| algorithm = settings_service.auth_settings.ALGORITHM | ||
|
|
||
| # Use appropriate key based on algorithm | ||
| if algorithm.is_asymmetric(): |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Thanks @Jkavia good catch! I've refactored this to extract the repeated logic into two helper functions.
Adam-Aghili
left a comment
There was a problem hiding this comment.
LGTM!
But id still like other eyes on this
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:
AuthSettings, including new fields forPRIVATE_KEYandPUBLIC_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]src/backend/base/langflow/services/auth/utils.py) [1] [2] [3]Documentation improvements:
yarn, and updated help output to include documentation commands. (Makefile) [1] [2] [3]docs/sidebars.js)Summary by CodeRabbit
Release Notes
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.