Skip to content

feat: Implement in-process JWT claims caching with TTL and LRU eviction#1625

Merged
ricofurtado merged 24 commits into
mainfrom
ttl-lru-eviction-cache-of-decoded-jwt-tokens
May 22, 2026
Merged

feat: Implement in-process JWT claims caching with TTL and LRU eviction#1625
ricofurtado merged 24 commits into
mainfrom
ttl-lru-eviction-cache-of-decoded-jwt-tokens

Conversation

@ricofurtado

@ricofurtado ricofurtado commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Performance Improvements

    • Implemented in-process JWT claims caching to reduce token validation latency; respects token expiration and evicts stale entries.
  • Configuration

    • Added environment variables to tune the JWT cache: OPENRAG_JWT_CACHE_TTL (default 60s) and OPENRAG_JWT_CACHE_MAXSIZE (default 1024).
  • Other

    • Startup now logs that the JWT claims cache is configured.
    • When an alternate auth mode is enabled, local JWT caching is bypassed.
  • Tests

    • Added unit tests covering cache hits, misses, expiration, key normalization, and decode-failure handling.

Review Change Stack

@github-actions github-actions Bot added backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) tests labels May 19, 2026
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The head commit changed during the review from 28b9e06 to dfc5256.

Walkthrough

Added TTL-based in-memory caches for decoded JWT claims used by SessionManager.verify_token and auth.ibm_auth.decode_ibm_jwt. Cache TTL and max-size are environment-configurable and logged at startup. Unit tests validate cache hits, misses, expiration eviction, non-caching of failures, bearer-prefix normalization, and IBM-auth bypass.

Changes

JWT Claims Caching

Layer / File(s) Summary
Cache configuration and startup logging
src/config/settings.py, src/app/lifespan.py
New JWT_CLAIMS_CACHE_TTL_SECONDS and JWT_CLAIMS_CACHE_MAX_SIZE settings sourced from environment variables with documented defaults. Application startup logs cache configuration with backend type and settings.
SessionManager JWT claims cache
src/session_manager.py
Imports reorganized to include cache settings. Module-level _JWT_CLAIMS_CACHE (TTLCache) added. verify_token refactored to strip Bearer prefix, check cache with expiration validation, evict stale entries, and store newly decoded claims; IBM auth mode bypasses cache.
IBM auth JWT claims cache
src/auth/ibm_auth.py
Module-level cache added and decode_ibm_jwt refactored to return cached claims when present and unexpired, evict stale entries, decode with verify_signature=False when needed, and cache successful results. Invalid tokens remain uncached.
JWT cache unit tests
tests/unit/test_jwt_claims_cache.py
New test module with autouse fixture clearing both caches between tests. TestVerifyTokenCache validates cache hit/miss, expiration handling, bearer-prefix normalization, and IBM-auth bypass. TestDecodeIbmJwtCache validates cache behavior and failure non-caching for IBM tokens.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SessionManager
  participant _JWT_CLAIMS_CACHE
  participant jwt_decode as jwt.decode
  Client->>SessionManager: verify_token("Bearer <token>")
  SessionManager->>SessionManager: strip "Bearer " prefix
  SessionManager->>_JWT_CLAIMS_CACHE: lookup by token
  alt Cache hit
    _JWT_CLAIMS_CACHE-->>SessionManager: cached claims
    SessionManager->>SessionManager: compare exp with time.time()
    alt exp expired
      SessionManager->>_JWT_CLAIMS_CACHE: evict token
      SessionManager->>jwt_decode: jwt.decode(token, audience, algorithms)
      jwt_decode-->>SessionManager: claims
      SessionManager->>_JWT_CLAIMS_CACHE: store claims[token]
      SessionManager-->>Client: return claims
    else exp valid
      SessionManager-->>Client: return cached claims
    end
  else Cache miss
    SessionManager->>jwt_decode: jwt.decode(token, audience, algorithms)
    jwt_decode-->>SessionManager: claims
    SessionManager->>_JWT_CLAIMS_CACHE: store claims[token]
    SessionManager-->>Client: return claims
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and specifically describes the main change: implementing JWT claims caching with TTL and LRU eviction, which is the core feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.
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 ttl-lru-eviction-cache-of-decoded-jwt-tokens
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch ttl-lru-eviction-cache-of-decoded-jwt-tokens

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.

