Skip to content

refactor: streamline required scopes handling in GoogleDriveOAuth and add test for optional group scopes#1716

Closed
ricofurtado wants to merge 4 commits into
mainfrom
returning-only-required-scopes-for-google-drive-connector
Closed

refactor: streamline required scopes handling in GoogleDriveOAuth and add test for optional group scopes#1716
ricofurtado wants to merge 4 commits into
mainfrom
returning-only-required-scopes-for-google-drive-connector

Conversation

@ricofurtado
Copy link
Copy Markdown
Collaborator

@ricofurtado ricofurtado commented Jun 1, 2026

Google Drive OAuth was requesting Drive scopes plus optional Google Workspace group/admin scopes, then treating all of them as required. If Google withheld either optional scope, the OAuth callback could succeed, but the next connector status check would reject/delete the token and show Google Drive as not connected. That matches your symptom: consent flow completes, but ingestion/file selection never becomes enabled.

Summary by CodeRabbit

  • Bug Fixes

    • Google Drive auth now distinguishes required vs optional scopes to reduce unnecessary re-authentication.
  • New Features

    • Updated flow: calculator now safely evaluates arithmetic expressions with clearer numeric results and structured error messages.
    • Flow UI: model selection options trimmed to a smaller, focused set.
  • Chores

    • Updated base image for the Langflow-related container.
  • Tests

    • Added tests for Google Drive credential handling and ingest token signing behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Walkthrough

This PR adds a REQUIRED_SCOPES constant and narrows Google Drive credential scope checks, enables asymmetric JWT signing for Langflow ingest tokens with updated creation/validation, refactors OpenSearch onboarding/startup to select credentials by run mode with per-call getters, updates Langflow flow JSON (nodes, model options, Calculator code), and bumps a Docker base image.

Changes

Google Drive OAuth Scope Refactor

Layer / File(s) Summary
Scope Constants and Validation Logic
src/connectors/google_drive/oauth.py
Introduce REQUIRED_SCOPES for Drive permissions, rebuild SCOPES to include OpenID/profile + REQUIRED_SCOPES, and change _missing_required_scopes() to validate against REQUIRED_SCOPES only.
Test for Optional Scope Loading
tests/unit/test_oauth_encryption.py
Add async unit test ensuring GoogleDriveOAuth.load_credentials() accepts tokens that include REQUIRED_SCOPES while optional group scopes may be absent.

Langflow Ingest Token Service

Layer / File(s) Summary
Key resolution and constructor wiring
src/services/langflow_ingest_token_service.py
Add _resolve_default_signing_config() to load a PEM private key and derive the verification key and JWT algorithm; constructor sets internal signing/verification keys and algorithm when secret not provided.
Sign / validate / revoke behavior changes
src/services/langflow_ingest_token_service.py
JWT creation signs with internal _signing_key; validate_token and revoke_token now verify with _verification_key instead of using a single shared secret.
Unit test for signing-key preference
tests/unit/test_langflow_ingest_callback.py
Add test confirming tokens minted from JWT_SIGNING_KEY validate under default service and fail when only SESSION_SECRET is used.

OpenSearch Run-Mode and Bootstrap

Layer / File(s) Summary
Per-call OpenSearch credential accessors
src/config/settings.py
Add get_opensearch_username() and get_opensearch_password() to read credentials at call time from the environment/config.
Onboarding: mode-specific admin/client selection
src/api/settings/endpoints.py
Refactor onboarding to select admin identity and OpenSearch client per run mode: SaaS prefers platform service token with fallback to onboarding JWT or unauthenticated client; on_prem/oss use basic auth with admin username/password.
Lifespan startup bootstrap wiring
src/app/lifespan.py, src/config/settings.py
Startup now imports username/password getters and selects bootstrap path per run mode, computing admin identity per mode before calling OpenSearch wait/setup helpers; AppClients.initialize() chooses writer client auth by run mode (service token, unauthenticated, or basic auth).

Langflow Flow JSON Updates

Layer / File(s) Summary
Edge/node metadata and timestamps
flows/openrag_agent.json
Update edge presentation fields, frontend folder ids, last_updated timestamps, viewport/last_tested_version, and related serialized metadata across nodes.
Model option pruning
flows/openrag_agent.json
Prune Agent/Embedding Model UI model option entries to a reduced selection.
Calculator component code and metadata
flows/openrag_agent.json
Update Calculator metadata/dependencies and replace embedded code with an AST-based expression evaluator; remove obsolete is_refresh entry.

Miscellaneous

Layer / File(s) Summary
Dockerfile base image bump
Dockerfile.langflow
Bump base image to langflowai/langflow:1.9.6.rc0.

Sequence Diagram(s)

sequenceDiagram
  participant OnboardingEndpoint
  participant PlatformServiceToken
  participant OpenSearchClient
  participant AdminIdentity
  participant SetupOpenSearchSecurity

  OnboardingEndpoint->>PlatformServiceToken: request service token (saas)
  PlatformServiceToken-->>OnboardingEndpoint: JWT (claims with admin username)
  OnboardingEndpoint->>AdminIdentity: derive admin username from JWT
  OnboardingEndpoint->>OpenSearchClient: create client (JWT-based or unauthenticated or basic-auth)
  OpenSearchClient->>SetupOpenSearchSecurity: wait_for_opensearch() / setup_opensearch_security(admin)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • langflow-ai/openrag#1713: Modifies the same OpenSearch onboarding/startup credential selection paths and related ingest JWT signing changes.

Suggested reviewers

  • lucaseduoli
  • mfortman11
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: refactoring required scopes handling in GoogleDriveOAuth and adding a test for optional group scopes, which directly aligns with the primary changes in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch returning-only-required-scopes-for-google-drive-connector

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 backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) tests refactor and removed refactor labels Jun 1, 2026
edwinjosechittilappilly and others added 3 commits June 1, 2026 17:39
…rding flow, and support asymmetric JWT signing (#1713)

* Support OpenSearch basic-auth for on-prem

Add support for using OpenSearch basic-auth credentials in on-prem IBM-auth deployments. Introduces get_opensearch_username(), get_opensearch_password(), and use_opensearch_basic_auth() to read credentials at runtime (allowing overrides without restart). Update onboarding and lifespan startup logic to create a basic-auth OpenSearch client and use the OpenSearch username as the admin when basic-auth is enabled; otherwise preserve JWT-based client creation and bootstrap behavior. Adjust AppClients.initialize to set opensearch auth appropriately based on IBM_AUTH_ENABLED and the new basic-auth mode.

* Prefer service token for OpenSearch onboarding

Import get_openrag_service_token and prefer the platform service JWT when creating the OpenSearch client during onboarding, so the onboarding process pins the same admin identity as the startup security bootstrap. If a service token is present, extract admin username via admin_username_from_service_jwt and create the client with create_opensearch_client_from_jwt; raise a RuntimeError if the token lacks a username/sub claim. Maintain a backward-compatibility fallback: log a warning and fall back to using the onboarding user's jwt_token (and set admin_username to the user) when no service token is provided. Add a TODO to remove the fallback once OPENRAG_SERVICE_TOKEN is always supplied.

* Support JWT_SIGNING_KEY and key type detection

Prefer JWT_SIGNING_KEY over SESSION_SECRET and add PEM private key support for asymmetric JWTs. Introduces _resolve_default_signing_config to load PEM keys via cryptography, detect key types (RSA, EC with curve->ES*, EdDSA) and return signing/verification keys plus algorithm. LangflowIngestTokenService now stores separate signing and verification keys, uses them for jwt.encode/decode, and still accepts an explicit symmetric secret. Adds a unit test to ensure JWT_SIGNING_KEY is preferred and that a session secret cannot validate a JWT signed with JWT_SIGNING_KEY.

* style: ruff autofix (auto)

* Update langflow_ingest_token_service.py

* Use run-mode utils for OpenSearch auth selection

Unify OpenSearch client and admin selection across onboarding, startup, and client initialization by using run-mode helpers (is_run_mode_saas/on_prem/oss) instead of the old use_opensearch_basic_auth helper. Prefer the platform service token in SaaS mode (with a backward-compat fallback to the onboarding user when the token is missing), and use OpenSearch basic-auth credentials in on-prem/OSS modes. Added informative logging for each path and adjusted AppClients.initialize to choose the global writer client based on run mode. Changes in src/api/settings/endpoints.py, src/app/lifespan.py, and src/config/settings.py.

* style: ruff autofix (auto)

* Update lifespan.py

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Upgraded Langflow to 1.9.3

* update docling remote to throw errors

* upgrade docling version on docling manager

* style: ruff autofix (auto)

* Update docling code and fix docling manager lint

* updated langflow to 1.9.4

* change image to future langflow image

* upgraded to langflow 1.9.6rc0

* fix langflow image

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
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: 2

🧹 Nitpick comments (1)
src/services/langflow_ingest_token_service.py (1)

29-50: 💤 Low value

Wrap PEM parsing in error handling for clearer startup failures.

If JWT_SIGNING_KEY is set to a malformed or password-protected PEM, load_pem_private_key raises an opaque ValueError or TypeError. Consider catching and re-raising with a descriptive message to aid debugging configuration issues at startup.

🛡️ Suggested improvement
     if signing_key.lstrip().startswith("-----BEGIN"):
-        key = serialization.load_pem_private_key(signing_key.encode(), password=None)
+        try:
+            key = serialization.load_pem_private_key(signing_key.encode(), password=None)
+        except (ValueError, TypeError) as exc:
+            raise ValueError(
+                "JWT_SIGNING_KEY appears to be a PEM key but could not be loaded. "
+                "Ensure it is a valid unencrypted private key."
+            ) from exc
         public_key = key.public_key()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/langflow_ingest_token_service.py` around lines 29 - 50, Wrap the
PEM parsing call around serialization.load_pem_private_key in a try/except that
catches ValueError, TypeError and cryptography.exceptions.UnsupportedAlgorithm
(or a broad Exception if UnsupportedAlgorithm isn't imported) and re-raise a new
ValueError with a clear, descriptive message including the original exception
text and indicating JWT_SIGNING_KEY is malformed or password-protected; keep the
subsequent logic that derives public_key and sets algorithm (rsa.RSAPrivateKey,
ec.EllipticCurvePrivateKey, ed25519.Ed25519PrivateKey/ed448.Ed448PrivateKey
checks) unchanged so only the PEM loading step is given clearer error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@flows/openrag_agent.json`:
- Line 1741: The evaluator in CalculatorComponent (method _eval_expr) currently
rejects ast.UnaryOp, causing expressions like "-3+2" to fail; update _eval_expr
to handle ast.UnaryOp by mapping ast.UAdd/ast.USub to +/- and applying them to
the recursively evaluated operand (use operator.pos/operator.neg or simple unary
logic), ensure the handler coexists with the existing OPERATORS lookup for
ast.BinOp, and keep error handling in evaluate_expression unchanged so
unary-related errors still surface as invalid expressions.

In `@src/config/settings.py`:
- Around line 618-619: When constructing basic auth for on-prem/oss, validate
that get_opensearch_password() returns a non-None, non-empty string before
building os_auth; if it is None/empty, raise or log an explicit error (mirroring
the SaaS branch service token check) instead of passing
(get_opensearch_username(), None) to http_auth. Update the block that calls
is_run_mode_on_prem() or is_run_mode_oss() to fetch pw =
get_opensearch_password(), check pw, and only set os_auth =
(get_opensearch_username(), pw) when valid; apply the same validation pattern
for other call sites that pass get_opensearch_password() into
create_basic_opensearch_client().

---

Nitpick comments:
In `@src/services/langflow_ingest_token_service.py`:
- Around line 29-50: Wrap the PEM parsing call around
serialization.load_pem_private_key in a try/except that catches ValueError,
TypeError and cryptography.exceptions.UnsupportedAlgorithm (or a broad Exception
if UnsupportedAlgorithm isn't imported) and re-raise a new ValueError with a
clear, descriptive message including the original exception text and indicating
JWT_SIGNING_KEY is malformed or password-protected; keep the subsequent logic
that derives public_key and sets algorithm (rsa.RSAPrivateKey,
ec.EllipticCurvePrivateKey, ed25519.Ed25519PrivateKey/ed448.Ed448PrivateKey
checks) unchanged so only the PEM loading step is given clearer error handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 167b9508-2b5c-4558-980a-d2c9ca6558bf

📥 Commits

Reviewing files that changed from the base of the PR and between 899c250 and 6712820.

📒 Files selected for processing (8)
  • Dockerfile.langflow
  • flows/ingestion_flow.json
  • flows/openrag_agent.json
  • src/api/settings/endpoints.py
  • src/app/lifespan.py
  • src/config/settings.py
  • src/services/langflow_ingest_token_service.py
  • tests/unit/test_langflow_ingest_callback.py
✅ Files skipped from review due to trivial changes (1)
  • Dockerfile.langflow

Comment thread flows/openrag_agent.json
"title_case": false,
"type": "code",
"value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom lfx.custom.custom_component.component import Component\nfrom lfx.inputs.inputs import MessageTextInput\nfrom lfx.io import Output\nfrom lfx.schema.data import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n documentation: str = \"https://docs.langflow.org/calculator\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"JSON\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n if isinstance(node, ast.Num): # For backwards compatibility\n if isinstance(node.n, int | float):\n return float(node.n)\n error_msg = f\"Unsupported number type: {type(node.n).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n"
"value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom lfx.custom.custom_component.component import Component\nfrom lfx.inputs.inputs import MessageTextInput\nfrom lfx.io import Output\nfrom lfx.schema.data import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n documentation: str = \"https://docs.langflow.org/calculator\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"JSON\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Support unary operators in the AST calculator evaluator.

At Line 1741, the evaluator rejects ast.UnaryOp, so valid expressions like -3+2 fail as invalid. This breaks basic arithmetic support.

Suggested fix
-    def _eval_expr(self, node: ast.AST) -> float:
+    def _eval_expr(self, node: ast.AST) -> float:
         """Evaluate an AST node recursively."""
         if isinstance(node, ast.Constant):
             if isinstance(node.value, int | float):
                 return float(node.value)
             error_msg = f"Unsupported constant type: {type(node.value).__name__}"
             raise TypeError(error_msg)
 
+        if isinstance(node, ast.UnaryOp):
+            operand = self._eval_expr(node.operand)
+            if isinstance(node.op, ast.UAdd):
+                return +operand
+            if isinstance(node.op, ast.USub):
+                return -operand
+            error_msg = f"Unsupported unary operator: {type(node.op).__name__}"
+            raise TypeError(error_msg)
+
         if isinstance(node, ast.BinOp):
             op_type = type(node.op)
             if op_type not in self.OPERATORS:
                 error_msg = f"Unsupported binary operator: {op_type.__name__}"
                 raise TypeError(error_msg)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@flows/openrag_agent.json` at line 1741, The evaluator in CalculatorComponent
(method _eval_expr) currently rejects ast.UnaryOp, causing expressions like
"-3+2" to fail; update _eval_expr to handle ast.UnaryOp by mapping
ast.UAdd/ast.USub to +/- and applying them to the recursively evaluated operand
(use operator.pos/operator.neg or simple unary logic), ensure the handler
coexists with the existing OPERATORS lookup for ast.BinOp, and keep error
handling in evaluate_expression unchanged so unary-related errors still surface
as invalid expressions.

Comment thread src/config/settings.py
Comment on lines +618 to +619
if is_run_mode_on_prem() or is_run_mode_oss():
os_auth = (get_opensearch_username(), get_opensearch_password())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate password before constructing basic auth credentials.

get_opensearch_password() can return None, but passing (username, None) to http_auth may cause OpenSearch to receive a malformed auth header or fail unexpectedly. In on_prem/oss modes, the password is required for basic auth to succeed.

Consider adding validation similar to the SaaS branch's service token check:

🛡️ Proposed fix
     if is_run_mode_on_prem() or is_run_mode_oss():
+        os_password = get_opensearch_password()
+        if not os_password:
+            raise RuntimeError(
+                "OPENSEARCH_PASSWORD is required for on_prem/oss modes "
+                "but is not set"
+            )
-        os_auth = (get_opensearch_username(), get_opensearch_password())
+        os_auth = (get_opensearch_username(), os_password)

Note: The same pattern appears in src/api/settings/endpoints.py (line 1110-1112) and src/app/lifespan.py (line 225-227) where get_opensearch_password() is passed to create_basic_opensearch_client() which expects password: str.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/settings.py` around lines 618 - 619, When constructing basic auth
for on-prem/oss, validate that get_opensearch_password() returns a non-None,
non-empty string before building os_auth; if it is None/empty, raise or log an
explicit error (mirroring the SaaS branch service token check) instead of
passing (get_opensearch_username(), None) to http_auth. Update the block that
calls is_run_mode_on_prem() or is_run_mode_oss() to fetch pw =
get_opensearch_password(), check pw, and only set os_auth =
(get_opensearch_username(), pw) when valid; apply the same validation pattern
for other call sites that pass get_opensearch_password() into
create_basic_opensearch_client().

@ricofurtado
Copy link
Copy Markdown
Collaborator Author

Too many merging issues. replacing it for #1744

@ricofurtado ricofurtado closed this Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) docker refactor tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants