Skip to content

fix: per-user model list support with resolved headers#63

Open
bensi94 wants to merge 6 commits intomainfrom
fix/per-user-model-list
Open

fix: per-user model list support with resolved headers#63
bensi94 wants to merge 6 commits intomainfrom
fix/per-user-model-list

Conversation

@bensi94
Copy link

@bensi94 bensi94 commented Feb 18, 2026

Summary

When using an upstream model provider like LiteLLM with JWT/OIDC-based authentication, different users may have access to different models based on their role and permissions. The previous implementation cached the models config globally (MODELS_CONFIG key), causing all users to see the same model list regardless of their identity or authorization level.

This PR fixes two issues:

  1. Removes global model config caching in ModelController.js — models are now fetched fresh on each request, ensuring per-user model lists are correctly returned. This applies to both master-key and user-token scenarios, but is especially important when tokens vary per user.

  2. Resolves custom headers through resolveHeaders() in fetchModels() — template placeholders like {{LIBRECHAT_OPENID_ID_TOKEN}} in config headers are now properly expanded per-user before the model fetch request. Custom headers are merged after default auth headers, so config-level authorization headers (e.g. forwarding an OIDC token) take precedence over the default Bearer <apiKey>.

Example config that now works correctly:

headers:
  authorization: "Bearer {{LIBRECHAT_OPENID_ID_TOKEN}}"

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

  • Updated existing tests in models.spec.ts to verify:
    • Custom headers are resolved via resolveHeaders() before being sent
    • Custom authorization header overrides the default Bearer token
    • Anthropic endpoint merges custom headers on top of its defaults
  • Verified that ModelController.js no longer references CacheKeys or getLogStores

Test Configuration:

  • LibreChat with LiteLLM backend using OIDC JWT authentication
  • Config with headers.authorization: "Bearer {{LIBRECHAT_OPENID_ID_TOKEN}}"
  • Multiple users with different role-based model access

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

… fetching

The models config was cached globally (MODELS_CONFIG key) which meant all
users saw the same model list regardless of their role or permissions.
This is incorrect when the upstream provider (e.g. LiteLLM) returns
different models per user based on JWT/OIDC tokens forwarded via custom
headers.

Changes:
- Remove MODELS_CONFIG cache from ModelController so models are fetched
  fresh on each request, supporting per-user model lists
- Resolve custom headers through resolveHeaders() before merging into
  the request options in fetchModels(), enabling template placeholders
  like {{LIBRECHAT_OPENID_ID_TOKEN}} to be expanded per-user
- Merge resolved custom headers after default auth headers so config
  headers (e.g. authorization) take precedence over the default Bearer
  token
- Update tests to verify header resolution and override behavior
@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

Important

Review skipped

Too many files!

This PR contains 273 files, which is 123 over the limit of 150.

📥 Commits

Reviewing files that changed from the base of the PR and between 9054ca9 and dd6dbc8.

