@@ -785,6 +785,7 @@ async def embed(
785785
786786 log .info (f'generate_ollama_batch_embeddings { form_data } ' )
787787 await check_model_access (user , await Models .get_model_by_id (form_data .model ), BYPASS_MODEL_ACCESS_CONTROL )
788+ await validate_ollama_backend_idx (request , form_data .model , url_idx , user )
788789
789790 if url_idx is None :
790791 model = form_data .model
@@ -837,6 +838,7 @@ async def embeddings(
837838
838839 log .info (f'generate_ollama_embeddings { form_data } ' )
839840 await check_model_access (user , await Models .get_model_by_id (form_data .model ), BYPASS_MODEL_ACCESS_CONTROL )
841+ await validate_ollama_backend_idx (request , form_data .model , url_idx , user )
840842
841843 if url_idx is None :
842844 model = form_data .model
@@ -896,6 +898,7 @@ async def generate_completion(
896898 raise HTTPException (status_code = 503 , detail = ERROR_MESSAGES .OLLAMA_API_DISABLED )
897899
898900 await check_model_access (user , await Models .get_model_by_id (form_data .model ), BYPASS_MODEL_ACCESS_CONTROL )
901+ await validate_ollama_backend_idx (request , form_data .model , url_idx , user )
899902
900903 if url_idx is None :
901904 await get_all_models (request , user = user )
@@ -954,7 +957,21 @@ class GenerateChatCompletionForm(BaseModel):
954957 model_config = ConfigDict (extra = 'allow' )
955958
956959
957- async def get_ollama_url (request : Request , model : str , url_idx : int | None = None ):
960+ async def validate_ollama_backend_idx (request : Request , model : str , url_idx : int | None , user ) -> None :
961+ # A caller-supplied url_idx must point to a backend the model is actually
962+ # served from; the None path is already constrained to that allow-list.
963+ if url_idx is None or user is None or getattr (user , 'role' , None ) == 'admin' or BYPASS_MODEL_ACCESS_CONTROL :
964+ return
965+ models = request .app .state .OLLAMA_MODELS
966+ if not models or model not in models :
967+ await get_all_models (request , user = user )
968+ models = request .app .state .OLLAMA_MODELS
969+ if url_idx not in (models .get (model ) or {}).get ('urls' , []):
970+ raise HTTPException (status_code = 403 , detail = ERROR_MESSAGES .ACCESS_PROHIBITED )
971+
972+
973+ async def get_ollama_url (request : Request , model : str , url_idx : int | None = None , user = None ):
974+ await validate_ollama_backend_idx (request , model , url_idx , user )
958975 if url_idx is None :
959976 models = request .app .state .OLLAMA_MODELS
960977 if model not in models :
@@ -1026,7 +1043,7 @@ async def generate_chat_completion(
10261043 else :
10271044 await check_model_access (user , None , bypass_filter )
10281045
1029- url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx )
1046+ url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx , user )
10301047 api_config = _resolve_api_config (request , url_idx , url )
10311048
10321049 prefix_id = api_config .get ('prefix_id' )
@@ -1112,7 +1129,7 @@ async def generate_openai_completion(
11121129 else :
11131130 await check_model_access (user , None )
11141131
1115- url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx )
1132+ url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx , user )
11161133 api_config = _resolve_api_config (request , url_idx , url )
11171134
11181135 prefix_id = api_config .get ('prefix_id' )
@@ -1169,7 +1186,7 @@ async def generate_openai_chat_completion(
11691186 else :
11701187 await check_model_access (user , None )
11711188
1172- url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx )
1189+ url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx , user )
11731190 api_config = _resolve_api_config (request , url_idx , url )
11741191
11751192 prefix_id = api_config .get ('prefix_id' )
@@ -1218,7 +1235,7 @@ async def generate_anthropic_messages(
12181235 else :
12191236 await check_model_access (user , None )
12201237
1221- url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx )
1238+ url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx , user )
12221239 api_config = request .app .state .config .OLLAMA_API_CONFIGS .get (
12231240 str (url_idx ),
12241241 request .app .state .config .OLLAMA_API_CONFIGS .get (url , {}), # Legacy support
@@ -1276,7 +1293,7 @@ async def generate_responses(
12761293 else :
12771294 await check_model_access (user , None )
12781295
1279- url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx )
1296+ url , url_idx = await get_ollama_url (request , payload ['model' ], url_idx , user )
12801297 api_config = request .app .state .config .OLLAMA_API_CONFIGS .get (
12811298 str (url_idx ),
12821299 request .app .state .config .OLLAMA_API_CONFIGS .get (url , {}), # Legacy support
0 commit comments