@ricofurtado ricofurtado requested a review from mpawlow May 19, 2026 04:38
@ricofurtado ricofurtado requested a review from lucaseduoli May 19, 2026 04:38
@github-actions github-actions Bot added the enhancement 🔵 New feature or request label May 19, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 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 `@src/auth/ibm_auth.py`:
- Around line 24-28: Replace the hardcoded TTLCache initialization for
_IBM_JWT_CLAIMS_CACHE with values pulled from the centralized config in
config/settings.py: import the appropriate cache settings (e.g., names like
JWT_CACHE_MAXSIZE and JWT_CACHE_TTL or the settings object that exposes them)
and use those values when constructing TTLCache(maxsize=..., ttl=...); keep the
same key/value types and behavior (re-check exp on each hit) and add a sensible
fallback default if the config values are missing. Ensure the change touches the
_IBM_JWT_CLAIMS_CACHE symbol and removes any direct os.environ usage so all
env-driven configuration comes from config/settings.py.

In `@src/session_manager.py`:
- Line 5: Replace all uses of typing.Dict with the built-in generic dict: remove
Dict from the import line (change "from typing import Any, Dict, Optional,
Union" to exclude Dict) and update every annotation like Dict[K, V] to dict[K,
V] (notably in the module-level imports and the annotations referenced at lines
~5, ~158, and ~245). Keep other typing names (Any, Optional, Union) as-is and
ensure all replaced annotations use the new built-in dict generic forms.
🪄 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: 85ced2d0-e096-4efc-9a6a-1c9553a2d207

📥 Commits

Reviewing files that changed from the base of the PR and between a4b2da8 and 026c220.

📒 Files selected for processing (5)
  • src/app/lifespan.py
  • src/auth/ibm_auth.py
  • src/config/settings.py
  • src/session_manager.py
  • tests/unit/test_jwt_claims_cache.py

Comment thread src/auth/ibm_auth.py
Comment thread src/session_manager.py Outdated
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 19, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 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 `@src/session_manager.py`:
- Line 5: Replace all usages of Optional[T] with the modern union syntax T |
None (e.g., change Optional[str] to str | None) throughout
src/session_manager.py (including the occurrences noted around the other
locations), update the top import by removing Optional from the typing import
(so it becomes "from typing import Any, Union" or add specific types you need),
and ensure any now-unused imports are removed; adjust any function signatures,
variable annotations, and type aliases that referenced Optional to the new X |
None form.
🪄 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: f299a38a-acb3-4eb0-91f0-86f7feee5d1e

📥 Commits

Reviewing files that changed from the base of the PR and between 026c220 and 51d5a78.

📒 Files selected for processing (2)
  • src/auth/ibm_auth.py
  • src/session_manager.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/auth/ibm_auth.py

