diff --git a/apisix/plugins/ai-rag.lua b/apisix/plugins/ai-rag.lua index 88f4e99c2231..73b3ebfa050b 100644 --- a/apisix/plugins/ai-rag.lua +++ b/apisix/plugins/ai-rag.lua @@ -25,6 +25,8 @@ local protocols = require("apisix.plugins.ai-protocols") local azure_openai_embeddings = require("apisix.plugins.ai-rag.embeddings.azure_openai").schema local azure_ai_search_schema = require("apisix.plugins.ai-rag.vector-search.azure_ai_search").schema +local fetch_secrets = require("apisix.secret").fetch_secrets + local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR local HTTP_BAD_REQUEST = ngx.HTTP_BAD_REQUEST @@ -116,6 +118,9 @@ function _M.access(conf, ctx) local vector_search_driver = require("apisix.plugins.ai-rag.vector-search." .. vector_search_provider) + embeddings_provider_conf = fetch_secrets(embeddings_provider_conf, true) + vector_search_provider_conf = fetch_secrets(vector_search_provider_conf, true) + local vs_req_schema = vector_search_driver.request_schema local emb_req_schema = embeddings_driver.request_schema diff --git a/docs/en/latest/plugins/ai-rag.md b/docs/en/latest/plugins/ai-rag.md index fe1130ddffb4..828eb56d5848 100644 --- a/docs/en/latest/plugins/ai-rag.md +++ b/docs/en/latest/plugins/ai-rag.md @@ -53,7 +53,7 @@ The Plugin supports using [Azure OpenAI](https://azure.microsoft.com/en-us/produ | `vector_search_provider` | object | True | | | Vector search provider configurations. | | `vector_search_provider.azure_ai_search` | object | True | | | Configurations of [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search). | | `vector_search_provider.azure_ai_search.endpoint` | string | True | | | Azure AI Search endpoint. | -| `vector_search_provider.azure_ai_search.api_key` | string | True | | | Azure AI Search API key. | +| `vector_search_provider.azure_ai_search.api_key` | string | True | | | Azure AI Search API key. Supports [secret references](../terminology/secret.md) via environment variables (e.g. `$ENV://AI_RAG_APIKEY`) and secret managers. | ## Request Body Format @@ -390,3 +390,24 @@ You should receive an `HTTP/1.1 200 OK` response similar to the following: } } ``` + +## Secret References + +The `api_key` fields support APISIX secret resolution, via environment variable and secret manager. For secret reference formats and setup, see [APISIX Secret](../terminology/secret.md). Example: + +```json +{ + "embeddings_provider": { + "azure_openai": { + "endpoint": "'"$AZ_EMBEDDINGS_ENDPOINT"'", + "api_key": "$ENV://API_KEY" + } + }, + "vector_search_provider": { + "azure_ai_search": { + "endpoint": "'"$AZ_AI_SEARCH_ENDPOINT"'", + "api_key": "$secret://$manager/$id/$secret_name/$key" + } + } +} +``` diff --git a/docs/zh/latest/plugins/ai-rag.md b/docs/zh/latest/plugins/ai-rag.md index 7adffdbf2f59..72a29facc82a 100644 --- a/docs/zh/latest/plugins/ai-rag.md +++ b/docs/zh/latest/plugins/ai-rag.md @@ -53,7 +53,7 @@ import TabItem from '@theme/TabItem'; | `vector_search_provider` | object | 是 | | | 向量搜索提供商的配置。 | | `vector_search_provider.azure_ai_search` | object | 是 | | | [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search) 的配置。 | | `vector_search_provider.azure_ai_search.endpoint` | string | 是 | | | Azure AI Search 端点。 | -| `vector_search_provider.azure_ai_search.api_key` | string | 是 | | | Azure AI Search API 密钥。 | +| `vector_search_provider.azure_ai_search.api_key` | string | 是 | | | Azure AI Search API 密钥。支持通过环境变量(如 `$ENV://AI_RAG_APIKEY`)和密钥管理器进行[密钥引用](../terminology/secret.md)。 | ## 请求体格式 @@ -390,3 +390,24 @@ curl "http://127.0.0.1:9080/rag" -X POST \ } } ``` + +## 密钥引用 + +`api_key` 字段支持通过环境变量和密钥管理器进行 APISIX 密钥解析。有关密钥引用格式和设置,请参阅 [APISIX 密钥](../terminology/secret.md)。示例: + +```json +{ + "embeddings_provider": { + "azure_openai": { + "endpoint": "'"$AZ_EMBEDDINGS_ENDPOINT"'", + "api_key": "$ENV://API_KEY" + } + }, + "vector_search_provider": { + "azure_ai_search": { + "endpoint": "'"$AZ_AI_SEARCH_ENDPOINT"'", + "api_key": "$secret://$manager/$id/$secret_name/$key" + } + } +} +``` diff --git a/t/plugin/ai-rag.t b/t/plugin/ai-rag.t index 240ef7c8a7f5..b23cbcbbda10 100644 --- a/t/plugin/ai-rag.t +++ b/t/plugin/ai-rag.t @@ -41,6 +41,12 @@ add_block_preprocessor(sub { $block->set_value("request", "GET /t"); } + my $main_config = $block->main_config // <<_EOC_; + env AI_RAG_APIKEY=key; +_EOC_ + + $block->set_value("main_config", $main_config); + my $http_config = $block->http_config // <<_EOC_; server { listen 3623; @@ -596,3 +602,60 @@ false done --- error_log ai_rag ssl_verify: false + + + +=== TEST 18: configure plugin with api_key via nginx env directive secret reference +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/echo", + "plugins": { + "ai-rag": { + "embeddings_provider": { + "azure_openai": { + "endpoint": "http://localhost:3623/embeddings", + "api_key": "$ENV://AI_RAG_APIKEY" + } + }, + "vector_search_provider": { + "azure_ai_search": { + "endpoint": "http://localhost:3623/search", + "api_key": "$ENV://AI_RAG_APIKEY" + } + } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + }, + "scheme": "http", + "pass_host": "node" + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 19: send request with api_key resolved from environment variable +--- request +POST /echo +{"ai_rag":{"vector_search":{"fields":"something"},"embeddings":{"input":"which service is good for devops"}}} +--- error_code: 200 +--- response_body eval +qr/\{"messages":\[\{"content":"passed","role":"user"\}\]\}|\{"messages":\[\{"role":"user","content":"passed"\}\]\}/