Skip to content

fix(api): authenticate /product, bind user_id to principal, clamp doc_path - #2227

Open
Evenss wants to merge 5 commits into
MemTensor:mainfrom
Evenss:fix-product-auth
Open

fix(api): authenticate /product, bind user_id to principal, clamp doc_path#2227
Evenss wants to merge 5 commits into
MemTensor:mainfrom
Evenss:fix-product-auth

Conversation

@Evenss

@Evenss Evenss commented Aug 6, 2026

Copy link
Copy Markdown

Description

Fixes the four issues reported in #2202, staying within the scope of the issue's Suggested change.

  1. /product is unauthenticated — the router now declares dependencies=[Depends(verify_api_key)], so every current and future endpoint under it requires a key.
  2. Auth is off by defaultAUTH_ENABLED now defaults to true. The two health endpoints parse the same variable independently, so their defaults were flipped too; a startup warning is logged when auth is on but MASTER_KEY_HASH is unset.
  3. user_id is client-supplied (IDOR) — new resolve_authorized_user_id() binds a non-privileged principal to its own user ID (an API key's user_name is the Product API user ID it may act as). Applied to the 17 /product endpoints that accept a caller-supplied user ID; the remaining endpoints have no user ID to bind, so they are authenticated but not further restricted. Master key / internal-service / admin principals keep acting for any user. With auth disabled, the identity is now pinned to MOS_USER_ID instead of the client-supplied X-User-Name.
  4. doc_path reads arbitrary files, and None == None internal bypass_get_all_documents confines doc_path to MEMOS_DOC_ROOT (falling back to FILE_LOCAL_PATH), re-resolving each matched file so symlinks cannot escape; local library usage with neither variable set is unchanged. is_internal_request no longer trusts the source IP and requires both the secret and the header to be non-empty, compared with hmac.compare_digest.

api_analyzer.py is a passive adaptation — it calls the endpoint functions in-process and must now pass an explicit internal auth.

Related Issue (Required): Fixes #2202

Breaking changes

  • Deployments that do not set AUTH_ENABLED will start rejecting unauthenticated requests. MASTER_KEY_HASH was added to both docker/.env.example files; note server_api.py does not mount admin_router, so the master key is the only bootstrap path on the base server.
  • API keys with a non-null expires_at will now always fail to authenticate. lookup_api_key compares a datetime against time.time(), and the TypeError is swallowed into a return None. It is pre-existing and fails closed, so it is left for a separate fix, but default-on auth makes it reachable.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How Has This Been Tested?

  • Unit Test

9 regression cases, one per issue item. The fixtures in test_server_router.py and test_cube_endpoints.py now supply an admin key, since their pre-existing cases would otherwise all return 401.

$ poetry run pytest tests/api/test_auth.py tests/api/test_server_router.py tests/api/test_cube_endpoints.py -q
37 passed in 9.71s

$ poetry run pytest tests/mem_os/test_memos_core.py -q -k DocumentPathConfinement
3 passed, 24 deselected in 8.18s

$ make format
All checks passed!

test_mos_init_invalid_user and the four test_mcp_serve.py import errors fail identically at the base commit and are unrelated.

Checklist

  • I have performed a self-review of my own code | 我已自行检查了自己的代码
  • I have commented my code in hard-to-understand areas | 我已在难以理解的地方对代码进行了注释
  • I have added tests that prove my fix is effective or that my feature works | 我已添加测试以证明我的修复有效或功能正常
  • I have created related documentation issue/PR in MemOS-Docs (if applicable) | 我已在 MemOS-Docs 中创建了相关的文档 issue/PR(如果适用)
  • I have linked the issue to this PR (if applicable) | 我已将 issue 链接到此 PR
  • I have mentioned the person who will review this PR | 我已提及将审查此 PR 的人

Evenss and others added 5 commits July 20, 2026 17:50
Add optional OceanBase / seekdb backends reusing the existing BaseVecDB
and BaseGraphDB contracts, without changing any default behavior.

- vec_dbs/oceanbase.py: OceanBaseVecDB on top of pyseekdb's Collection API,
  serving General Memory; require a positive vector_dimension in config.
- graph_dbs/oceanbase.py: OceanBaseGraphDB ported from the postgres backend
  (nodes + edges + JSON + VECTOR) over the MySQL-compatible protocol, with a
  thread-safe connection pool, atomic multi-step deletes, and identifier
  whitelisting (table_prefix / search_filter keys).
- Register "oceanbase" / "seekdb" aliases in the vec/graph factories and
  config factories; add GraphDBError; declare the optional "ob-mem" extra.
- Add contract tests for both providers.
…ection handling

- Updated pyseekdb version constraints in pyproject.toml to restrict to <1.5.0.
- Increased default embedding dimension in APIConfig from 768 to 1024.
- Improved connection handling in OceanBaseGraphDB and OceanBaseVecDB to ensure better resource management and error handling.
- Added validation for table prefix length in OceanBaseGraphDB to prevent identifier overflow.
- Enhanced logging for empty password configurations in OceanBaseGraphDB.
- Updated tests to reflect changes in search behavior and connection management.
… isolation

- Default AUTH_ENABLED to true and add MASTER_KEY_HASH env configuration.
- Require API key on all /product routes and bind user-scoped parameters to the authenticated principal.
- Replace IP-based internal request trust with a constant-time X-Internal-Service secret check.
- Confine document enumeration to MEMOS_DOC_ROOT / FILE_LOCAL_PATH to prevent path traversal.
- Add security regression tests for auth, user scoping, and document path confinement.
@Memtensor-AI Memtensor-AI added area:api 云服务 / FastAPI / OpenAPI / MCP area:core MOS 编排层 / 框架底座 / 跨模块问题 area:database graph_db + vector_db | 图数据库与向量数据库 area:scheduler 调度模块 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:api 云服务 / FastAPI / OpenAPI / MCP area:core MOS 编排层 / 框架底座 / 跨模块问题 area:database graph_db + vector_db | 图数据库与向量数据库 area:scheduler 调度模块 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/product REST surface is unauthenticated by default; user_id is client-supplied (cross-user IDOR) and doc_path reads arbitrary server files

3 participants