Comment thread src/session_manager.py Outdated
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 19, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 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 `@src/session_manager.py`:
- Around line 63-66: The JWT claims cache (_JWT_CLAIMS_CACHE) is currently
module-global but verification uses instance-specific material (SessionManager
self.public_key and self.algorithm), so make the cache scoped to each
SessionManager instance: remove or stop using the module-level _JWT_CLAIMS_CACHE
and instead initialize a TTLCache (using JWT_CLAIMS_CACHE_MAX_SIZE and
JWT_CLAIMS_CACHE_TTL_SECONDS) as an instance attribute in
SessionManager.__init__ (e.g., self._jwt_claims_cache) and update all uses
(token lookup/insert code that referenced _JWT_CLAIMS_CACHE) to use
self._jwt_claims_cache; alternatively, if you must share a cache, include the
verifier identity (a stable fingerprint of self.public_key and self.algorithm)
in the cache key so cached entries are only reused for matching verification
material.
- Line 249: The code currently uses token.removeprefix("Bearer ") which only
removes the exact-case prefix; update the logic that produces raw (use
token.removeprefix or equivalent) to strip the "Bearer" scheme
case-insensitively (e.g., detect a leading bearer token regardless of case and
any whitespace) before verification so inputs like "bearer <token>" are handled
correctly; locate the token.removeprefix usage (variable raw) in
session_manager.py and replace it with a case-insensitive removal (or a
regex/normalized-split approach) that preserves the token value for subsequent
JWT verification.
- Around line 146-156: The call that sets self.public_key_pem uses
open(self.public_key_path, "r").read(), which triggers Ruff UP015 for redundant
read mode; change it to open(self.public_key_path).read() (or use a
with-statement to read into self.public_key_pem) so the explicit "r" mode is
removed while keeping behavior unchanged in the SessionManager code where
self.public_key and self.public_key_pem are loaded.
🪄 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: 6ee9539a-274a-4d7a-a699-709edefbccca

📥 Commits

Reviewing files that changed from the base of the PR and between 51d5a78 and 3a179cc.

📒 Files selected for processing (1)
  • src/session_manager.py

Comment thread src/session_manager.py
Comment on lines +63 to +66
_JWT_CLAIMS_CACHE: TTLCache[str, dict] = TTLCache(
maxsize=JWT_CLAIMS_CACHE_MAX_SIZE,
ttl=JWT_CLAIMS_CACHE_TTL_SECONDS,
)

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 | 🔴 Critical | ⚡ Quick win

Scope the JWT claims cache to the verifier instance.

Lines 63-66 make the cache process-global, but Lines 258-263 validate with self.public_key and self.algorithm. A token accepted and cached by one SessionManager instance can then be returned by another instance with different verification material without re-checking the signature.

🔐 Minimal direction
- _JWT_CLAIMS_CACHE: TTLCache[str, dict] = TTLCache(
-     maxsize=JWT_CLAIMS_CACHE_MAX_SIZE,
-     ttl=JWT_CLAIMS_CACHE_TTL_SECONDS,
- )
-
 class SessionManager:
@@
         self.users: dict[str, User] = {}  # user_id -> User
         self.user_opensearch_clients: dict[str, Any] = {}  # user_id -> OpenSearch client
+        self.jwt_claims_cache: TTLCache[str, dict[str, Any]] = TTLCache(
+            maxsize=JWT_CLAIMS_CACHE_MAX_SIZE,
+            ttl=JWT_CLAIMS_CACHE_TTL_SECONDS,
+        )
@@
-        cached = _JWT_CLAIMS_CACHE.get(raw)
+        cached = self.jwt_claims_cache.get(raw)
@@
-            _JWT_CLAIMS_CACHE.pop(raw, None)  # evict immediately on stale hit
+            self.jwt_claims_cache.pop(raw, None)  # evict immediately on stale hit
@@
-            _JWT_CLAIMS_CACHE[raw] = payload
+            self.jwt_claims_cache[raw] = payload

Also applies to: 82-83, 251-265

