From 392400fe2899d17ff7d63fccc7b3625024c92bec Mon Sep 17 00:00:00 2001 From: Jason Cook Date: Thu, 23 Apr 2026 11:44:41 -0400 Subject: [PATCH] docs: call out STORE_MODEL_IN_DB=True requirement for OAuth credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DB → litellm.credential_list reload that makes OAuth credentials survive a proxy restart lives inside the same ``if store_model_in_db is True:`` block in proxy_server.py as the model-deployment scheduler. Without the env var the write succeeds but nothing reads it back on startup — credentials appear to vanish, and any model with ``api_key: oauth:`` fails at request time. This was caught during deployment testing. Not a new requirement introduced by this PR (the same block gates the standard Add Model UI flow), but easy to miss if you're only thinking about OAuth. Added a prominent note to the CLAUDE.md OAuth section. Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CLAUDE.md b/CLAUDE.md index 7bd8b1afeef..f5b1acf5fb9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -125,6 +125,7 @@ LiteLLM is a unified interface for 100+ LLM providers with two main components: - Use `RecordNotFoundError` (not bare `except Exception`) when catching "already deleted" in credential delete endpoints. ### ChatGPT / Copilot OAuth Credentials +- **`STORE_MODEL_IN_DB=True` is required** for the proxy UI OAuth flow to survive a restart. The `proxy_config.get_credentials(prisma_client)` call that reloads `litellm.credential_list` from `LiteLLM_CredentialsTable` at startup lives inside the same `if store_model_in_db is True:` block as the model-deployment scheduler in `proxy_server.py`. Without the env var: the DB write succeeds, but nothing reads it back — credentials "disappear" on restart, and any model configured with `api_key: oauth:` fails at request time because the name isn't in the in-memory cache. Also needed for the Add Model UI (`STORE_MODEL_IN_DB=True` → `LiteLLM_ProxyModelTable` → `add_deployment` job). The OAuth flow silently no-ops without it; document this prominently when rolling out. - Two providers use OAuth device-code flows with tokens stored in `LiteLLM_CredentialsTable`: `chatgpt` (ChatGPT / Codex backend) and `github_copilot`. Each has an `Authenticator` (filesystem-backed, used by CLI / direct SDK use) and a `DBAuthenticator` subclass (DB-backed, used by the proxy). - **Request-time dispatch**: the convention is `api_key: "oauth:"` in the model's `litellm_params`. When the transformation sees this prefix it resolves via `resolve_authenticator(...)` in `llms/chatgpt/db_authenticator.py` (or `llms/github_copilot/db_authenticator.py`), which swaps in a `DBAuthenticator` bound to that credential. Any other `api_key` falls through to the filesystem authenticator. Do not invent alternative markers — reuse the `oauth:` prefix so both providers stay symmetric. - **Copilot has two use-sites**: `_get_openai_compatible_provider_info` may rewrite `api_key` to the resolved Copilot key before `validate_environment` runs. The Copilot `resolve_authenticator` therefore takes both `api_key` and `litellm_params` and checks both; the ChatGPT version only needs `litellm_params`.