infiniflow / infiniflow/ragflow

[Question]: Does the user_id binding to JWT principal (v0.25.3 #14745) apply to API Key callers? It seems to break server-to-server integration scenarios

Open
#17,516 3 comments 1 reaction 0 assignees View on GitHub
🙋‍♀️ question
Dominant language
Go
Stars
91k
Forks
10.8k
Avg merge
1d 14h
Merged PRs (30d)
705

Description

### Self Checks

- [x] I have searched for existing issues [search for existing issues](https://github.com/infiniflow/ragflow/issues), including closed ones.
- [x] I confirm that I am using English to submit this report ([Language Policy](https://github.com/infiniflow/ragflow/issues/5910)).
- [x] Non-english title submitions will be closed directly ( 非英文标题的提交将会被直接关闭 ) ([Language Policy](https://github.com/infiniflow/ragflow/issues/5910)).
- [x] Please do not modify this template :) and fill in all the required fields.

### Describe your problem

I'm raising this as a question because I want to understand whether the user_id security binding introduced in v0.25.3 (PR #14745) was intended to cover the API Key authentication scenario, or if this is an oversight.
My team integrates RAGFlow purely as a backend AI service behind our own application. The architecture is straightforward: our Spring Boot backend manages everything related to users — authentication, authorization, session management, privacy compliance — and calls RAGFlow via HTTP API using a single API Key. RAGFlow is never directly exposed to end users. From our perspective, RAGFlow is a stateless knowledge base and inference engine; our backend is the trusted authority on who the user is.
This setup was working well until we upgraded to v0.25.3+. After the upgrade, we discovered that the user_id parameter in POST /api/v1/chats/{chat_id}/sessions is silently overridden by the JWT principal. For API Key callers, the JWT principal resolves to the API Key owner's tenant_id — which is always the same value (our admin account). The externally provided user_id is discarded entirely.
This creates a fundamental problem for us: with a single API Key serving 10,000+ end users, all sessions are now tagged with the same user_id. We can no longer associate a session with a specific user, which means we cannot:
List sessions belonging to a particular user (everyone's sessions are mixed together)
Isolate conversation history between users (privacy concern)
Delete a specific user's data when they request it (GDPR compliance)
I understand the security motivation behind #14745 — preventing users from impersonating each other through the web UI by forging user_id. That makes complete sense for the RAGFlow-native authentication flow, where users log in with their own JWT tokens and the server needs to ensure they can't pretend to be someone else.
But for the API Key scenario, the trust model is fundamentally different. The caller is not an end user — it's a backend server that has already authenticated the user through its own mechanism. The API Key itself is the proof of authorization. Forcing user_id to always be the same tenant_id doesn't add any security in this context; it just makes it impossible to distinguish between end users. The two scenarios seem worth distinguishing:
User JWT Token authentication (RAGFlow web UI): binding user_id to the token principal is correct and necessary.
API Key authentication (third-party backend): the caller is a trusted server that should be allowed to specify which user it's acting on behalf of.
Currently the API documentation still lists user_id as an optional parameter for session creation, which made this even harder to diagnose — we spent significant time debugging why sessions weren't being associated with the correct users before discovering through release notes that the parameter is silently ignored.
So my questions are:
Was the API Key integration scenario specifically considered when implementing #14745, or was the focus primarily on the web UI security?
Is the current behavior (silently overriding user_id for all callers including API Key) intentional, or could it be refined to differentiate between the two authentication modes?
If overriding is the permanent policy, would RAGFlow consider providing an alternative field — such as external_user_id or a generic metadata object — so that third-party integrators can still associate sessions with their own users?
For now we've resorted to storing user IDs in the name field as a workaround, which technically works but feels fragile and semantically wrong. I'd appreciate any clarification on the intended direction here, as it significantly affects how third-party systems can architect their integration with RAGFlow.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing PR #14745, the v0.25.3 release notes, and the POST /api/v1/chats/{chat_id}/sessions API documentation to compare JWT and API Key behavior. Confirm whether API Key callers are intentionally bound to the key owner's tenant_id, then document the intended policy or define a supported way to preserve external user identity.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, spring-boot
Domain
api, authentication, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.