🤖 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/session_manager.py` around lines 63 - 66, The JWT claims cache
(_JWT_CLAIMS_CACHE) is currently module-global but verification uses
instance-specific material (SessionManager self.public_key and self.algorithm),
so make the cache scoped to each SessionManager instance: remove or stop using
the module-level _JWT_CLAIMS_CACHE and instead initialize a TTLCache (using
JWT_CLAIMS_CACHE_MAX_SIZE and JWT_CLAIMS_CACHE_TTL_SECONDS) as an instance
attribute in SessionManager.__init__ (e.g., self._jwt_claims_cache) and update
all uses (token lookup/insert code that referenced _JWT_CLAIMS_CACHE) to use
self._jwt_claims_cache; alternatively, if you must share a cache, include the
verifier identity (a stable fingerprint of self.public_key and self.algorithm)
in the cache key so cached entries are only reused for matching verification
material.

Comment thread src/session_manager.py
Comment thread src/session_manager.py Outdated
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 22, 2026
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 22, 2026
* Handle user insert races and add test timeout

Increase TypeScript integration test timeout to 120s to reduce flakiness during slow CI runs.

Enhance user_service.ensure_user_row IntegrityError handling to explicitly handle concurrent-insert races: detect a (oauth_provider, oauth_subject) race and return the existing row, detect an email_lookup_hash race by looking up the email and returning the concurrent identity when it matches, and handle PK collisions by retrying the insert with a new UUID. Add explanatory comments about which collisions are recoverable and when errors should propagate to the caller.

* style: ruff format (auto)

* Use PEP 604 union for agent config return type

Replace typing.Optional[dict] with PEP 604 union syntax (dict | None) for get_effective_agent_config and remove the now-unused Optional import. This is a pure type-annotation cleanup (no runtime behavior changes); note it requires Python 3.10+ for the `|` union syntax.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
edwinjosechittilappilly and others added 11 commits May 21, 2026 23:21
* Add kind build/load targets and kind sample

Add Makefile targets to build and load app images into a kind cluster (KIND_CLUSTER_NAME default: openrag): kind-load-app-images and kind-build-load-apps, and expose them in the help output. Update kubernetes/operator/README.md with instructions to run the operator locally, apply a kind-local sample, build/load images into kind, and restart deployments after rebuilding. Add a new config sample openrag_v1alpha1_openrag-kind-local.yaml tuned for 2-CPU kind/Colima clusters (lower resource requests, imagePullPolicy: Never). Also annotate the default sample to point users to the kind-local file for local clusters.

* Add Makefile help for operator & kind

Add a new help_operator target and OPERATOR_DIR variable to the Makefile, and include it in the .PHONY list. The new help output documents Kubernetes operator and kind-related commands (build/load app images into kind, operator deps/install/run/build/test/lint/manifests/generate, deploy/undeploy, docker-build, helm install) and provides a typical kind + local images workflow and sample CR usage. This makes it easier for developers to discover and run local operator/cluster tasks from the repo root.
Add a COPY instruction to include the local flows/ directory at /app/flows in the image so bundled flows are available at runtime. Placed before the entrypoint/ownership handling to ensure the files are copied with the intended UID/permissions.
* remove logic for previous tab selected, need to be discussed with Ana

* reduce repeated code and use darkmodelight class

* reduce repeated code and use darkmodelight class

* remove unecessary !important

* remove unecessary !important

* remove duplicate css blocks

* remove !important and merge active and hover state

* put back TabsContent anf fix hover issue

---------

Co-authored-by: Olfa Maslah <[email protected]>
* Add ruff autofix step to CI workflows

Add an in-place Ruff fix step to .github/workflows/autofix.ci.yml that runs uv run ruff check --fix on changed files, rename the job and autofix commit message to reflect "ruff autofix", and update comments to clarify that autofix.ci applies safe fixes and formatting. Also update .github/workflows/lint-backend.yml comments to state that safe lint fixes and formatting are auto-applied by autofix.ci while keeping strict lint (--no-fix) and mypy in the lint workflow.

* Update autofix.ci.yml
* Enum IDs and delete OpenSearch docs by _id

Add DLS-safe OpenSearch delete helpers and use them to avoid silent no-ops from delete_by_query. Introduces utils/opensearch_delete.py with collect_visible_document_ids and delete_document_ids (enumerate visible _ids via search/scroll, then delete by primary _id). Update delete_chunks_by_document_ids to enumerate chunk IDs and delete each by _id. Ensure langflow_connector_service and TaskProcessor clear stale chunks (by document_id) before re-ingest/re-index to prevent duplicate or trailing chunks after renames. Improve connector listing by scoping cfg.file_ids/folder_ids when available to avoid false orphan detection. Add and update unit tests to assert the new enumeration-and-delete behavior and ordering.

* style: ruff format (auto)

* ruff fix

* ruff fix

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Remove google_drive from the cloud-brand exclusion so Google Drive connectors are visible when isCloudBrand is true. Applied the change in connector-cards.tsx and knowledge-dropdown.tsx (OneDrive remains excluded).
* fix cr deletion

* refactoring

* fix unit test

* fix lint

* fix cross namespace CR deletion
@github-actions github-actions Bot added enhancement 🔵 New feature or request frontend 🟨 Issues related to the UI/UX ci ⬛ CI/CD, build, and infrastructure issues docker and removed enhancement 🔵 New feature or request labels May 22, 2026
Comment thread src/api/connectors.py Fixed
Comment thread src/api/connectors.py Fixed

@coderabbitai coderabbitai Bot left a comment

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.

Caution

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

⚠️ Outside diff range comments (2)
src/session_manager.py (2)

5-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the unused Union import.

Ruff is already failing with F401 on Line 5, so this blocks CI until Union is dropped from the typing import.

🤖 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/session_manager.py` at line 5, Remove the unused Union import from the
typing import in session_manager.py: update the import statement that currently
reads "from typing import Any, Union" to only import the used symbol(s) (e.g.,
"from typing import Any"), ensuring no other references to the name Union exist
in functions or type hints (check for usages in any methods or type annotations
in the file such as in SessionManager or related functions).

285-295: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix JWT typing to match nullable flow

  • get_user_opensearch_client declares jwt_token: str = None but the code passes/assigns jwt_token that can be None; annotate as str | None.
  • get_effective_jwt_token is typed as jwt_token: str -> str, but it accepts None in practice (checks jwt_token is not None) and returns None on multiple paths; update its parameter and return types to include None.
🤖 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/session_manager.py` around lines 285 - 295, Update the type annotations
to reflect nullable JWT flow: change get_user_opensearch_client's parameter
jwt_token from "str = None" to "str | None" (or Optional[str]) so the signature
matches runtime usage, and modify get_effective_jwt_token's signature to accept
"jwt_token: str | None" and return "str | None" (or Optional[str]) since it
currently accepts None and can return None on several paths; adjust any related
type hints or return annotations referencing these functions
(get_user_opensearch_client, get_effective_jwt_token) accordingly.
🤖 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.

Outside diff comments:
In `@src/session_manager.py`:
- Line 5: Remove the unused Union import from the typing import in
session_manager.py: update the import statement that currently reads "from
typing import Any, Union" to only import the used symbol(s) (e.g., "from typing
import Any"), ensuring no other references to the name Union exist in functions
or type hints (check for usages in any methods or type annotations in the file
such as in SessionManager or related functions).
- Around line 285-295: Update the type annotations to reflect nullable JWT flow:
change get_user_opensearch_client's parameter jwt_token from "str = None" to
"str | None" (or Optional[str]) so the signature matches runtime usage, and
modify get_effective_jwt_token's signature to accept "jwt_token: str | None" and
return "str | None" (or Optional[str]) since it currently accepts None and can
return None on several paths; adjust any related type hints or return
annotations referencing these functions (get_user_opensearch_client,
get_effective_jwt_token) accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 25b735f3-e037-4ec7-b749-8c222fe4807a

📥 Commits

Reviewing files that changed from the base of the PR and between 3a179cc and f87517f.

📒 Files selected for processing (1)
  • src/session_manager.py

… through an exception'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 22, 2026
@github-actions github-actions Bot added enhancement 🔵 New feature or request and removed enhancement 🔵 New feature or request labels May 22, 2026
@github-actions github-actions Bot added the lgtm label May 22, 2026
@ricofurtado ricofurtado merged commit 022527b into main May 22, 2026
12 of 13 checks passed
@github-actions github-actions Bot deleted the ttl-lru-eviction-cache-of-decoded-jwt-tokens branch May 22, 2026 04:57
@mpawlow mpawlow removed their request for review May 22, 2026 13:25
ricofurtado added a commit that referenced this pull request May 23, 2026
…on (#1625)

* feat: Implement in-process JWT claims caching with TTL and LRU eviction

* style: ruff format (auto)

* refactor: Update cache initialization to use settings for max size and TTL

* feat: code cleanup

* fix: Improve public key file reading and enhance token scheme handling

* style: ruff autofix (auto)

* fix: Handle user insert races and add test timeout (#1618)

* Handle user insert races and add test timeout

Increase TypeScript integration test timeout to 120s to reduce flakiness during slow CI runs.

Enhance user_service.ensure_user_row IntegrityError handling to explicitly handle concurrent-insert races: detect a (oauth_provider, oauth_subject) race and return the existing row, detect an email_lookup_hash race by looking up the email and returning the concurrent identity when it matches, and handle PK collisions by retrying the insert with a new UUID. Add explanatory comments about which collisions are recoverable and when errors should propagate to the caller.

* style: ruff format (auto)

* Use PEP 604 union for agent config return type

Replace typing.Optional[dict] with PEP 604 union syntax (dict | None) for get_effective_agent_config and remove the now-unused Optional import. This is a pure type-annotation cleanup (no runtime behavior changes); note it requires Python 3.10+ for the `|` union syntax.

---------

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

* fix: display file names and fix ingestion for onedrive (#1609)

* fixed onedrive not working

* style: ruff format (auto)

* removed sites.read.all from onedrive

* style: ruff format (auto)

* fixed allowed users and groups

* fix lint error

* fixed lint

* fixed mypy lint

* style: ruff format (auto)

---------

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

* fix: Skip deleted connector files; return orphan IDs (#1592)

* Skip deleted connector files; return orphan IDs

Handle files deleted at source and improve orphan reconciliation.

- Add TaskStatus.SKIPPED and update ConnectorFileProcessor to catch FileNotFoundError/ValueError from connector.get_file_content. When a file is missing, mark the file task as SKIPPED, set a skipped result, update timestamps and counters, and avoid raising so the upload can continue.
- Change reconcile_orphans_for_connector_type to return a list of orphan file IDs ([]) instead of an int, update early returns and docstring to reflect returning the deleted/removed document IDs so callers can exclude them from subsequent sync passes.
- Minor whitespace cleanup in sync_all_connectors.

These changes avoid aborting syncs on missing source files and make orphan deletions explicit for downstream processing.

* Skip deleted connector files; return orphan IDs

Handle files deleted at source and improve orphan reconciliation.

- Add TaskStatus.SKIPPED and update ConnectorFileProcessor to catch FileNotFoundError/ValueError from connector.get_file_content. When a file is missing, mark the file task as SKIPPED, set a skipped result, update timestamps and counters, and avoid raising so the upload can continue.
- Change reconcile_orphans_for_connector_type to return a list of orphan file IDs ([]) instead of an int, update early returns and docstring to reflect returning the deleted/removed document IDs so callers can exclude them from subsequent sync passes.
- Minor whitespace cleanup in sync_all_connectors.

These changes avoid aborting syncs on missing source files and make orphan deletions explicit for downstream processing.

* Add *.db to .gitignore

Add a '*.db' pattern to .gitignore to prevent local database files (e.g., SQLite) from being committed to the repository.

* Add orphan reconcile and bulk-delete helper

Introduce a reconcile pass and supporting bulk-delete utility to remove OpenSearch chunks for files that no longer exist remotely.

- Add reconcile_orphans_for_connector_type (src/api/connectors.py): lists all active connections for a connector type, strictly gates on unauthenticated connections or listing errors (abort with 0 deletes), aggregates paginated remote file IDs, computes orphans (indexed IDs not present remotely) and invokes delete_chunks_by_document_ids. Integrated into connector_sync and sync_all_connectors (skips reconcile when sync is capped).
- Add delete_chunks_by_document_ids (src/api/documents.py): issues a single delete_by_query with terms(document_id, ...) and conflicts="proceed", returns deleted count, and short-circuits on empty input.
- Update connector metadata painless params (src/connectors/service.py): include filename param and assign ctx._source.filename = params.filename in the update script so renamed files update indexed chunks.
- Add unit tests: cover delete_chunks_by_document_ids, reconcile_orphans_for_connector_type (gating, pagination, multi-connection union, error handling), and connector metadata filename behavior.

Behavior notes: reconcile is conservative to avoid false-positive deletions; bulk delete is defensive and returns 0 on unexpected responses or failures.

* fix lint

* style: ruff format (auto)

* fix lint

* Use max_files param and add typing

Add an explicit type annotation for files_to_process and update the connector.list_files call to use the max_files parameter instead of limit to match the connector API. Also remove redundant `# type: ignore` comments on connector.cfg assignments as they are no longer necessary. Minor cleanup to improve type clarity and API consistency.