⛔ Files ignored due to path filters (7)
  • bun.lock is excluded by !**/*.lock
  • package-lock.json is excluded by !**/package-lock.json
  • packages/api/src/files/documents/empty.docx is excluded by !**/*.docx
  • packages/api/src/files/documents/sample.docx is excluded by !**/*.docx
  • packages/api/src/files/documents/sample.xls is excluded by !**/*.xls
  • packages/api/src/files/documents/sample.xlsx is excluded by !**/*.xlsx
  • packages/data-provider/react-query/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (273)
  • .env.example
  • .github/CONTRIBUTING.md
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • Dockerfile
  • Dockerfile.multi
  • api/app/clients/BaseClient.js
  • api/app/clients/tools/manifest.json
  • api/app/clients/tools/structured/GeminiImageGen.js
  • api/app/clients/tools/util/handleTools.js
  • api/cache/banViolation.js
  • api/cache/getLogStores.js
  • api/db/connect.js
  • api/db/utils.js
  • api/db/utils.spec.js
  • api/models/Conversation.js
  • api/models/Conversation.spec.js
  • api/models/Role.js
  • api/models/Role.spec.js
  • api/models/Transaction.spec.js
  • api/models/spendTokens.spec.js
  • api/models/tx.js
  • api/models/tx.spec.js
  • api/package.json
  • api/server/controllers/AuthController.js
  • api/server/controllers/AuthController.spec.js
  • api/server/controllers/ModelController.js
  • api/server/controllers/PluginController.js
  • api/server/controllers/PluginController.spec.js
  • api/server/controllers/UserController.js
  • api/server/controllers/agents/__tests__/callbacks.spec.js
  • api/server/controllers/agents/__tests__/openai.spec.js
  • api/server/controllers/agents/__tests__/responses.unit.spec.js
  • api/server/controllers/agents/callbacks.js
  • api/server/controllers/agents/client.js
  • api/server/controllers/agents/openai.js
  • api/server/controllers/agents/responses.js
  • api/server/controllers/agents/v1.js
  • api/server/controllers/agents/v1.spec.js
  • api/server/controllers/auth/LogoutController.js
  • api/server/index.js
  • api/server/middleware/buildEndpointOption.js
  • api/server/middleware/buildEndpointOption.spec.js
  • api/server/middleware/requireJwtAuth.js
  • api/server/routes/__tests__/convos.spec.js
  • api/server/routes/__tests__/keys.spec.js
  • api/server/routes/__tests__/mcp.spec.js
  • api/server/routes/actions.js
  • api/server/routes/convos.js
  • api/server/routes/keys.js
  • api/server/routes/mcp.js
  • api/server/routes/oauth.js
  • api/server/services/ActionService.js
  • api/server/services/AuthService.js
  • api/server/services/AuthService.spec.js
  • api/server/services/Config/__tests__/getCachedTools.spec.js
  • api/server/services/Config/getCachedTools.js
  • api/server/services/Config/mcp.js
  • api/server/services/Endpoints/agents/title.js
  • api/server/services/Endpoints/assistants/title.js
  • api/server/services/Files/Azure/crud.js
  • api/server/services/Files/Firebase/crud.js
  • api/server/services/Files/Local/crud.js
  • api/server/services/Files/S3/crud.js
  • api/server/services/Files/process.js
  • api/server/services/Files/process.spec.js
  • api/server/services/Files/strategies.js
  • api/server/services/GraphTokenService.js
  • api/server/services/MCP.js
  • api/server/services/MCP.spec.js
  • api/server/services/ToolService.js
  • api/server/services/initializeMCPs.spec.js
  • api/server/socialLogins.js
  • api/strategies/openIdJwtStrategy.js
  • api/strategies/openIdJwtStrategy.spec.js
  • api/strategies/openidStrategy.js
  • api/strategies/openidStrategy.spec.js
  • api/test/services/Files/S3/crud.test.js
  • api/utils/tokens.spec.js
  • client/jest.config.cjs
  • client/package.json
  • client/src/Providers/BadgeRowContext.tsx
  • client/src/common/agents-types.ts
  • client/src/components/Chat/Input/BadgeRow.tsx
  • client/src/components/Chat/Input/ChatForm.tsx
  • client/src/components/Chat/Input/Files/AttachFileMenu.tsx
  • client/src/components/Chat/Input/Files/DragDropModal.tsx
  • client/src/components/Chat/Input/Files/ImagePreview.tsx
  • client/src/components/Chat/Input/MCPSelect.tsx
  • client/src/components/Chat/Input/MCPSubMenu.tsx
  • client/src/components/Chat/Input/SendButton.tsx
  • client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
  • client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
  • client/src/components/Chat/Messages/Content/MarkdownLite.tsx
  • client/src/components/Chat/Messages/Content/Part.tsx
  • client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
  • client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
  • client/src/components/Chat/Messages/Content/ToolCall.tsx
  • client/src/components/MCP/MCPConfigDialog.tsx
  • client/src/components/MCP/ServerInitializationSection.tsx
  • client/src/components/Nav/Favorites/FavoritesList.tsx
  • client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
  • client/src/components/Nav/NewChat.tsx
  • client/src/components/Plugins/Store/PluginAuthForm.tsx
  • client/src/components/SidePanel/Agents/AgentPanel.tsx
  • client/src/components/SidePanel/Agents/MCPTools.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/MCPServerForm.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/index.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/sections/AuthSection.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/sections/BasicInfoSection.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/sections/ConnectionSection.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/sections/TransportSection.tsx
  • client/src/components/SidePanel/MCPBuilder/MCPServerDialog/sections/TrustSection.tsx
  • client/src/components/Tools/MCPToolSelectDialog.tsx
  • client/src/data-provider/MCP/queries.ts
  • client/src/data-provider/queries.ts
  • client/src/hooks/Agents/useApplyModelSpecAgents.ts
  • client/src/hooks/Chat/useAddedResponse.ts
  • client/src/hooks/Chat/useChatFunctions.ts
  • client/src/hooks/Conversations/useDefaultConvo.ts
  • client/src/hooks/Conversations/useExportConversation.ts
  • client/src/hooks/Conversations/useGenerateConvo.ts
  • client/src/hooks/Conversations/useNavigateToConvo.tsx
  • client/src/hooks/MCP/__tests__/useMCPSelect.test.tsx
  • client/src/hooks/MCP/useMCPSelect.ts
  • client/src/hooks/MCP/useMCPServerManager.ts
  • client/src/hooks/Plugins/__tests__/useToolToggle.test.tsx
  • client/src/hooks/Plugins/useToolToggle.ts
  • client/src/hooks/useNewConvo.ts
  • client/src/locales/en/translation.json
  • client/src/locales/lv/translation.json
  • client/src/locales/nb/translation.json
  • client/src/routes/ChatRoute.tsx
  • client/src/store/favorites.ts
  • client/src/store/jotai-utils.ts
  • client/src/store/mcp.ts
  • client/src/style.css
  • client/src/utils/__tests__/applyModelSpecEphemeralAgent.test.ts
  • client/src/utils/__tests__/buildDefaultConvo.test.ts
  • client/src/utils/__tests__/cleanupPreset.integration.test.ts
  • client/src/utils/__tests__/cleanupPreset.test.ts
  • client/src/utils/buildDefaultConvo.ts
  • client/src/utils/cleanupPreset.ts
  • client/src/utils/endpoints.ts
  • client/src/utils/errors.ts
  • client/src/utils/index.ts
  • client/src/utils/resources.ts
  • client/tailwind.config.cjs
  • config/smart-reinstall.js
  • deploy-compose.yml
  • docker-compose.yml
  • e2e/jestSetup.js
  • eslint.config.mjs
  • helm/librechat-rag-api/Chart.yaml
  • helm/librechat-rag-api/templates/rag-deployment.yaml
  • helm/librechat-rag-api/values.yaml
  • helm/librechat/Chart.yaml
  • helm/librechat/templates/configmap-env.yaml
  • helm/librechat/templates/deployment.yaml
  • helm/librechat/values.yaml
  • librechat.example.yaml
  • package.json
  • packages/api/jest.config.mjs
  • packages/api/package.json
  • packages/api/src/agents/__tests__/initialize.test.ts
  • packages/api/src/agents/avatars.spec.ts
  • packages/api/src/agents/avatars.ts
  • packages/api/src/agents/client.ts
  • packages/api/src/agents/index.ts
  • packages/api/src/agents/initialize.ts
  • packages/api/src/agents/responses/__tests__/responses-api.live.test.sh
  • packages/api/src/agents/responses/__tests__/service.test.ts
  • packages/api/src/agents/responses/service.ts
  • packages/api/src/app/config.test.ts
  • packages/api/src/app/config.ts
  • packages/api/src/app/permissions.spec.ts
  • packages/api/src/app/permissions.ts
  • packages/api/src/auth/agent.spec.ts
  • packages/api/src/auth/agent.ts
  • packages/api/src/auth/domain.spec.ts
  • packages/api/src/auth/domain.ts
  • packages/api/src/auth/index.ts
  • packages/api/src/cache/__tests__/cacheConfig.spec.ts
  • packages/api/src/cache/__tests__/cacheFactory/standardCache.namespace_isolation.spec.ts
  • packages/api/src/cache/__tests__/cacheFactory/violationCache.cache_integration.spec.ts
  • packages/api/src/cache/cacheConfig.ts
  • packages/api/src/cache/cacheFactory.ts
  • packages/api/src/cache/redisClients.ts
  • packages/api/src/cdn/__tests__/s3.test.ts
  • packages/api/src/cdn/s3.ts
  • packages/api/src/endpoints/anthropic/helpers.ts
  • packages/api/src/endpoints/anthropic/llm.spec.ts
  • packages/api/src/endpoints/models.spec.ts
  • packages/api/src/endpoints/models.ts
  • packages/api/src/files/documents/crud.spec.ts
  • packages/api/src/files/documents/crud.ts
  • packages/api/src/files/encode/document.spec.ts
  • packages/api/src/files/encode/document.ts
  • packages/api/src/files/index.ts
  • packages/api/src/files/mistral/crud.ts
  • packages/api/src/files/rag.spec.ts
  • packages/api/src/files/rag.ts
  • packages/api/src/files/validation.spec.ts
  • packages/api/src/files/validation.ts
  • packages/api/src/mcp/ConnectionsRepository.ts
  • packages/api/src/mcp/MCPConnectionFactory.ts
  • packages/api/src/mcp/MCPManager.ts
  • packages/api/src/mcp/UserConnectionManager.ts
  • packages/api/src/mcp/__tests__/ConnectionsRepository.test.ts
  • packages/api/src/mcp/__tests__/MCPConnection.test.ts
  • packages/api/src/mcp/__tests__/MCPConnectionAgentLifecycle.test.ts
  • packages/api/src/mcp/__tests__/MCPConnectionFactory.test.ts
  • packages/api/src/mcp/__tests__/MCPManager.test.ts
  • packages/api/src/mcp/__tests__/zod.spec.ts
  • packages/api/src/mcp/connection.ts
  • packages/api/src/mcp/oauth/OAuthReconnectionManager.test.ts
  • packages/api/src/mcp/oauth/OAuthReconnectionManager.ts
  • packages/api/src/mcp/registry/MCPServerInspector.ts
  • packages/api/src/mcp/registry/MCPServersRegistry.ts
  • packages/api/src/mcp/registry/__tests__/MCPServerInspector.test.ts
  • packages/api/src/mcp/types/index.ts
  • packages/api/src/mcp/zod.ts
  • packages/api/src/middleware/__tests__/concurrency.cache_integration.spec.ts
  • packages/api/src/middleware/concurrency.ts
  • packages/api/src/oauth/csrf.spec.ts
  • packages/api/src/oauth/csrf.ts
  • packages/api/src/oauth/index.ts
  • packages/api/src/stream/GenerationJobManager.ts
  • packages/api/src/stream/__tests__/GenerationJobManager.stream_integration.spec.ts
  • packages/api/src/stream/__tests__/RedisEventTransport.stream_integration.spec.ts
  • packages/api/src/stream/__tests__/RedisJobStore.stream_integration.spec.ts
  • packages/api/src/stream/__tests__/collectedUsage.spec.ts
  • packages/api/src/stream/__tests__/reconnect-reorder-desync.stream_integration.spec.ts
  • packages/api/src/stream/implementations/InMemoryEventTransport.ts
  • packages/api/src/stream/implementations/RedisEventTransport.ts
  • packages/api/src/stream/implementations/RedisJobStore.ts
  • packages/api/src/stream/interfaces/IJobStore.ts
  • packages/api/src/tools/definitions.ts
  • packages/api/src/tools/format.spec.ts
  • packages/api/src/tools/format.ts
  • packages/api/src/types/files.ts
  • packages/api/src/types/http.ts
  • packages/api/src/utils/oidc.spec.ts
  • packages/api/src/utils/tokens.ts
  • packages/client/package.json
  • packages/client/src/components/OGDialogTemplate.tsx
  • packages/client/src/components/Radio.tsx
  • packages/client/src/components/ThemeSelector.tsx
  • packages/client/src/theme/atoms/themeAtoms.ts
  • packages/client/src/theme/context/ThemeProvider.tsx
  • packages/data-provider/package.json
  • packages/data-provider/react-query/package.json
  • packages/data-provider/specs/actions.spec.ts
  • packages/data-provider/specs/bedrock.spec.ts
  • packages/data-provider/specs/parsers.spec.ts
  • packages/data-provider/src/actions.ts
  • packages/data-provider/src/api-endpoints.ts
  • packages/data-provider/src/bedrock.ts
  • packages/data-provider/src/config.ts
  • packages/data-provider/src/data-service.ts
  • packages/data-provider/src/file-config.ts
  • packages/data-provider/src/mcp.ts
  • packages/data-provider/src/models.ts
  • packages/data-provider/src/parameterSettings.ts
  • packages/data-provider/src/parsers.ts
  • packages/data-provider/src/schemas.ts
  • packages/data-provider/src/types.ts
  • packages/data-provider/src/types/files.ts
  • packages/data-schemas/package.json
  • packages/data-schemas/src/models/plugins/mongoMeili.spec.ts
  • packages/data-schemas/src/models/plugins/mongoMeili.ts
  • turbo.json

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/per-user-model-list

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant