Commit graph

5 commits

Author SHA1 Message Date
Mateo Wang
4867a56e9a
fix(proxy)!: reject client-supplied Vertex location and project unless the admin opts in (#47028)
* fix(proxy): reject client-supplied Vertex location and project unless the admin opts in

A request body could carry vertex_location, vertex_project, or their
vertex_ai_* aliases and override the region and project pinned on a
Vertex AI deployment, sending the admin's credentials to a caller-chosen
project or region. Add the four fields to the banned request params so
they need allow_client_side_credentials or configurable_clientside_auth_params.

/vertex_ai/live and /rag/ingest name their Vertex project and location
by design and have no deployment pin to override, so they keep those two
fields while every other banned param is still rejected there

* fix(proxy): close the remaining Vertex target overrides and keep inert fields working

/vertex_ai/live now closes with 1008 when the query names a project or location that differs from a use_in_pass_through deployment's pin, unless that deployment or the proxy opts in

A model group's opt-in now counts only when every deployment in it carries it, and Google-style routes look the opt-in up on the model named in the URL

Vertex target names inside metadata, the live route's vertex_ai_* aliases, and /health/test_connection inheritance go back to the base behavior, since nothing reads them as a target

* test(batches): give the batch FakeRouter the model-list lookup the opt-in check reads

* fix(proxy): pin default_vertex_config on /vertex_ai/live and the proxy's Vertex project on /rag/ingest

* fix(proxy): require the Vertex opt-in on alias targets and fallbacks, and pass the live rewriter flag in main's tests

* test(proxy): give the batch tests' fake router the alias and routed-group lookups

* fix(proxy): close the Vertex opt-in, RAG corpus, and live setup-frame gaps found in review

A Vertex opt-in now counts only when every group the request can reach opts in, router,
context window, and content policy fallbacks and one alias hop included, while a group
with no Google deployment never needs the fields. A model named in the route path is
checked next to the body model.

RAG ingest from a non-admin key refuses a bare or dot-segment corpus id, a
vertex_ai_project or vertex_ai_location naming another target, and a store a non-admin
saved before the upgrade, and reads a corpus named by project number on the proxy's
own project.

/vertex_ai/live closes 1008 on any caller-named project when the proxy pins none, moves
a setup frame sent as a binary message onto the session's target, and resolves the
region from default_vertex_config before the model path.

* fix(proxy): let a live caller name the proxy's configured Vertex project when nothing pins one

With default_vertex_config set but no project pinned, /vertex_ai/live closed every query that named a project,
including the one the admin set in VERTEXAI_PROJECT or DEFAULT_VERTEXAI_PROJECT. A query naming one of those
projects now connects, and any other project still closes with 1008 before a token is minted.

* fix(proxy): keep an admin-created vector store's corpus as saved on RAG ingest

A non-admin ingest into a store an admin created named by project number had its corpus moved onto
the proxy's own project before the admin-store exemption ran, so the upload went to a different
corpus than the admin saved. The exemption now runs first, and a non-admin store still gets the
project-number rewrite and the target check.

* fix(proxy): authorize a RAG corpus moved onto the proxy's project and check client-side opt-ins once per request

* fix(proxy): merge opt-in fallback groups only when their deployments share provider and opt-in list

* fix(proxy): check team public models before allowing target overrides

* fix(proxy): include team wildcard targets in opt-in checks

* fix(proxy): validate overrides against authenticated team routes

* fix(proxy): retain URL model during deferred credential checks
2026-11-10 20:50:17 +00:00
tavren27
96b916028a
fix(proxy)!: return managed file ids from rag ingest and use team credentials on vector store file routes (#50459)
* fix(proxy): give rag ingest managed file ids and team credentials on vector store file routes

RAG ingest through a team's OpenAI deployment now registers the uploaded file as a LiteLLM managed file and returns its managed id, so GET /v1/files lists it for the caller. Re-ingesting a managed id attaches the provider file and returns the caller's managed id

Model-less vector store file calls (create, list, retrieve, content, update, delete) from a team key now use the team's OpenAI deployment that ingest uploads through, via the router, and fall back to the direct path when the key may not use one. Explicit api_key, api_base, litellm_credential_name, and forwarded provider keys still win, and blank values count as absent

* fix(proxy): route managed vector store file ids to their team deployment and keep missing-file 404s off the router

Model-less team vector store file calls now go straight to the provider with the team deployment's
credentials, so 404s on missing files no longer put the team deployment in cooldown.

A managed file id on the vector store file routes now uses the deployment named by its
llm_output_file_model_id when that deployment is proxy-wide or belongs to the caller's team, and falls
back to target_model_names otherwise.

* fix(rag): keep managed ids and team checks on every file and search path

Ingest no longer registers a raw file id when file_url is empty, a managed
file id on a proxy without the managed files hook answers 400, and vector
store search and /v1/rag/query hits show the managed id ingest returned.

Model-less vector store file calls use the team deployment only after the
key, team, and member model checks pass, fall through to the router when the
team has no OpenAI deployment, and log the deployment they used.

* fix(rag): keep provider ids on lookup failures and mint managed ids only for keys that can use them

A database error while mapping search hits to managed ids keeps OpenAI's ids instead of failing a finished search. Ingest registers a managed id only when the caller passes the team deployment's model checks, so a model-limited key keeps the raw id it can still use, and the file routes share that check.

* fix(rag): attach the managed file copy that matches the ingest credentials

* fix(vector_store_files): route a managed file id to the caller team's copy

* fix(vector_store_files): keep the upload copy for a store registered with its own credentials

* fix(vector_store_files): use a managed file's team copy only when the store holds it

* fix(vector_store_files): attach a managed file's team copy and keep named credential options out of the store check

* fix(vector_store_files): attach the team copy only to a store that routes to the team deployment

* fix(vector_store_files): keep a managed store's routing and check the upload copy through its own deployment

* fix(vector_store_files): route a managed file to its upload deployment only when the key may call it

A managed file id names its upload deployment, and with require_managed_files off that id is not checked against an ownership record. The routes now use that deployment only when the caller may call its public model, else they keep target_model_names routing as on main.

* fix(vector_store_files): log a pinned managed file call under its deployment's public model name

* fix(vector_store_files): send a pinned managed file call's deployment key only to that deployment's base

* fix(vector_store_files): keep stored credential headers intact and fail the store check on errors other than 404

* fix(vector_store_files): answer a failed store check with the provider status and copy credentials read by name

* fix(vector_store_files): send a call to the upload copy when the store check fails without a 404

A store check error other than a 404 now leaves the call on the upload copy, the way main always routed it, so the real call keeps the router's retries, the provider's status, and its failure log instead of failing on one transient error

* fix(vector_store_files): keep a credential's no-log key out of the store check

A named credential carrying a no-log key made the store check call aretrieve with no-log twice, so every managed id call through that deployment answered 500 where main answered 200

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-11-10 05:44:28 +00:00
Mateo Wang
77064d6c70
feat(vector_stores): add OpenSearch k-NN search as a vector store provider (#47759)
* feat(vector_stores): add Amazon OpenSearch as a vector store provider

* feat(ui): add Amazon OpenSearch to the vector store provider dropdown

* feat(vector_stores): add OpenSearch k-NN search as a vector store provider

* test(vector_stores): hold the OpenSearch provider tests alone for the first review

The provider source comes back in the next commits on this PR

* ci(tests): run the OpenSearch vector store unit tests

* fix(vector_stores): sign on.aws and FIPS OpenSearch hosts and reject missing AWS credentials before embedding

* fix(vector_stores): regenerate provider endpoint support for opensearch

* fix(vector_stores): keep opensearch retrieve, update, and delete off the index and refuse half-set AWS keys and per-account endpoints

* fix(vector_stores): return only scalar opensearch attributes and keep credential source output out of 401s

* test(vector_stores): inject a failing opensearch credential source instead of running a shell

* fix(vector_stores): sign opensearch for the endpoint's region, refuse list, add opensearch_index_name, honor drop_params

* fix(vector_stores): refuse a caller-chosen opensearch_index_name on search and rag query

* fix(vector_stores): refuse opensearch_index_name only on OpenSearch stores, keep the old 400 text

Other providers drop the key again as they did before OpenSearch support, and the four embedding keys keep their original error sentence.

* fix(vector_stores): refuse a caller index on slash-form OpenSearch stores
2026-10-29 08:15:05 -07:00
Shivam Rawat
c58fc0c996
fix(rag)!: use team provider credentials and allow viewer and JWT team access (#45497)
* fix(rag): use team provider credentials and allow viewer and JWT team access

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(rag): assert persisted managed store data excludes team credentials

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(jwt): run real team model checks in the route denial test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(rag): scope team provider credentials to openai vector stores

Bedrock and other providers kept their pre-PR credential and region
resolution: a team bedrock deployment's region no longer overrides the
caller's region on RAG query. Query tests now fake the provider at the
HTTP boundary with a real vector store registry.

* fix(rag): use only the team's own OpenAI deployment for RAG credentials

* fix(rag): ignore caller credential fields the query search never uses when picking team credentials

* fix(rag): treat blank credential fields as absent when picking team credentials

* test(rag): delete the stores the integration ingests create before the owned proxy exits

* fix(proxy): let a restricted key use the team deployment its wildcard or model covers

A key restricted to gpt-4o on a team whose own OpenAI deployment is openai/*
never resolved that deployment's credentials, because the key allowlist was
matched against the deployment's public name literally. The allowlist now
matches a wildcard on either side the way request authorization does, through
the auth layer's own helper, so /rag, /files and /batches resolve the team
deployment for every key that may call a model on it.

* fix(batches): read a restricted key's batch input through its team deployment

The batch access check downloaded the input JSONL with the proxy's OPENAI_API_KEY while the upload and the create used the team deployment, so a key restricted under a team openai/* deployment could not create a batch when the two keys belong to different OpenAI projects. The read now resolves the team deployment the way the create does when no model pins it

Adds the audit cells for keys restricted under the team wildcard on /rag, /files and /batches, and for the rag-vs-chat split of a key restricted to a global exact-name deployment

* fix(rag): load deployments oldest first, reject file_id on stores that cannot take one, and show ingest errors in the dashboard

* fix(rag): pick the team deployment with the lowest id, return 400 for caller mistakes, keep the ingest id in errors, and show partial success in the dashboard

* fix(rag): pick the team's oldest OpenAI deployment so adding one never moves the team

* fix(rag): keep config file team deployments first and try JWT teams in sorted order

A team's config file OpenAI deployments now win in file order, as on the
base, before its DB ones oldest first, so upgrading never moves a team that
has both. A JWT in several teams tries them in sorted order, so every worker
resolves the same team.

* fix(rag): return 400 for Bedrock, S3 Vectors and Gemini store config mistakes on ingest

* fix(rag): keep forwarded provider keys on /rag/query and mixed JWT team claims working

A forwarded x-api-key now counts as a caller credential, so the /rag/query
search uses it over the team deployment as at the merge base. Sorting the
JWT team claim compares entries as text, so a stray number or null no
longer turns into a 401. A Gemini store with no proxy key is a 500 again,
and a non-string vector_store_id keeps the merge base's 400 message.

* fix(rag): let a forwarded provider key win over team credentials on files, batches and ingest

* fix(rag): keep team credentials when a request carries its own key or api_base

A forwarded x-api-key or a body api_key now replaces only the key of the team
deployment, keeping its api_base, as chat completions does. A body
litellm_credential_name no longer turns team credentials off on /v1/batches.

* fix(batches): keep the team key on the team host when a request sends only api_base

A request api_base now replaces the team deployment's api_base only when the
request also brings its own api_key, and a non-string api_key or api_base is
ignored, as on the merge base.

* fix(files): ignore a blank request api_key or api_base next to team credentials

* fix(files): answer 400 for a request api_key that cannot be sent as an HTTP header

* fix(rag): honor a body drop_params for a forwarded key that cannot be an HTTP header

* fix(rag): read the request field for drop_params only on multipart ingest bodies

* fix(rag): type the ingest body read for drop_params

* fix(batches): count a model-routed batch's input with the deployment key it is created with

* fix(batches): reject a batch create whose x-litellm-model headers name different models

* fix(rag): treat a null provider and whitespace store credentials as unset when picking team credentials

* refactor(files): type the team deployment the credential resolver ranks

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-10-17 23:51:48 +00:00
devin-ai-integration[bot]
25109a523b
test(proxy): move utils, agent_endpoints and endpoint tests into tests/unit/proxy (#44006)
* test(proxy): move utils, agent_endpoints and endpoint tests into tests/unit/proxy

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(proxy): package moved unit test directories

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(proxy): exclude proxy-db-owned files from the misc target

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(proxy): drop the redundant fixture docstrings in the proxy conftest

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yuneng <yuneng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-01 11:06:42 -07:00