Skip to content

fix(api): strip Bearer scheme so keyed requests reach per-key rate-limit bucket (#2428) - #2490

Open
RerankerGuo wants to merge 1 commit into
MemTensor:dev-v2.0.36from
RerankerGuo:fix/issue-2428-rate-limit-bearer
Open

RerankerGuo wants to merge 1 commit into
MemTensor:dev-v2.0.36from
RerankerGuo:fix/issue-2428-rate-limit-bearer

Conversation

@RerankerGuo

Copy link
Copy Markdown
Contributor

Summary

_get_client_key in src/memos/api/middleware/rate_limit.py tested whether request.headers["Authorization"] started with krlk_, but real clients send Authorization: Bearer krlk_<hex> per RFC 6750. The prefix check never matched and every request — including ones carrying a valid API key — fell through to IP-based limiting.

Root cause

auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("krlk_"):    # ← false for "Bearer krlk_..."
    return f"ratelimit:key:{auth_header[:20]}"

Real Authorization values are Bearer <token>; the Bearer prefix is what made this branch unreachable. Behind a shared egress IP all keyed clients shared one bucket and the per-key rate-limit was dead code.

Fix

Strip the Bearer scheme (case-insensitive, per RFC 7235) before the prefix check, so Bearer krlk_<hex> correctly maps to ratelimit:key:<first 20 of stripped key>. Backwards compatibility is preserved: a bare krlk_<hex> header still matches.

Tests

New tests/api/test_rate_limit_bearer.py, 7 cases:

  1. test_bearer_krlk_key_uses_per_key_bucket — red against unpatched main, green with the fix
  2. test_bearer_krlk_key_first_twenty_chars_of_actual_key — confirms the key slice
  3. test_lowercase_bearer_scheme — RFC 7235 case-insensitivity
  4. test_bearer_with_non_key_token_falls_back_to_ip — non-API-key Bearer tokens still go to IP
  5. test_missing_authorization_header_falls_back_to_ip
  6. test_x_forwarded_for_header_preferred_over_ip
  7. test_krlk_prefix_without_bearer_scheme_still_matches — backwards compat

Verification

PYTHONPATH=src pytest tests/api/test_rate_limit_bearer.py -v
============================== 7 passed in 2.50s ==============================

Ruff: ruff format --check and ruff check both clean on the touched test file; the source file has the same 2 pre-existing BLE001 findings as on main (this PR introduces 0 new lint issues).

Out of scope

  • No new dependencies
  • No public API / OpenAPI contract changes
  • No DB schema, migration, or graph model changes
  • No Makefile / pyproject.toml / pre-commit / GitHub workflow changes

Closes #2428

…mit bucket (MemTensor#2428)

_get_client_key in src/memos/api/middleware/rate_limit.py tested
whether request.headers['Authorization'] started with 'krlk_', but real
clients send 'Authorization: Bearer krlk_<hex>' per RFC 6750. The prefix
check never matched and every request — including ones carrying a valid
API key — fell through to IP-based limiting. Behind a shared egress IP
all keyed clients shared one bucket, so the per-key rate-limit was dead.

The fix strips the 'Bearer ' scheme (case-insensitive, per RFC 7235)
before the prefix check, so 'Bearer krlk_<hex>' correctly maps to
'ratelimit:key:<first 20 of stripped key>'. Backwards compatibility is
preserved: a bare 'krlk_<hex>' header still matches.

- New tests/api/test_rate_limit_bearer.py with 7 cases covering Bearer
  prefix, lowercase bearer, non-key Bearer tokens, missing header,
  X-Forwarded-For preference, and the bare-krlk_ backwards-compat path.
- No new imports, no new dependencies, no public API change.

Fixes MemTensor#2428.
@Memtensor-AI Memtensor-AI added area:api 云服务 / FastAPI / OpenAPI / MCP status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Oct 13, 2026
@Memtensor-AI

Copy link
Copy Markdown
Collaborator

🤖 Open Code Review

Target: PR #2490
Task: d13801ae958edc1d
Base: dev-v2.0.36
Head: fix/issue-2428-rate-limit-bearer

✅ OpenCodeReview: Review partially complete: 0 finding(s); 1 of 2 selected item(s) failed.

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

✅ Automated Test Results: PASSED

All tests passed (7/7 executed). memos_python_core/changed-repo-python: 7/7. Duration: 9s

Branch: fix/issue-2428-rate-limit-bearer

@Memtensor-AI Memtensor-AI added status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 and removed status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Oct 13, 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 status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants