chore(auth): harden invite-link onboarding token flow#26843
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
be4ae2e to
8205e24
Compare
Greptile SummaryThis PR hardens the invite-link onboarding flow to fix Confidence Score: 5/5Safe to merge — the security fix is correctly implemented with proper TOCTOU protection, rollback on key-mint failure, and frontend guard against a missing session token. No P0 or P1 issues found. All concerns from previous review threads are addressed in the current code. The one new observation is a P2 style inconsistency between the pre-flight check and the transaction guard condition. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/proxy_server.py | Core security fix: GET /onboarding/get_token now mints a 15-min onboarding JWT instead of a live session key; POST /onboarding/claim_token uses an atomic update_many + transaction to prevent TOCTOU races; rollback helper resets invite state on key-mint failure |
| tests/test_litellm/proxy/auth/test_onboarding.py | Comprehensive new tests covering missing onboarding token, wrong session binding, invalid bearer, concurrent-reuse prevention, rollback on key-mint failure, and the happy path; mocks are correctly isolated and do not weaken existing coverage |
| ui/litellm-dashboard/src/app/onboarding/OnboardingForm.tsx | Frontend now reads the session token from the claim response (data.token) rather than the pre-claim jwtToken; correctly surfaces a claim error when data.token is absent instead of silently setting an unusable cookie |
| ui/litellm-dashboard/src/app/onboarding/OnboardingForm.test.tsx | New test for missing-token error path validates the cookie is not set and the error message is rendered; existing tests unchanged |
Reviews (3): Last reviewed commit: "chore(auth): drop generated dashboard ou..." | Re-trigger Greptile
a9db887
into
BerriAI:litellm_internal_staging
- BerriAI/litellm#26843 (merge-after-nits) — invite-link onboarding token hardening - google-gemini/gemini-cli#26067 (merge-after-nits) — JetBrains alt-buffer respects user setting - QwenLM/qwen-code#3622 (merge-as-is) — rewind E2E assertion update post isRealUserTurn - QwenLM/qwen-code#3609 (merge-after-nits) — zero-width-space placeholder unification - aaif-goose/goose#8796 (merge-as-is) — newSession _meta wire-protocol field rename
Relevant issues
Addresses
GHSA-2hg5-37xr-3pgm/ invite-link token minting finding.Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewType
🐛 Bug Fix
✅ Test
Changes
GET /onboarding/get_tokenaccepted an invitation id and immediately minted a live UI session virtual key for the invited user. If an invite URL leaked, a caller could decode the returned UI JWT and use the embeddedsk-...key before completing the password claim flow.This PR moves key minting out of invite lookup and into the one-time password claim path.
Three changes:
GET /onboarding/get_tokennow returns a 15-minute signed onboarding JWT bound to the invite id and user id. It does not mint a LiteLLM virtual key.POST /onboarding/claim_tokenrequires that onboarding JWT, reserves the invite withupdate_many(... is_accepted=False ...)inside the password-claim transaction, writes the password, marks the invite accepted, and only then mints the finallitellm-dashboardUI session key.Files
litellm/proxy/proxy_server.py,ui/litellm-dashboard/src/app/onboarding/OnboardingForm.tsxtests/test_litellm/proxy/auth/test_onboarding.pylitellm/proxy/_experimental/out/so the proxy-served static UI matches the dashboard source changeBehaviour notes for operators
/onboarding/get_tokenis no longer a usable LiteLLM key.Validation
uv run black litellm/proxy/proxy_server.py tests/test_litellm/proxy/auth/test_onboarding.pyuv run ruff check litellm/proxy/proxy_server.py tests/test_litellm/proxy/auth/test_onboarding.pyuv run pytest tests/test_litellm/proxy/auth/test_onboarding.py -q./node_modules/.bin/vitest run src/app/onboarding/OnboardingForm.test.tsxNPM_CONFIG_MIN_RELEASE_AGE=0 npm run buildcd litellm && uv run mypy .