* Add connector sync preview UI and API

Introduce sync-preview functionality for connectors and sync-all flows. Backend: add ID→filename aggregation, compute_orphans (non-destructive orphan detection), orphan deletion helper, and preview endpoints (connector_sync_preview, connectors_sync_all_preview) plus wiring in internal routes. Frontend: add useSyncConnectorPreview/useSyncAllConnectorsPreview mutations, wire preview flows into Knowledge pages/components, and add SyncConfirmDialog component to show orphan lists, per-connector synced counts, availability flags, and confirm deletion+sync interactions. Also update UI buttons to open the preview dialog and handle loading/syncing states.

* style: ruff format (auto)

* Hoist and consolidate imports in processors

Move many inline imports to module scope and consolidate repeated imports across TaskProcessor and its subclasses. Adds top-level imports (asyncio, datetime, mimetypes, os, time), config/settings and utility functions (clients, get_embedding_model, get_index_name, get_openrag_config, extract_relevant, process_text_file, resplit_chunks_character_windows, ensure_embedding_field_exists, auto_cleanup_tempfile, hash_id, build_filename_delete_body, build_filename_search_body) and imports TaskStatus. Removes redundant per-function imports to improve readability and reduce repeated import overhead; no functional changes intended.

* Type UseQueryOptions with SearchResult

