* feat(proxy): add OpenSearch index pass-through with per-key read/write grants
Adds /opensearch/<index>/<api> for LiteLLM vector store indexes on OpenSearch
stores. A key or team needs read or write on the index in
allowed_vector_store_indexes, and the proxy signs each call with the vector
store's AWS identity, so callers never hold AWS credentials
The route maps the LiteLLM index name to the store's provider index, refuses
any path, query parameter, or body field that could reach another index, and
sends the exact signed bytes upstream with only the signed headers
* fix(proxy): let OpenSearch _bulk and _msearch NDJSON bodies through auth
opensearch-py sends _bulk and _msearch NDJSON with content-type application/json, and the
auth-time body read parsed it as one JSON document and answered 400 before the route ran.
Auth now skips parsing OpenSearch NDJSON bodies the same way it skips Azure Speech audio.
* feat(proxy): accept a _bulk _index naming the path index and allow named search pipelines
A _bulk action line may name the index in the URL path, and LiteLLM rewrites it to the
real index, which is what opensearch-py's helpers.bulk sends. The search_pipeline query
param now goes through so hybrid search works, while an inline pipeline stays refused.
Also types the type-checking Router stub with _router_init's parameters again, which
make lint's tests/e2e check needs since the Rust core change.
* fix(opensearch): answer 401 when the AWS credential source cannot read its token file
* refactor(proxy): check OpenSearch request bodies without recursive helpers
* fix(opensearch): answer 401 when AWS credentials fail to refresh at signing time
* fix(opensearch): keep auth off OpenSearch bodies and widen the read list to index checks
Auth no longer parses any OpenSearch request body, so a document field named model, api_base or base_url is written
instead of answering 401 or 403. GET and HEAD on the index and HEAD on _doc and _source are reads, each operation
checks the exact grant the list names, an index whose store name two stores share answers 400, and an _msearch
header that names the path index is sent to the mapped index
* fix(opensearch): need read for writes that return documents and keep document fields out of LiteLLM params
* fix(opensearch): keep documents out of LiteLLM hooks, keep main's credential statuses, make _msearch admin only, and bill only searches
* fix(proxy): bill only an exact /opensearch/<index>/_search path
A document read such as /opensearch/docs/_doc/_search ended in /_search and was counted as a billable search. The check now matches the index segment and _search exactly
* fix(proxy): only proxy admins set vector store index grants, and bill no OpenSearch document call
An index grant now opens document writes through /opensearch, so key generate, update, bulk update,
regenerate, team new and update, /user/new, and bulk user creation answer 403 when a non-admin
changes allowed_vector_store_indexes, top-level or under metadata. Resending the stored grants is not a change
An /opensearch path is matched before the LLM route suffixes, so a document id such as search or
embeddings never makes a document call count as a billable request
* fix(proxy): treat an empty index grant list from a non-admin as a change
An explicit empty top-level allowed_vector_store_indexes passed the admin-only check as unchanged and then
replaced the stored grants. It now counts as a change, so a non-admin gets 403. The new grant tests also
carry parameter types
---------
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
* 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