Repository: meta-llama/llama-stack
File: src/llama_stack/core/routers/inference.py (Python)

Code before:
        # Handles cases where clients use the provider format directly
        return await self._get_provider_by_fallback(model_id, expected_model_type)

    async def _get_provider_by_fallback(self, model_id: str, expected_model_type: str) -> tuple[Inference, str]:
        """
        Handle fallback case where model_id is in provider_id/provider_resource_id format.
        """
        splits = model_id.split("/", maxsplit=1)
        if len(splits) != 2:
            raise ModelNotFoundError(model_id)

        provider_id, provider_resource_id = splits

        # Check if provider exists
        if provider_id not in self.routing_table.impls_by_provider_id:
            logger.warning(f"Provider {provider_id} not found for model {model_id}")
            raise ModelNotFoundError(model_id)

        # Create a temporary model object for RBAC check
        temp_model = ModelWithOwner(
            identifier=model_id,
            provider_id=provider_id,
            provider_resource_id=provider_resource_id,
            model_type=expected_model_type,
            type="model",
            metadata={},  # Empty metadata for temporary object
        )

        # Perform RBAC check
        user = get_authenticated_user()
        if not is_action_allowed(self.routing_table.policy, "read", temp_model, user):
            logger.debug(
                f"Access denied to model '{model_id}' via fallback path for user {user.principal if user else 'anonymous'}"
            )
            raise ModelNotFoundError(model_id)

        return self.routing_table.impls_by_provider_id[provider_id], provider_resource_id

    async def rerank(
        self,
        model: str,
        query: str | OpenAIChatCompletionContentPartTextParam | OpenAIChatCompletionContentPartImageParam,
        items: list[str | OpenAIChatCompletionContentPartTextParam | OpenAIChatCompletionContentPartImageParam],
        max_num_results: int | None = None,
    ) -> RerankResponse:
        logger.debug(f"InferenceRouter.rerank: {model}")
        provider, provider_resource_id = await self._get_model_provider(model, ModelType.rerank)
        return await provider.rerank(provider_resource_id, query, items, max_num_results)

    async def openai_completion(
        self,

Review comment (bug):
With no `owner` and empty `metadata`, does that have an impact on our RBAC policies? Will this cause checks to pass that should otherwise fail? Or checks to fail that should otherwise pass?

Code after:
        # Handles cases where clients use the provider format directly
        return await self._get_provider_by_fallback(model_id, expected_model_type)

    async def _get_provider_by_fallback(self, model_id: str, expected_model_type: str) -> tuple[Inference, str]:
        """
        Handle fallback case where model_id is in provider_id/provider_resource_id format.
        """
        splits = model_id.split("/", maxsplit=1)
        if len(splits) != 2:
            raise ModelNotFoundError(model_id)

        provider_id, provider_resource_id = splits

        # Check if provider exists
        if provider_id not in self.routing_table.impls_by_provider_id:
            logger.warning(f"Provider {provider_id} not found for model {model_id}")
            raise ModelNotFoundError(model_id)

        # Create a temporary model object for RBAC check
        temp_model = ModelWithOwner(
            identifier=model_id,
            provider_id=provider_id,
            provider_resource_id=provider_resource_id,
            model_type=expected_model_type,
            metadata={},  # Empty metadata for temporary object
        )

        # Perform RBAC check
        user = get_authenticated_user()
        if not is_action_allowed(self.routing_table.policy, "read", temp_model, user):
            logger.debug(
                f"Access denied to model '{model_id}' via fallback path for user {user.principal if user else 'anonymous'}"
            )
            raise ModelNotFoundError(model_id)

        return self.routing_table.impls_by_provider_id[provider_id], provider_resource_id

    async def rerank(
        self,
        model: str,
        query: str | OpenAIChatCompletionContentPartTextParam | OpenAIChatCompletionContentPartImageParam,
        items: list[str | OpenAIChatCompletionContentPartTextParam | OpenAIChatCompletionContentPartImageParam],
        max_num_results: int | None = None,
    ) -> RerankResponse:
        logger.debug(f"InferenceRouter.rerank: {model}")
        provider, provider_resource_id = await self._get_model_provider(model, ModelType.rerank)
        return await provider.rerank(provider_resource_id, query, items, max_num_results)

    async def openai_completion(
        self,
        params: Annotated[OpenAICompletionRequestWithExtraBody, Body(...)],