Specify UseQueryOptions<SearchResult> for the useGetSearchQuery hook's options parameter to improve TypeScript type inference and ensure the query options expect SearchResult data. This change tightens typings without altering runtime behavior.

---------

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

* fix: add reset db on command, expose error on e2e tests (#1627)

* fix factory reset not deleting data

* make onboarding errors pop up on e2e tests

* style: ruff format (auto)

* added check for error when uploading

* added check if its on first step to rollback, not only if its complete

* reset correctly

* update timeout for uploading document

* remove misclick

* fixed lint

* fix mypy errors

* style: ruff format (auto)

---------

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

* refactor: handler for file upload for context (#1624)

* file upload for context

* coderabbit suggestions

* chore:  add operator make commands (#1628)

* Add kind build/load targets and kind sample

Add Makefile targets to build and load app images into a kind cluster (KIND_CLUSTER_NAME default: openrag): kind-load-app-images and kind-build-load-apps, and expose them in the help output. Update kubernetes/operator/README.md with instructions to run the operator locally, apply a kind-local sample, build/load images into kind, and restart deployments after rebuilding. Add a new config sample openrag_v1alpha1_openrag-kind-local.yaml tuned for 2-CPU kind/Colima clusters (lower resource requests, imagePullPolicy: Never). Also annotate the default sample to point users to the kind-local file for local clusters.

* Add Makefile help for operator & kind

Add a new help_operator target and OPERATOR_DIR variable to the Makefile, and include it in the .PHONY list. The new help output documents Kubernetes operator and kind-related commands (build/load app images into kind, operator deps/install/run/build/test/lint/manifests/generate, deploy/undeploy, docker-build, helm install) and provides a typical kind + local images workflow and sample CR usage. This makes it easier for developers to discover and run local operator/cluster tasks from the repo root.

* redirect on logout (#1440) (#1636)

* fix: Copy flows directory into Docker image (#1632)

Add a COPY instruction to include the local flows/ directory at /app/flows in the image so bundled flows are available at runtime. Placed before the entrypoint/ownership handling to ensure the files are copied with the intended UID/permissions.

* feat: settings saas tabs menu (#1637)

* remove logic for previous tab selected, need to be discussed with Ana

* reduce repeated code and use darkmodelight class

* reduce repeated code and use darkmodelight class

* remove unecessary !important

* remove unecessary !important

* remove duplicate css blocks

* remove !important and merge active and hover state

* put back TabsContent anf fix hover issue

---------

Co-authored-by: Olfa Maslah <[email protected]>

* chore: Add ruff autofix step to CI workflows (#1640)

* Add ruff autofix step to CI workflows

Add an in-place Ruff fix step to .github/workflows/autofix.ci.yml that runs uv run ruff check --fix on changed files, rename the job and autofix commit message to reflect "ruff autofix", and update comments to clarify that autofix.ci applies safe fixes and formatting. Also update .github/workflows/lint-backend.yml comments to state that safe lint fixes and formatting are auto-applied by autofix.ci while keeping strict lint (--no-fix) and mypy in the lint workflow.

* Update autofix.ci.yml

* fix: Enum IDs and delete OpenSearch docs by _id (#1638)

* Enum IDs and delete OpenSearch docs by _id

Add DLS-safe OpenSearch delete helpers and use them to avoid silent no-ops from delete_by_query. Introduces utils/opensearch_delete.py with collect_visible_document_ids and delete_document_ids (enumerate visible _ids via search/scroll, then delete by primary _id). Update delete_chunks_by_document_ids to enumerate chunk IDs and delete each by _id. Ensure langflow_connector_service and TaskProcessor clear stale chunks (by document_id) before re-ingest/re-index to prevent duplicate or trailing chunks after renames. Improve connector listing by scoping cfg.file_ids/folder_ids when available to avoid false orphan detection. Add and update unit tests to assert the new enumeration-and-delete behavior and ordering.

* style: ruff format (auto)

* ruff fix

* ruff fix

---------

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

* make probes more robust (#1642)

* feat: Show google_drive connector for cloud brand (#1650)

Remove google_drive from the cloud-brand exclusion so Google Drive connectors are visible when isCloudBrand is true. Applied the change in connector-cards.tsx and knowledge-dropdown.tsx (OneDrive remains excluded).

* operator ubi base build (#1652)

* remove flow download initContainer when flowRef is removed (#1653)

* fix: cr deletion (#1656)

* fix cr deletion

* refactoring

* fix unit test

* fix lint

* fix cross namespace CR deletion

* Potential fix for pull request finding 'CodeQL / Information exposure through an exception'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Edwin Jose <[email protected]>
Co-authored-by: Lucas Oliveira <[email protected]>
Co-authored-by: Mike Fortman <[email protected]>
Co-authored-by: Wallgau <[email protected]>
Co-authored-by: Olfa Maslah <[email protected]>
Co-authored-by: ming <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
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) ci ⬛ CI/CD, build, and infrastructure issues docker enhancement 🔵 New feature or request frontend 🟨 Issues related to the UI/UX lgtm tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants