From bfca9598b6fd8c4074104e48ff993e400b85020c Mon Sep 17 00:00:00 2001 From: jbaross Date: Wed, 24 Jun 2026 14:12:35 +0100 Subject: [PATCH 1/6] existing forward proxy content --- .../md/ai-gateway/v2/forward-proxy.md | 5 + app/_kong_plugins/ai-aws-guardrails/index.md | 4 + .../ai-azure-content-safety/index.md | 4 + .../ai-custom-guardrail/index.md | 4 + app/_kong_plugins/ai-gcp-model-armor/index.md | 6 +- app/_kong_plugins/ai-lakera-guard/index.md | 6 +- .../ai-prompt-compressor/index.md | 4 + .../examples/forward-proxy.yaml | 45 ++++ app/_kong_plugins/ai-proxy-advanced/index.md | 6 + app/_kong_plugins/ai-rag-injector/index.md | 4 + app/_kong_plugins/ai-sanitizer/index.md | 4 + app/_kong_plugins/ai-semantic-cache/index.md | 4 + .../ai-semantic-prompt-guard/index.md | 4 + .../ai-semantic-response-guard/index.md | 4 + app/_kong_plugins/forward-proxy/index.md | 4 + app/ai-gateway/forward-proxy.md | 241 ++++++++++++++++++ 16 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 app/_includes/md/ai-gateway/v2/forward-proxy.md create mode 100644 app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml create mode 100644 app/ai-gateway/forward-proxy.md diff --git a/app/_includes/md/ai-gateway/v2/forward-proxy.md b/app/_includes/md/ai-gateway/v2/forward-proxy.md new file mode 100644 index 00000000000..f47cdade1ff --- /dev/null +++ b/app/_includes/md/ai-gateway/v2/forward-proxy.md @@ -0,0 +1,5 @@ +Set `config.proxy_config` on this plugin to route its outbound requests through an HTTP forward proxy. Use this in network-isolated deployments where {{site.ai_gateway}} cannot open direct connections to LLM providers or auxiliary services. + +The `proxy_config` record is identical across all {{site.ai_gateway}} plugins that support forward proxying. Existing capabilities such as load balancing, health checking, streaming, WebSocket, and HTTP/2 continue to work when the proxy is active. + +For the full field reference, traffic flow, and limitations, see [Forward proxy support](/ai-gateway/forward-proxy/). diff --git a/app/_kong_plugins/ai-aws-guardrails/index.md b/app/_kong_plugins/ai-aws-guardrails/index.md index 66a2f97d293..dfbd3a8a602 100644 --- a/app/_kong_plugins/ai-aws-guardrails/index.md +++ b/app/_kong_plugins/ai-aws-guardrails/index.md @@ -93,3 +93,7 @@ The AI AWS Guardrails plugin emits structured log data for every inspected reque To log the raw content of blocked requests and responses, enable [`config.log_blocked_content`](/plugins/ai-aws-guardrails/reference/#schema--config-log-blocked-content). {% new_in 3.14 %} When enabled, the blocked prompt or response body appears under `ai.proxy.aws-guardrails.input_faulty_prompt` and `ai.proxy.aws-guardrails.output_faulty_response` in each log entry. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-azure-content-safety/index.md b/app/_kong_plugins/ai-azure-content-safety/index.md index 52fdf0371b1..b0fd72e775b 100644 --- a/app/_kong_plugins/ai-azure-content-safety/index.md +++ b/app/_kong_plugins/ai-azure-content-safety/index.md @@ -115,3 +115,7 @@ To log the raw content of blocked requests and responses, enable [`config.log_bl This plugin works with all of the AI Proxy plugin's `route_type` settings (excluding the `preserve` mode), and is able to compose an Azure Content Safety text check by compiling all chat history, or just the `'user'` content. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-custom-guardrail/index.md b/app/_kong_plugins/ai-custom-guardrail/index.md index f1a4bada484..a4440c1daf1 100644 --- a/app/_kong_plugins/ai-custom-guardrail/index.md +++ b/app/_kong_plugins/ai-custom-guardrail/index.md @@ -131,3 +131,7 @@ The [`config.metrics`](./reference/#schema--config-metrics) field allows you to * `masked`: Whether content was masked in the request or response. The values can be set to Lua expressions. You can also use the [`config.custom_metrics`](./reference/#schema--config-custom-metrics) field to define additional metrics. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-gcp-model-armor/index.md b/app/_kong_plugins/ai-gcp-model-armor/index.md index ab44e633483..411c7e0cc55 100644 --- a/app/_kong_plugins/ai-gcp-model-armor/index.md +++ b/app/_kong_plugins/ai-gcp-model-armor/index.md @@ -171,4 +171,8 @@ To log the raw content of blocked requests and responses, enable [`config.log_bl * Only chat prompts and chat responses are inspected; embeddings and other modalities are not checked. * Inspects one chat message or one response body at a time. Combining multiple messages reduces accuracy. * For SSE streaming, unsafe content may appear briefly before termination with `"stop_reason: blocked by content safety"`. -* Only one `template_id` can be configured per plugin instance. \ No newline at end of file +* Only one `template_id` can be configured per plugin instance. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-lakera-guard/index.md b/app/_kong_plugins/ai-lakera-guard/index.md index aadba36986e..4187b1f49ed 100644 --- a/app/_kong_plugins/ai-lakera-guard/index.md +++ b/app/_kong_plugins/ai-lakera-guard/index.md @@ -170,4 +170,8 @@ When a request is blocked, the log captures the violation reason, detector detai } } } -``` \ No newline at end of file +``` + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-prompt-compressor/index.md b/app/_kong_plugins/ai-prompt-compressor/index.md index 8db73c546ce..44bd36f6bc4 100644 --- a/app/_kong_plugins/ai-prompt-compressor/index.md +++ b/app/_kong_plugins/ai-prompt-compressor/index.md @@ -215,3 +215,7 @@ sequenceDiagram The AI Prompt Compressor plugin applies structured compression to preserve essential context of prompts sent by users, rather than trimming prompts arbitrarily or risking token overflows. This ensures the LLM receives a well-formed, focused prompt keeping token usage under control. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml b/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml new file mode 100644 index 00000000000..cdf7c548a5f --- /dev/null +++ b/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml @@ -0,0 +1,45 @@ +--- + +title: 'Route inference traffic through a forward proxy' +description: 'Configure AI Proxy Advanced to send outbound inference requests through an HTTP forward proxy for network-isolated deployments.' + +weight: 950 + +group: network + +config: + targets: + - route_type: llm/v1/chat + auth: + header_name: Authorization + header_value: Bearer ${openai_key} + model: + provider: openai + name: gpt-5.1 + proxy_config: + http_proxy_host: proxy.internal + http_proxy_port: 3128 + https_proxy_host: proxy.internal + https_proxy_port: 3128 + proxy_scheme: http + auth_username: ${proxy_user} + auth_password: ${proxy_password} + https_verify: false + +variables: + openai_key: + value: $OPENAI_API_KEY + description: The API key to use to connect to OpenAI. + proxy_user: + value: $FORWARD_PROXY_USER + description: Username for the corporate forward proxy. + proxy_password: + value: $FORWARD_PROXY_PASSWORD + description: Password for the corporate forward proxy. + +tools: + - deck + - admin-api + - konnect-api + - kic + - terraform diff --git a/app/_kong_plugins/ai-proxy-advanced/index.md b/app/_kong_plugins/ai-proxy-advanced/index.md index 4911e5c2b74..16f897b37cd 100644 --- a/app/_kong_plugins/ai-proxy-advanced/index.md +++ b/app/_kong_plugins/ai-proxy-advanced/index.md @@ -71,6 +71,8 @@ examples_groups: text: Native routes - slug: claude-code text: claude-code + - slug: network + text: Network configuration faqs: - q: Can I override `config.model.name` by specifying a different model name in the request? @@ -197,3 +199,7 @@ For setup instructions, see [AI plugin Partials](/gateway/entities/partial/#ai-p {% include_cached /plugins/redis/redis-cloud-auth.md tier=page.tier %} {% include_cached /plugins/redis/enterprise.md name=page.name heading_level=3 %} + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-rag-injector/index.md b/app/_kong_plugins/ai-rag-injector/index.md index 499925a083b..2882483c249 100644 --- a/app/_kong_plugins/ai-rag-injector/index.md +++ b/app/_kong_plugins/ai-rag-injector/index.md @@ -498,3 +498,7 @@ Use the [Admin API](/plugins/ai-rag-injector/api/) to ingest content with metada {% include_cached /plugins/ai-partials-vectordb-embeddings.md %} {% include_cached /plugins/redis/redis-cloud-auth.md tier=page.tier %} + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-sanitizer/index.md b/app/_kong_plugins/ai-sanitizer/index.md index 2c57cca44bf..1e682f0db1a 100644 --- a/app/_kong_plugins/ai-sanitizer/index.md +++ b/app/_kong_plugins/ai-sanitizer/index.md @@ -245,3 +245,7 @@ You can use the following fields in the `anonymize` array: * `custom`: Anonymizes user-defined custom PII patterns using regular expressions only when custom patterns are provided. * `credentials`: Anonymizes the credentials, similar to `/sanitize_credentials`. * `all`: Includes all the fields above, including custom ones. + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-cache/index.md b/app/_kong_plugins/ai-semantic-cache/index.md index 8efb5816bd2..42209878780 100644 --- a/app/_kong_plugins/ai-semantic-cache/index.md +++ b/app/_kong_plugins/ai-semantic-cache/index.md @@ -182,3 +182,7 @@ The plugin respects cache control headers to determine if requests and responses {% include_cached /plugins/redis/redis-cloud-auth.md tier=page.tier %} {% include_cached /plugins/redis/enterprise.md name=page.name heading_level=3 %} + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-prompt-guard/index.md b/app/_kong_plugins/ai-semantic-prompt-guard/index.md index 8612cfc9cd4..29eae890023 100644 --- a/app/_kong_plugins/ai-semantic-prompt-guard/index.md +++ b/app/_kong_plugins/ai-semantic-prompt-guard/index.md @@ -106,3 +106,7 @@ The matching behavior is as follows: {% include_cached /plugins/redis/redis-cloud-auth.md tier=page.tier %} {% include_cached /plugins/redis/enterprise.md name=page.name heading_level=3 %} + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-response-guard/index.md b/app/_kong_plugins/ai-semantic-response-guard/index.md index 89507be12c6..3d646d0941f 100644 --- a/app/_kong_plugins/ai-semantic-response-guard/index.md +++ b/app/_kong_plugins/ai-semantic-response-guard/index.md @@ -101,3 +101,7 @@ To enforce these rules, the plugin: {% include_cached /plugins/redis/redis-cloud-auth.md tier=page.tier %} {% include_cached /plugins/redis/enterprise.md name=page.name heading_level=3 %} + +## Forward proxy support + +{% include ai-gateway/forward-proxy.md %} diff --git a/app/_kong_plugins/forward-proxy/index.md b/app/_kong_plugins/forward-proxy/index.md index 925359dad1a..61a5d185f0c 100644 --- a/app/_kong_plugins/forward-proxy/index.md +++ b/app/_kong_plugins/forward-proxy/index.md @@ -38,6 +38,10 @@ search_aliases: min_version: gateway: '1.0' + +related_resources: + - text: Forward proxy support for {{site.ai_gateway}} + url: /ai-gateway/forward-proxy/ --- The Forward Proxy Advanced plugin allows {{site.base_gateway}} to connect to intermediary transparent HTTP proxies, instead of directly to the `upstream_url`, when forwarding requests upstream. diff --git a/app/ai-gateway/forward-proxy.md b/app/ai-gateway/forward-proxy.md new file mode 100644 index 00000000000..92ee7927691 --- /dev/null +++ b/app/ai-gateway/forward-proxy.md @@ -0,0 +1,241 @@ +--- +title: "Forward proxy support" +content_type: reference +layout: reference + +description: "Route outbound traffic from {{site.ai_gateway}} plugins through a forward proxy to operate in network-isolated environments without breaking load balancing, streaming, WebSocket, or HTTP/2." + +breadcrumbs: + - /ai-gateway/ + +products: + - gateway + - ai-gateway + +works_on: + - on-prem + - konnect + +tools: + - deck + - admin-api + - konnect-api + - kic + +TODO: confirm the minimum Gateway version with engineering before publishing. +min_version: + ai-gateway: '2.0' + +plugins: + - ai-proxy-advanced + - ai-semantic-cache + - ai-semantic-prompt-guard + - ai-semantic-response-guard + - ai-rag-injector + - ai-prompt-compressor + - ai-sanitizer + - ai-aws-guardrails + - ai-azure-content-safety + - ai-lakera-guard + - ai-gcp-model-armor + - ai-custom-guardrail + +tags: + - ai + - network + - security + +related_resources: + - text: "{{site.ai_gateway}}" + url: /ai-gateway/ + - text: AI Proxy Advanced + url: /plugins/ai-proxy-advanced/ +--- + +## What is forward proxy support? + +In network-isolated deployments, {{site.ai_gateway}} cannot open direct outbound connections to LLM providers or auxiliary services. Forward proxy support lets {{site.ai_gateway}} plugins route their outbound requests through a controlled HTTP forward proxy so that inference traffic, semantic operations, and guardrail checks continue to work behind a strict egress policy. + +A shared `proxy_config` record can be added to each {{site.ai_gateway}} plugin that names the proxy host, port, scheme, and optional credentials. When configured, all outbound requests issued by that plugin go through the proxy. Existing capabilities such as [load balancing](/ai-gateway/load-balancing/), health checking, [streaming](/ai-gateway/streaming/), WebSocket, and HTTP/2 continue to work. + +## How forward proxy support works + +{{site.ai_gateway}} plugins issue three categories of outbound request. `proxy_config` applies to all three, using a different mechanism depending on where the request originates. + +The three request categories are: + +- **Inference**: requests from clients to LLM providers, proxied by [AI Proxy Advanced](/plugins/ai-proxy-advanced/) through the native {{site.base_gateway}} upstream path. This is the majority of {{site.ai_gateway}} traffic. Load balancing, health checks, retries, streaming, WebSocket, and HTTP/2 all continue to function when forward proxy support is active. Upstream keepalive is disabled while the forward proxy is active, so inference connections are not reused across requests targeting different upstream peers. +- **Identity auth**: cloud identity authentication issued by provider SDKs. AWS Bedrock SigV4 signing, Azure and GCP managed identity token acquisition, when targets require managed identity. +- **Auxiliary calls**: direct HTTP calls from semantic, RAG, guardrail, sanitizer, and compressor plugins to their external services. For example, an embeddings service, AWS Bedrock Guardrails, Azure Content Safety, Lakera, GCP Model Armor, or a configured custom endpoint. + + +{% mermaid %} +flowchart LR + Client --> AIProxy + Client --> Aux + subgraph Gateway_Group[Kong AI Gateway] + subgraph Plugins[AI Plugins] + AIProxy[AI Proxy Advanced] + Aux[Auxiliary plugins] + end + end + AIProxy -- inference --> Proxy[Forward proxy] + AIProxy -- "identity auth" --> Proxy + Aux -- "auxiliary calls" --> Proxy + Proxy --> LLM[LLM providers] + Proxy --> CloudAPI[Cloud platform APIs] + Proxy --> AuxSvc[Auxiliary services] + style Plugins stroke-dasharray: 5 5 +{% endmermaid %} +> _Figure 1: Outbound traffic from {{site.ai_gateway}} plugins routed through a forward proxy._ + + +When `proxy_config` is set on a plugin, every outbound request that plugin issues goes through the configured proxy. + +## Relationship to the Forward Proxy Advanced plugin + +{{site.base_gateway}} also provides the [Forward Proxy Advanced plugin](/plugins/forward-proxy/) for routing non-AI upstream traffic through an intermediary HTTP proxy. For non-AI services use the Forward Proxy Advanced plugin. + +The Forward Proxy Advanced plugin plugin takes over the request before the balancer phase runs, which works for standard Kong Services but not with behavior that {{site.ai_gateway}} depends on: upstream load balancing, health check reporting, retries, WebSocket upgrades, and HTTP/2 request bodies. + +For any Service that serves traffic through a {{site.ai_gateway}} plugin you should use `proxy_config` instead, so the balancer phase continues to run normally. Load balancing across LLM targets, streaming, real-time API traffic, and HTTP/2 inference requests all remain functional when the forward proxy is active and you have configured `proxy_config`. + +## Supported plugins + +`proxy_config` is set per-plugin. Enabling forward proxy support on AI Proxy Advanced does not apply to other {{site.ai_gateway}} plugins attached to the same Route. You should configure it on every plugin whose external calls need to traverse the forward proxy. + +The following plugins expose `proxy_config`. The record structure and behavior are identical across all of them. + + +{% table %} +columns: + - title: Traffic + key: traffic + - title: Plugins + key: plugins + - title: Proxied destination + key: service +rows: + - traffic: "Inference requests to LLM providers" + plugins: | + - [AI Proxy Advanced](/plugins/ai-proxy-advanced/) + service: "LLM provider APIs" + - traffic: "Embeddings and semantic operations" + plugins: | + - [AI Semantic Cache](/plugins/ai-semantic-cache/) + - [AI Semantic Prompt Guard](/plugins/ai-semantic-prompt-guard/) + - [AI Semantic Response Guard](/plugins/ai-semantic-response-guard/) + - [AI RAG Injector](/plugins/ai-rag-injector/) + service: "The configured embeddings service" + - traffic: "Prompt compression and sanitization" + plugins: | + - [AI Prompt Compressor](/plugins/ai-prompt-compressor/) + - [AI Sanitizer](/plugins/ai-sanitizer/) + service: "The configured `compressor_url` or `sanitizer_url`" + - traffic: "Guardrail services" + plugins: | + - [AI AWS Guardrails](/plugins/ai-aws-guardrails/) + - [AI Azure Content Safety](/plugins/ai-azure-content-safety/) + - [AI Lakera Guard](/plugins/ai-lakera-guard/) + - [AI GCP Model Armor](/plugins/ai-gcp-model-armor/) + - [AI Custom Guardrail](/plugins/ai-custom-guardrail/) + service: "Managed or custom guardrail service" +{% endtable %} + + +## proxy_config fields + +Every plugin in the supported list accepts the same `proxy_config` record at the top level of its `config` block. + + +{% table %} +columns: + - title: Field + key: field + - title: Type + key: type + - title: Description + key: description +rows: + - field: "`http_proxy_host`" + type: "host" + description: "Hostname of the forward proxy used for HTTP upstreams. Must be set together with `http_proxy_port`." + - field: "`http_proxy_port`" + type: "port" + description: "Port of the forward proxy used for HTTP upstreams. Must be set together with `http_proxy_host`." + - field: "`https_proxy_host`" + type: "host" + description: "Hostname of the forward proxy used for HTTPS upstreams. Must be set together with `https_proxy_port`." + - field: "`https_proxy_port`" + type: "port" + description: "Port of the forward proxy used for HTTPS upstreams. Must be set together with `https_proxy_host`." + - field: "`proxy_scheme`" + type: "string" + description: "Scheme used to connect to the forward proxy itself. One of `http` or `https`. Defaults to `http`." + - field: "`auth_username`" + type: "string" + description: "Username for proxy authentication. Optional. Referenceable from a [Vault](/gateway/entities/vault/)." + - field: "`auth_password`" + type: "string" + description: "Password for proxy authentication. Optional. Encrypted at rest and referenceable from a [Vault](/gateway/entities/vault/)." + - field: "`https_verify`" + type: "boolean" + description: "Whether to verify the forward proxy's TLS certificate when `proxy_scheme` is `https`. Defaults to `false`." +{% endtable %} + + +Two validation rules apply to the record: + +- `http_proxy_host` and `http_proxy_port` must both be set or both be absent. +- `https_proxy_host` and `https_proxy_port` must both be set or both be absent. + +{:.info} +> `https_verify` defaults to `false`. When `proxy_scheme` is `https`, set `https_verify: true` in production so the proxy's TLS certificate is validated. + +{:.warning} +> When `proxy_scheme` is `https` and the global `tls_certificate_verify` flag is enabled, `https_verify` cannot be set to `false`. Config load fails. + +## Configuration + +The minimal configuration adds a `proxy_config` block to any supported plugin. The same block applies unchanged across plugins: configure it once per plugin instance that needs to reach external services through the proxy. + +For a complete local setup with a running forward proxy, full decK configuration, and validation steps, see [Route AI Proxy Advanced traffic through a forward proxy](/how-to/route-ai-proxy-advanced-traffic-through-forward-proxy/). + +{% entity_example %} +type: plugin +data: + name: ai-proxy-advanced + config: + targets: + - model: + provider: openai + name: gpt-5.1 + auth: + header_name: Authorization + header_value: Bearer ${openai_key} + route_type: llm/v1/chat + proxy_config: + http_proxy_host: proxy.internal + http_proxy_port: 3128 + https_proxy_host: proxy.internal + https_proxy_port: 3128 + proxy_scheme: http + auth_username: ${proxy_user} + auth_password: ${proxy_password} + https_verify: false +variables: + openai_key: + value: $OPENAI_API_KEY + description: The API key to use to connect to OpenAI. + proxy_user: + value: $FORWARD_PROXY_USER + description: Username for the corporate forward proxy. + proxy_password: + value: $FORWARD_PROXY_PASSWORD + description: Password for the corporate forward proxy. +{% endentity_example %} + +## Limitations + +- Connections to vector databases (such as pgvector, Redis Vector, or Pinecone) use native database protocols rather than HTTP and are not routed through the forward proxy. If these connections must traverse a forward proxy, you should handle it at the network layer. +- The [AI Request Transformer](/plugins/ai-request-transformer/), [AI Response Transformer](/plugins/ai-response-transformer/), and [AI LLM as a Judge](/plugins/ai-llm-as-judge/) plugins keep their existing flat proxy fields (`http_proxy_host`, `http_proxy_port`, `https_proxy_host`, `https_proxy_port`) and do not accept a `proxy_config` record. They do not expose `auth_username`, `auth_password`, `proxy_scheme`, or `https_verify`, so proxy authentication and HTTPS-scheme proxies are unavailable for their traffic. From 329218e9e0b50afad4e1c8204cd7893ec751290c Mon Sep 17 00:00:00 2001 From: jbaross Date: Wed, 24 Jun 2026 14:37:33 +0100 Subject: [PATCH 2/6] fix include path --- app/_kong_plugins/ai-aws-guardrails/index.md | 2 +- app/_kong_plugins/ai-azure-content-safety/index.md | 2 +- app/_kong_plugins/ai-custom-guardrail/index.md | 2 +- app/_kong_plugins/ai-gcp-model-armor/index.md | 2 +- app/_kong_plugins/ai-lakera-guard/index.md | 2 +- app/_kong_plugins/ai-prompt-compressor/index.md | 2 +- app/_kong_plugins/ai-proxy-advanced/index.md | 2 +- app/_kong_plugins/ai-rag-injector/index.md | 2 +- app/_kong_plugins/ai-sanitizer/index.md | 2 +- app/_kong_plugins/ai-semantic-cache/index.md | 2 +- app/_kong_plugins/ai-semantic-prompt-guard/index.md | 2 +- app/_kong_plugins/ai-semantic-response-guard/index.md | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/_kong_plugins/ai-aws-guardrails/index.md b/app/_kong_plugins/ai-aws-guardrails/index.md index dfbd3a8a602..a7513bf3c84 100644 --- a/app/_kong_plugins/ai-aws-guardrails/index.md +++ b/app/_kong_plugins/ai-aws-guardrails/index.md @@ -96,4 +96,4 @@ To log the raw content of blocked requests and responses, enable [`config.log_bl ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-azure-content-safety/index.md b/app/_kong_plugins/ai-azure-content-safety/index.md index b0fd72e775b..be8f3890ffe 100644 --- a/app/_kong_plugins/ai-azure-content-safety/index.md +++ b/app/_kong_plugins/ai-azure-content-safety/index.md @@ -118,4 +118,4 @@ compose an Azure Content Safety text check by compiling all chat history, or jus ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-custom-guardrail/index.md b/app/_kong_plugins/ai-custom-guardrail/index.md index a4440c1daf1..1df0a5975fb 100644 --- a/app/_kong_plugins/ai-custom-guardrail/index.md +++ b/app/_kong_plugins/ai-custom-guardrail/index.md @@ -134,4 +134,4 @@ The values can be set to Lua expressions. You can also use the [`config.custom_m ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-gcp-model-armor/index.md b/app/_kong_plugins/ai-gcp-model-armor/index.md index 411c7e0cc55..c7841caca53 100644 --- a/app/_kong_plugins/ai-gcp-model-armor/index.md +++ b/app/_kong_plugins/ai-gcp-model-armor/index.md @@ -175,4 +175,4 @@ To log the raw content of blocked requests and responses, enable [`config.log_bl ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-lakera-guard/index.md b/app/_kong_plugins/ai-lakera-guard/index.md index 4187b1f49ed..caa5b4beaa2 100644 --- a/app/_kong_plugins/ai-lakera-guard/index.md +++ b/app/_kong_plugins/ai-lakera-guard/index.md @@ -174,4 +174,4 @@ When a request is blocked, the log captures the violation reason, detector detai ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-prompt-compressor/index.md b/app/_kong_plugins/ai-prompt-compressor/index.md index 44bd36f6bc4..f51d6528f0a 100644 --- a/app/_kong_plugins/ai-prompt-compressor/index.md +++ b/app/_kong_plugins/ai-prompt-compressor/index.md @@ -218,4 +218,4 @@ The AI Prompt Compressor plugin applies structured compression to preserve essen ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-proxy-advanced/index.md b/app/_kong_plugins/ai-proxy-advanced/index.md index 16f897b37cd..137de88535e 100644 --- a/app/_kong_plugins/ai-proxy-advanced/index.md +++ b/app/_kong_plugins/ai-proxy-advanced/index.md @@ -202,4 +202,4 @@ For setup instructions, see [AI plugin Partials](/gateway/entities/partial/#ai-p ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-rag-injector/index.md b/app/_kong_plugins/ai-rag-injector/index.md index 2882483c249..9b2f5945074 100644 --- a/app/_kong_plugins/ai-rag-injector/index.md +++ b/app/_kong_plugins/ai-rag-injector/index.md @@ -501,4 +501,4 @@ Use the [Admin API](/plugins/ai-rag-injector/api/) to ingest content with metada ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-sanitizer/index.md b/app/_kong_plugins/ai-sanitizer/index.md index 1e682f0db1a..e20ffb250f9 100644 --- a/app/_kong_plugins/ai-sanitizer/index.md +++ b/app/_kong_plugins/ai-sanitizer/index.md @@ -248,4 +248,4 @@ You can use the following fields in the `anonymize` array: ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-cache/index.md b/app/_kong_plugins/ai-semantic-cache/index.md index 42209878780..26bd1774919 100644 --- a/app/_kong_plugins/ai-semantic-cache/index.md +++ b/app/_kong_plugins/ai-semantic-cache/index.md @@ -185,4 +185,4 @@ The plugin respects cache control headers to determine if requests and responses ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-prompt-guard/index.md b/app/_kong_plugins/ai-semantic-prompt-guard/index.md index 29eae890023..2ec981afb37 100644 --- a/app/_kong_plugins/ai-semantic-prompt-guard/index.md +++ b/app/_kong_plugins/ai-semantic-prompt-guard/index.md @@ -109,4 +109,4 @@ The matching behavior is as follows: ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} diff --git a/app/_kong_plugins/ai-semantic-response-guard/index.md b/app/_kong_plugins/ai-semantic-response-guard/index.md index 3d646d0941f..2e869999cfd 100644 --- a/app/_kong_plugins/ai-semantic-response-guard/index.md +++ b/app/_kong_plugins/ai-semantic-response-guard/index.md @@ -104,4 +104,4 @@ To enforce these rules, the plugin: ## Forward proxy support -{% include ai-gateway/forward-proxy.md %} +{% include md/ai-gateway/v2/forward-proxy.md %} From 0dd9239071b5ec075eaa6e0a79048c8e43ab8b44 Mon Sep 17 00:00:00 2001 From: jbaross Date: Wed, 24 Jun 2026 15:00:10 +0100 Subject: [PATCH 3/6] clean up frontmatter --- .../examples/forward-proxy.yaml | 4 ---- app/ai-gateway/forward-proxy.md | 23 +------------------ 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml b/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml index cdf7c548a5f..d9979b12d0c 100644 --- a/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml +++ b/app/_kong_plugins/ai-proxy-advanced/examples/forward-proxy.yaml @@ -38,8 +38,4 @@ variables: description: Password for the corporate forward proxy. tools: - - deck - - admin-api - konnect-api - - kic - - terraform diff --git a/app/ai-gateway/forward-proxy.md b/app/ai-gateway/forward-proxy.md index 92ee7927691..76e027642db 100644 --- a/app/ai-gateway/forward-proxy.md +++ b/app/ai-gateway/forward-proxy.md @@ -9,37 +9,18 @@ breadcrumbs: - /ai-gateway/ products: - - gateway - ai-gateway works_on: - - on-prem - konnect tools: - - deck - - admin-api - konnect-api - - kic -TODO: confirm the minimum Gateway version with engineering before publishing. + min_version: ai-gateway: '2.0' -plugins: - - ai-proxy-advanced - - ai-semantic-cache - - ai-semantic-prompt-guard - - ai-semantic-response-guard - - ai-rag-injector - - ai-prompt-compressor - - ai-sanitizer - - ai-aws-guardrails - - ai-azure-content-safety - - ai-lakera-guard - - ai-gcp-model-armor - - ai-custom-guardrail - tags: - ai - network @@ -48,8 +29,6 @@ tags: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: AI Proxy Advanced - url: /plugins/ai-proxy-advanced/ --- ## What is forward proxy support? From ddcc217932f5dafb0c795d4ce9d7f9ffb8609cf3 Mon Sep 17 00:00:00 2001 From: jbaross Date: Thu, 25 Jun 2026 09:25:12 +0100 Subject: [PATCH 4/6] cleanup --- app/ai-gateway/forward-proxy.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/ai-gateway/forward-proxy.md b/app/ai-gateway/forward-proxy.md index 76e027642db..c532f5aadc9 100644 --- a/app/ai-gateway/forward-proxy.md +++ b/app/ai-gateway/forward-proxy.md @@ -176,9 +176,8 @@ Two validation rules apply to the record: ## Configuration -The minimal configuration adds a `proxy_config` block to any supported plugin. The same block applies unchanged across plugins: configure it once per plugin instance that needs to reach external services through the proxy. +The minimal configuration adds a `proxy_config` block to any supported Policy. The same block applies unchanged across Policies: configure it once per Policy instance that needs to reach external services through the proxy. -For a complete local setup with a running forward proxy, full decK configuration, and validation steps, see [Route AI Proxy Advanced traffic through a forward proxy](/how-to/route-ai-proxy-advanced-traffic-through-forward-proxy/). {% entity_example %} type: plugin From 68629cea746e92836683a414673b4b4815332520 Mon Sep 17 00:00:00 2001 From: jbaross Date: Thu, 25 Jun 2026 16:29:00 +0100 Subject: [PATCH 5/6] plugin to policy --- app/ai-gateway/forward-proxy.md | 72 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/app/ai-gateway/forward-proxy.md b/app/ai-gateway/forward-proxy.md index c532f5aadc9..bba986a858a 100644 --- a/app/ai-gateway/forward-proxy.md +++ b/app/ai-gateway/forward-proxy.md @@ -3,7 +3,7 @@ title: "Forward proxy support" content_type: reference layout: reference -description: "Route outbound traffic from {{site.ai_gateway}} plugins through a forward proxy to operate in network-isolated environments without breaking load balancing, streaming, WebSocket, or HTTP/2." +description: "Route outbound traffic from {{site.ai_gateway}} Policies through a forward proxy to operate in network-isolated environments without breaking load balancing, streaming, WebSocket, or HTTP/2." breadcrumbs: - /ai-gateway/ @@ -33,19 +33,19 @@ related_resources: ## What is forward proxy support? -In network-isolated deployments, {{site.ai_gateway}} cannot open direct outbound connections to LLM providers or auxiliary services. Forward proxy support lets {{site.ai_gateway}} plugins route their outbound requests through a controlled HTTP forward proxy so that inference traffic, semantic operations, and guardrail checks continue to work behind a strict egress policy. +In network-isolated deployments, {{site.ai_gateway}} cannot open direct outbound connections to LLM providers or auxiliary services. Forward proxy support lets {{site.ai_gateway}} Policys route their outbound requests through a controlled HTTP forward proxy so that inference traffic, semantic operations, and guardrail checks continue to work behind a strict egress policy. -A shared `proxy_config` record can be added to each {{site.ai_gateway}} plugin that names the proxy host, port, scheme, and optional credentials. When configured, all outbound requests issued by that plugin go through the proxy. Existing capabilities such as [load balancing](/ai-gateway/load-balancing/), health checking, [streaming](/ai-gateway/streaming/), WebSocket, and HTTP/2 continue to work. +A shared `proxy_config` record can be added to each {{site.ai_gateway}} Policy that names the proxy host, port, scheme, and optional credentials. When configured, all outbound requests issued by that Policy go through the proxy. Existing capabilities such as [load balancing](/ai-gateway/load-balancing/), health checking, [streaming](/ai-gateway/streaming/), WebSocket, and HTTP/2 continue to work. ## How forward proxy support works -{{site.ai_gateway}} plugins issue three categories of outbound request. `proxy_config` applies to all three, using a different mechanism depending on where the request originates. +{{site.ai_gateway}} Policies issue three categories of outbound request. `proxy_config` applies to all three, using a different mechanism depending on where the request originates. The three request categories are: -- **Inference**: requests from clients to LLM providers, proxied by [AI Proxy Advanced](/plugins/ai-proxy-advanced/) through the native {{site.base_gateway}} upstream path. This is the majority of {{site.ai_gateway}} traffic. Load balancing, health checks, retries, streaming, WebSocket, and HTTP/2 all continue to function when forward proxy support is active. Upstream keepalive is disabled while the forward proxy is active, so inference connections are not reused across requests targeting different upstream peers. +- **Inference**: requests from clients to LLM providers, proxied by [AI Proxy Advanced](ai-gateway/policies/ai-proxy-advanced/) through the native {{site.base_gateway}} upstream path. This is the majority of {{site.ai_gateway}} traffic. Load balancing, health checks, retries, streaming, WebSocket, and HTTP/2 all continue to function when forward proxy support is active. Upstream keepalive is disabled while the forward proxy is active, so inference connections are not reused across requests targeting different upstream peers. - **Identity auth**: cloud identity authentication issued by provider SDKs. AWS Bedrock SigV4 signing, Azure and GCP managed identity token acquisition, when targets require managed identity. -- **Auxiliary calls**: direct HTTP calls from semantic, RAG, guardrail, sanitizer, and compressor plugins to their external services. For example, an embeddings service, AWS Bedrock Guardrails, Azure Content Safety, Lakera, GCP Model Armor, or a configured custom endpoint. +- **Auxiliary calls**: direct HTTP calls from semantic, RAG, guardrail, sanitizer, and compressor Policies to their external services. For example, an embeddings service, AWS Bedrock Guardrails, Azure Content Safety, Lakera, GCP Model Armor, or a configured custom endpoint. {% mermaid %} @@ -53,9 +53,9 @@ flowchart LR Client --> AIProxy Client --> Aux subgraph Gateway_Group[Kong AI Gateway] - subgraph Plugins[AI Plugins] + subgraph Policies[AI Policies] AIProxy[AI Proxy Advanced] - Aux[Auxiliary plugins] + Aux[Auxiliary Policies] end end AIProxy -- inference --> Proxy[Forward proxy] @@ -64,67 +64,67 @@ flowchart LR Proxy --> LLM[LLM providers] Proxy --> CloudAPI[Cloud platform APIs] Proxy --> AuxSvc[Auxiliary services] - style Plugins stroke-dasharray: 5 5 + style Policies stroke-dasharray: 5 5 {% endmermaid %} -> _Figure 1: Outbound traffic from {{site.ai_gateway}} plugins routed through a forward proxy._ +> _Figure 1: Outbound traffic from {{site.ai_gateway}} Policies routed through a forward proxy._ -When `proxy_config` is set on a plugin, every outbound request that plugin issues goes through the configured proxy. +When `proxy_config` is set on a Policy, every outbound request that Policy issues goes through the configured proxy. ## Relationship to the Forward Proxy Advanced plugin {{site.base_gateway}} also provides the [Forward Proxy Advanced plugin](/plugins/forward-proxy/) for routing non-AI upstream traffic through an intermediary HTTP proxy. For non-AI services use the Forward Proxy Advanced plugin. -The Forward Proxy Advanced plugin plugin takes over the request before the balancer phase runs, which works for standard Kong Services but not with behavior that {{site.ai_gateway}} depends on: upstream load balancing, health check reporting, retries, WebSocket upgrades, and HTTP/2 request bodies. +The Forward Proxy Advanced plugin takes over the request before the balancer phase runs, which works for standard Kong Services but not with behavior that {{site.ai_gateway}} depends on: upstream load balancing, health check reporting, retries, WebSocket upgrades, and HTTP/2 request bodies. -For any Service that serves traffic through a {{site.ai_gateway}} plugin you should use `proxy_config` instead, so the balancer phase continues to run normally. Load balancing across LLM targets, streaming, real-time API traffic, and HTTP/2 inference requests all remain functional when the forward proxy is active and you have configured `proxy_config`. +For any Service that serves traffic through a {{site.ai_gateway}} Policy you should use `proxy_config` instead, so the balancer phase continues to run normally. Load balancing across LLM targets, streaming, real-time API traffic, and HTTP/2 inference requests all remain functional when the forward proxy is active and you have configured `proxy_config`. -## Supported plugins +## Supported Policies -`proxy_config` is set per-plugin. Enabling forward proxy support on AI Proxy Advanced does not apply to other {{site.ai_gateway}} plugins attached to the same Route. You should configure it on every plugin whose external calls need to traverse the forward proxy. +`proxy_config` is set per-Policy. Enabling forward proxy support on AI Proxy Advanced does not apply to other {{site.ai_gateway}} Policies attached to the same Route. You should configure it on every Policy whose external calls need to traverse the forward proxy. -The following plugins expose `proxy_config`. The record structure and behavior are identical across all of them. +The following Policies expose `proxy_config`. The record structure and behavior are identical across all of them. {% table %} columns: - title: Traffic key: traffic - - title: Plugins - key: plugins + - title: Policies + key: policies - title: Proxied destination key: service rows: - traffic: "Inference requests to LLM providers" - plugins: | - - [AI Proxy Advanced](/plugins/ai-proxy-advanced/) + policies: | + - [AI Proxy Advanced](ai-gateway/policies/ai-proxy-advanced/) service: "LLM provider APIs" - traffic: "Embeddings and semantic operations" - plugins: | - - [AI Semantic Cache](/plugins/ai-semantic-cache/) - - [AI Semantic Prompt Guard](/plugins/ai-semantic-prompt-guard/) - - [AI Semantic Response Guard](/plugins/ai-semantic-response-guard/) - - [AI RAG Injector](/plugins/ai-rag-injector/) + policies: | + - [AI Semantic Cache](ai-gateway/policies/ai-semantic-cache/) + - [AI Semantic Prompt Guard](ai-gateway/policies/ai-semantic-prompt-guard/) + - [AI Semantic Response Guard](ai-gateway/policies/ai-semantic-response-guard/) + - [AI RAG Injector](ai-gateway/policies/ai-rag-injector/) service: "The configured embeddings service" - traffic: "Prompt compression and sanitization" - plugins: | - - [AI Prompt Compressor](/plugins/ai-prompt-compressor/) - - [AI Sanitizer](/plugins/ai-sanitizer/) + policies: | + - [AI Prompt Compressor](ai-gateway/policies/ai-prompt-compressor/) + - [AI Sanitizer](ai-gateway/policies/ai-sanitizer/) service: "The configured `compressor_url` or `sanitizer_url`" - traffic: "Guardrail services" - plugins: | - - [AI AWS Guardrails](/plugins/ai-aws-guardrails/) - - [AI Azure Content Safety](/plugins/ai-azure-content-safety/) - - [AI Lakera Guard](/plugins/ai-lakera-guard/) - - [AI GCP Model Armor](/plugins/ai-gcp-model-armor/) - - [AI Custom Guardrail](/plugins/ai-custom-guardrail/) + policies: | + - [AI AWS Guardrails](ai-gateway/policies/ai-aws-guardrails/) + - [AI Azure Content Safety](ai-gateway/policies/ai-azure-content-safety/) + - [AI Lakera Guard](ai-gateway/policies/ai-lakera-guard/) + - [AI GCP Model Armor](ai-gateway/policies/ai-gcp-model-armor/) + - [AI Custom Guardrail](ai-gateway/policies/ai-custom-guardrail/) service: "Managed or custom guardrail service" {% endtable %} ## proxy_config fields -Every plugin in the supported list accepts the same `proxy_config` record at the top level of its `config` block. +Every Policy in the supported list accepts the same `proxy_config` record at the top level of its `config` block. {% table %} @@ -216,4 +216,4 @@ variables: ## Limitations - Connections to vector databases (such as pgvector, Redis Vector, or Pinecone) use native database protocols rather than HTTP and are not routed through the forward proxy. If these connections must traverse a forward proxy, you should handle it at the network layer. -- The [AI Request Transformer](/plugins/ai-request-transformer/), [AI Response Transformer](/plugins/ai-response-transformer/), and [AI LLM as a Judge](/plugins/ai-llm-as-judge/) plugins keep their existing flat proxy fields (`http_proxy_host`, `http_proxy_port`, `https_proxy_host`, `https_proxy_port`) and do not accept a `proxy_config` record. They do not expose `auth_username`, `auth_password`, `proxy_scheme`, or `https_verify`, so proxy authentication and HTTPS-scheme proxies are unavailable for their traffic. +- The [AI Request Transformer](ai-gateway/policies/ai-request-transformer/), [AI Response Transformer](ai-gateway/policies/ai-response-transformer/), and [AI LLM as a Judge](ai-gateway/policies/ai-llm-as-judge/) Policies keep their existing flat proxy fields (`http_proxy_host`, `http_proxy_port`, `https_proxy_host`, `https_proxy_port`) and do not accept a `proxy_config` record. They do not expose `auth_username`, `auth_password`, `proxy_scheme`, or `https_verify`, so proxy authentication and HTTPS-scheme proxies are unavailable for their traffic. From 61057dd05c88e5d1132f98eb7461087ab64222e2 Mon Sep 17 00:00:00 2001 From: jbaross Date: Thu, 25 Jun 2026 16:30:50 +0100 Subject: [PATCH 6/6] sync with release branch --- .../ai-gateway-migration-review/SKILL.md | 213 ++ .github/workflows/automated-tests.yaml | 2 +- app/_ai_gateway_policies/ace/index.md | 9 + app/_ai_gateway_policies/acl/index.md | 9 + app/_ai_gateway_policies/acme/index.md | 10 + .../ai-aws-guardrails/index.md | 9 + .../ai-azure-content-safety/index.md | 9 + .../ai-custom-guardrail/index.md | 9 + .../ai-gcp-model-armor/index.md | 9 + .../ai-lakera-guard/index.md | 9 + .../ai-llm-as-judge/index.md | 9 + .../ai-mcp-oauth2/index.md | 9 + .../ai-prompt-compressor/index.md | 9 + .../ai-prompt-decorator/index.md | 9 + .../ai-prompt-guard/index.md | 9 + .../ai-prompt-template/index.md | 9 + .../ai-rag-injector/index.md | 9 + .../ai-rate-limiting-advanced/index.md | 9 + .../ai-request-transformer/index.md | 9 + .../ai-response-transformer/index.md | 9 + .../ai-sanitizer/index.md | 9 + .../ai-semantic-cache/index.md | 9 + .../ai-semantic-prompt-guard/index.md | 9 + .../ai-semantic-response-guard/index.md | 9 + .../app-dynamics/index.md | 10 + app/_ai_gateway_policies/aws-lambda/index.md | 10 + .../azure-functions/index.md | 10 + app/_ai_gateway_policies/basic-auth/index.md | 9 + .../bot-detection/index.md | 9 + app/_ai_gateway_policies/canary/index.md | 9 + .../confluent-consume/index.md | 9 + app/_ai_gateway_policies/confluent/index.md | 9 + .../correlation-id/index.md | 9 + app/_ai_gateway_policies/cors/index.md | 9 + app/_ai_gateway_policies/datadog/index.md | 9 + app/_ai_gateway_policies/datakit/index.md | 9 + app/_ai_gateway_policies/degraphql/index.md | 9 + .../exit-transformer/index.md | 9 + app/_ai_gateway_policies/file-log/index.md | 9 + .../forward-proxy/index.md | 10 + .../graphql-proxy-cache-advanced/index.md | 10 + .../graphql-rate-limiting-advanced/index.md | 9 + .../grpc-gateway/index.md | 9 + app/_ai_gateway_policies/grpc-web/index.md | 9 + .../header-cert-auth/index.md | 9 + app/_ai_gateway_policies/hmac-auth/index.md | 9 + app/_ai_gateway_policies/http-log/index.md | 9 + .../injection-protection/index.md | 9 + .../ip-restriction/index.md | 9 + app/_ai_gateway_policies/jq/index.md | 9 + .../json-threat-protection/index.md | 9 + app/_ai_gateway_policies/jwe-decrypt/index.md | 9 + app/_ai_gateway_policies/jwt-signer/index.md | 9 + app/_ai_gateway_policies/jwt/index.md | 9 + .../kafka-consume/index.md | 9 + app/_ai_gateway_policies/kafka-log/index.md | 9 + .../kafka-upstream/index.md | 9 + .../key-auth-enc/index.md | 9 + app/_ai_gateway_policies/key-auth/index.md | 9 + .../ldap-auth-advanced/index.md | 9 + app/_ai_gateway_policies/ldap-auth/index.md | 9 + app/_ai_gateway_policies/loggly/index.md | 9 + .../metering-and-billing/index.md | 9 + app/_ai_gateway_policies/mocking/index.md | 9 + app/_ai_gateway_policies/mtls-auth/index.md | 9 + .../oas-validation/index.md | 9 + .../oauth2-introspection/index.md | 10 + app/_ai_gateway_policies/oauth2/index.md | 9 + app/_ai_gateway_policies/opa/index.md | 9 + .../openid-connect/index.md | 10 + .../opentelemetry/index.md | 9 + .../post-function/index.md | 9 + .../pre-function/index.md | 9 + app/_ai_gateway_policies/prometheus/index.md | 10 + .../proxy-cache-advanced/index.md | 9 + app/_ai_gateway_policies/proxy-cache/index.md | 9 + .../rate-limiting-advanced/index.md | 9 + .../rate-limiting/index.md | 9 + app/_ai_gateway_policies/redirect/index.md | 9 + .../request-callout/index.md | 9 + .../request-size-limiting/index.md | 9 + .../request-termination/index.md | 9 + .../request-transformer-advanced/index.md | 9 + .../request-transformer/index.md | 9 + .../request-validator/index.md | 9 + .../response-ratelimiting/index.md | 9 + .../response-transformer-advanced/index.md | 9 + .../response-transformer/index.md | 9 + .../route-by-header/index.md | 9 + .../route-transformer-advanced/index.md | 9 + app/_ai_gateway_policies/saml/index.md | 9 + .../service-protection/index.md | 9 + app/_ai_gateway_policies/session/index.md | 9 + .../solace-consume/index.md | 9 + app/_ai_gateway_policies/solace-log/index.md | 9 + .../solace-upstream/index.md | 9 + .../standard-webhooks/index.md | 9 + app/_ai_gateway_policies/statsd/index.md | 9 + app/_ai_gateway_policies/syslog/index.md | 9 + app/_ai_gateway_policies/tcp-log/index.md | 9 + .../tls-handshake-modifier/index.md | 9 + .../tls-metadata-headers/index.md | 9 + app/_ai_gateway_policies/udp-log/index.md | 9 + .../upstream-oauth/index.md | 10 + .../upstream-timeout/index.md | 9 + app/_ai_gateway_policies/vault-auth/index.md | 9 + .../websocket-size-limit/index.md | 9 + .../websocket-validator/index.md | 9 + .../xml-threat-protection/index.md | 9 + app/_ai_gateway_policies/zipkin/index.md | 9 + .../apps/components/SearchModalResultItem.vue | 4 +- app/_config/releases/ai-gateway/v1.yml | 4 +- app/_data/ai-gateway/v2/otel-metrics.yaml | 332 +++ .../ai-gateway/v2/otel-span-attributes.yaml | 75 + app/_data/policies/ai-gateway/scopes.json | 1050 +++++++ app/_includes/banners/cross_major_banner.md | 2 +- app/_includes/cards/plugin.html | 4 +- app/_includes/components/aigw_policy.html | 1 + app/_includes/components/aigw_policy.md | 1 + app/_includes/header.html | 21 +- app/_includes/info_box/plugin.html | 4 + app/_includes/info_box/sections/scopes.html | 20 + app/_includes/landing_pages/aigw_policy.md | 1 + .../layouts/policies/nav_header.html | 2 +- .../v2/policies/collecting-otel-data.md | 19 + .../ai-gateway/v2/policies/metric_tables.md | 43 + .../v2/policies/span_attribute_tables.md | 30 + .../plugins/ai-a2a-proxy/log-output-fields.md | 2 +- app/_includes/policies/index/filters.html | 80 + .../policies/index/plugin_cards.html | 29 + .../policies/index/search_input.html | 21 + app/_landing_pages/ai-gateway.yaml | 66 +- app/_landing_pages/ai-gateway/a2a.yaml | 16 +- .../ai-gateway/ai-providers.yaml | 1 - app/_landing_pages/ai-gateway/mcp.yaml | 16 +- .../ai_gateway_policies/reference.html | 13 + app/_llms.txt | 9 +- .../drops/plugins/aigw_policy_schema.rb | 35 + app/_plugins/drops/plugins/schema.rb | 29 +- .../generators/ai_gateway_policy/generator.rb | 32 + .../ai_gateway_policy/pages/base.rb | 36 + .../ai_gateway_policy/pages/overview.rb | 13 + .../ai_gateway_policy/pages/reference.rb | 27 + .../generators/ai_gateway_policy/policy.rb | 52 + app/_plugins/generators/broken_links.rb | 19 +- app/_plugins/generators/data/llm_metadata.rb | 1 + app/_plugins/generators/data/title/base.rb | 2 +- .../generators/plugins_ai_gateway_policies.rb | 15 + app/_plugins/generators/policies/generator.rb | 3 +- .../generators/policies/pages/base.rb | 1 + app/_plugins/hooks/site_post_write.rb | 11 +- app/_plugins/lib/link_icon_assigner.rb | 8 +- app/_plugins/tags/aigw_policy.rb | 47 + app/_redirects | 3 + app/_schemas/ai-gateway/policies/ACL.json | 79 + app/_schemas/ai-gateway/policies/Ace.json | 321 +++ app/_schemas/ai-gateway/policies/Acme.json | 419 +++ .../ai-gateway/policies/AiA2aProxy.json | 73 + .../ai-gateway/policies/AiAwsGuardrails.json | 209 ++ .../policies/AiAzureContentSafety.json | 221 ++ .../policies/AiCustomGuardrail.json | 291 ++ .../ai-gateway/policies/AiGcpModelArmor.json | 221 ++ .../ai-gateway/policies/AiLakeraGuard.json | 193 ++ .../ai-gateway/policies/AiLlmAsJudge.json | 593 ++++ .../ai-gateway/policies/AiMcpOauth2.json | 502 ++++ .../ai-gateway/policies/AiMcpProxy.json | 691 +++++ .../ai-gateway/policies/AiModelSelector.json | 101 + .../policies/AiPromptCompressor.json | 193 ++ .../policies/AiPromptDecorator.json | 145 + .../ai-gateway/policies/AiPromptGuard.json | 129 + .../ai-gateway/policies/AiPromptTemplate.json | 110 + .../ai-gateway/policies/AiProxyAdvanced.json | 1429 ++++++++++ .../ai-gateway/policies/AiRagInjector.json | 828 ++++++ .../policies/AiRateLimitingAdvanced.json | 559 ++++ .../policies/AiRequestTransformer.json | 553 ++++ .../policies/AiResponseTransformer.json | 568 ++++ .../ai-gateway/policies/AiSanitizer.json | 243 ++ .../ai-gateway/policies/AiSemanticCache.json | 776 ++++++ .../policies/AiSemanticPromptGuard.json | 779 ++++++ .../policies/AiSemanticResponseGuard.json | 787 ++++++ .../ai-gateway/policies/AppDynamics.json | 57 + .../ai-gateway/policies/AwsLambda.json | 223 ++ .../ai-gateway/policies/AzureFunctions.json | 122 + .../ai-gateway/policies/BasicAuth.json | 236 ++ .../ai-gateway/policies/BotDetection.json | 64 + app/_schemas/ai-gateway/policies/Canary.json | 117 + .../ai-gateway/policies/Confluent.json | 469 ++++ .../ai-gateway/policies/ConfluentConsume.json | 630 +++++ .../ai-gateway/policies/CorrelationId.json | 78 + app/_schemas/ai-gateway/policies/Cors.json | 123 + app/_schemas/ai-gateway/policies/Datadog.json | 232 ++ app/_schemas/ai-gateway/policies/Datakit.json | 1327 +++++++++ .../ai-gateway/policies/Degraphql.json | 53 + .../ai-gateway/policies/ExitTransformer.json | 80 + app/_schemas/ai-gateway/policies/FileLog.json | 87 + .../ai-gateway/policies/ForwardProxy.json | 112 + .../policies/GraphqlProxyCacheAdvanced.json | 343 +++ .../policies/GraphqlRateLimitingAdvanced.json | 399 +++ .../ai-gateway/policies/GrpcGateway.json | 69 + app/_schemas/ai-gateway/policies/GrpcWeb.json | 78 + .../ai-gateway/policies/HeaderCertAuth.json | 182 ++ .../ai-gateway/policies/HmacAuth.json | 113 + app/_schemas/ai-gateway/policies/HttpLog.json | 195 ++ .../policies/InjectionProtection.json | 126 + .../ai-gateway/policies/IpRestriction.json | 101 + app/_schemas/ai-gateway/policies/Jq.json | 145 + .../policies/JsonThreatProtection.json | 121 + .../ai-gateway/policies/JweDecrypt.json | 86 + app/_schemas/ai-gateway/policies/Jwt.json | 127 + .../ai-gateway/policies/JwtSigner.json | 1130 ++++++++ .../ai-gateway/policies/KafkaConsume.json | 626 +++++ .../ai-gateway/policies/KafkaLog.json | 460 ++++ .../ai-gateway/policies/KafkaUpstream.json | 488 ++++ app/_schemas/ai-gateway/policies/KeyAuth.json | 129 + .../ai-gateway/policies/KeyAuthEnc.json | 106 + .../policies/KonnectApplicationAuth.json | 2429 +++++++++++++++++ .../ai-gateway/policies/LdapAuth.json | 137 + .../ai-gateway/policies/LdapAuthAdvanced.json | 192 ++ app/_schemas/ai-gateway/policies/Loggly.json | 164 ++ .../policies/MeteringAndBilling.json | 217 ++ app/_schemas/ai-gateway/policies/Mocking.json | 107 + .../ai-gateway/policies/MtlsAuth.json | 178 ++ .../ai-gateway/policies/OasValidation.json | 142 + app/_schemas/ai-gateway/policies/Oauth2.json | 158 ++ .../policies/Oauth2Introspection.json | 139 + app/_schemas/ai-gateway/policies/Opa.json | 113 + .../ai-gateway/policies/OpenidConnect.json | 2360 ++++++++++++++++ .../ai-gateway/policies/Opentelemetry.json | 344 +++ .../ai-gateway/policies/PostFunction.json | 125 + .../ai-gateway/policies/PreFunction.json | 125 + .../ai-gateway/policies/Prometheus.json | 98 + .../ai-gateway/policies/ProxyCache.json | 192 ++ .../policies/ProxyCacheAdvanced.json | 441 +++ .../ai-gateway/policies/RateLimiting.json | 293 ++ .../policies/RateLimitingAdvanced.json | 490 ++++ .../ai-gateway/policies/Redirect.json | 90 + .../ai-gateway/policies/RequestCallout.json | 678 +++++ .../policies/RequestSizeLimiting.json | 78 + .../policies/RequestTermination.json | 96 + .../policies/RequestTransformer.json | 212 ++ .../policies/RequestTransformerAdvanced.json | 269 ++ .../ai-gateway/policies/RequestValidator.json | 147 + .../policies/ResponseRatelimiting.json | 270 ++ .../policies/ResponseTransformer.json | 202 ++ .../policies/ResponseTransformerAdvanced.json | 273 ++ .../ai-gateway/policies/RouteByHeader.json | 81 + .../policies/RouteTransformerAdvanced.json | 71 + app/_schemas/ai-gateway/policies/Saml.json | 581 ++++ .../policies/ServiceProtection.json | 370 +++ app/_schemas/ai-gateway/policies/Session.json | 244 ++ .../ai-gateway/policies/SolaceConsume.json | 302 ++ .../ai-gateway/policies/SolaceLog.json | 267 ++ .../ai-gateway/policies/SolaceUpstream.json | 342 +++ .../ai-gateway/policies/StandardWebhooks.json | 75 + app/_schemas/ai-gateway/policies/Statsd.json | 283 ++ .../ai-gateway/policies/StatsdAdvanced.json | 265 ++ app/_schemas/ai-gateway/policies/Syslog.json | 155 ++ app/_schemas/ai-gateway/policies/TcpLog.json | 113 + .../policies/TlsHandshakeModifier.json | 53 + .../policies/TlsMetadataHeaders.json | 75 + app/_schemas/ai-gateway/policies/UdpLog.json | 94 + .../ai-gateway/policies/UpstreamOauth.json | 547 ++++ .../ai-gateway/policies/UpstreamTimeout.json | 76 + .../ai-gateway/policies/VaultAuth.json | 97 + .../policies/WebsocketSizeLimit.json | 64 + .../policies/WebsocketValidator.json | 144 + .../policies/XmlThreatProtection.json | 183 ++ app/_schemas/ai-gateway/policies/Zipkin.json | 324 +++ app/ai-gateway/ai-audit-log-reference.md | 200 +- app/ai-gateway/ai-logs.md | 248 ++ app/ai-gateway/ai-otel-metrics.md | 402 +-- app/ai-gateway/ai-providers/anthropic.md | 4 +- app/ai-gateway/ai-providers/azure.md | 6 +- app/ai-gateway/ai-providers/bedrock.md | 6 +- app/ai-gateway/ai-providers/cerebras.md | 6 +- app/ai-gateway/ai-providers/cohere.md | 6 +- app/ai-gateway/ai-providers/dashscope.md | 6 +- app/ai-gateway/ai-providers/databricks.md | 8 +- app/ai-gateway/ai-providers/deepseek.md | 6 +- app/ai-gateway/ai-providers/gemini.md | 6 +- app/ai-gateway/ai-providers/huggingface.md | 8 +- app/ai-gateway/ai-providers/kimi.md | 4 +- app/ai-gateway/ai-providers/llama.md | 8 +- app/ai-gateway/ai-providers/mistral.md | 8 +- app/ai-gateway/ai-providers/ollama.md | 4 +- app/ai-gateway/ai-providers/openai.md | 8 +- app/ai-gateway/ai-providers/vercel.md | 4 +- app/ai-gateway/ai-providers/vertex.md | 8 +- app/ai-gateway/ai-providers/vllm.md | 8 +- app/ai-gateway/ai-providers/xai.md | 8 +- app/ai-gateway/llm-open-telemetry.md | 35 +- app/ai-gateway/load-balancing.md | 1 - app/ai-gateway/monitor-ai-llm-metrics.md | 16 +- app/ai-gateway/policies/index.html | 70 + app/ai-gateway/semantic-similarity.md | 30 +- app/ai-gateway/streaming.md | 49 +- app/event-gateway/policies/index.html | 20 +- app/plugins.html | 122 +- jekyll-dev.yml | 1 + jekyll.yml | 17 +- .../drops/plugins/aigw_policy_schema_spec.rb | 85 + .../app/_plugins/drops/plugins/schema_spec.rb | 144 + .../ai_gateway_policy/pages/base_spec.rb | 35 + .../ai_gateway_policy/pages/overview_spec.rb | 66 + .../ai_gateway_policy/pages/reference_spec.rb | 63 + .../ai_gateway_policy/policy_spec.rb | 108 + .../generators/data/llm_metadata_spec.rb | 11 + .../generators/data/title/base_spec.rb | 5 + .../generators/release_map_loader_spec.rb | 2 +- .../_plugins/hooks/site_post_write_spec.rb | 164 ++ spec/integration/llms_txt_writer_spec.rb | 151 + spec/support/page_double.rb | 14 + tools/aigw-policy-scopes/README.md | 44 + tools/aigw-policy-scopes/fetch-scopes.js | 69 + tools/aigw-policy-scopes/package-lock.json | 13 + tools/aigw-policy-scopes/package.json | 10 + .../config/expected_failures.yaml | 100 +- .../automated-tests/instructions/extractor.js | 8 +- tools/frontmatter-validator/index.js | 1 + 319 files changed, 40511 insertions(+), 924 deletions(-) create mode 100644 .claude/skills/ai-gateway-migration-review/SKILL.md create mode 100644 app/_ai_gateway_policies/ace/index.md create mode 100644 app/_ai_gateway_policies/acl/index.md create mode 100644 app/_ai_gateway_policies/acme/index.md create mode 100644 app/_ai_gateway_policies/ai-aws-guardrails/index.md create mode 100644 app/_ai_gateway_policies/ai-azure-content-safety/index.md create mode 100644 app/_ai_gateway_policies/ai-custom-guardrail/index.md create mode 100644 app/_ai_gateway_policies/ai-gcp-model-armor/index.md create mode 100644 app/_ai_gateway_policies/ai-lakera-guard/index.md create mode 100644 app/_ai_gateway_policies/ai-llm-as-judge/index.md create mode 100644 app/_ai_gateway_policies/ai-mcp-oauth2/index.md create mode 100644 app/_ai_gateway_policies/ai-prompt-compressor/index.md create mode 100644 app/_ai_gateway_policies/ai-prompt-decorator/index.md create mode 100644 app/_ai_gateway_policies/ai-prompt-guard/index.md create mode 100644 app/_ai_gateway_policies/ai-prompt-template/index.md create mode 100644 app/_ai_gateway_policies/ai-rag-injector/index.md create mode 100644 app/_ai_gateway_policies/ai-rate-limiting-advanced/index.md create mode 100644 app/_ai_gateway_policies/ai-request-transformer/index.md create mode 100644 app/_ai_gateway_policies/ai-response-transformer/index.md create mode 100644 app/_ai_gateway_policies/ai-sanitizer/index.md create mode 100644 app/_ai_gateway_policies/ai-semantic-cache/index.md create mode 100644 app/_ai_gateway_policies/ai-semantic-prompt-guard/index.md create mode 100644 app/_ai_gateway_policies/ai-semantic-response-guard/index.md create mode 100644 app/_ai_gateway_policies/app-dynamics/index.md create mode 100644 app/_ai_gateway_policies/aws-lambda/index.md create mode 100644 app/_ai_gateway_policies/azure-functions/index.md create mode 100644 app/_ai_gateway_policies/basic-auth/index.md create mode 100644 app/_ai_gateway_policies/bot-detection/index.md create mode 100644 app/_ai_gateway_policies/canary/index.md create mode 100644 app/_ai_gateway_policies/confluent-consume/index.md create mode 100644 app/_ai_gateway_policies/confluent/index.md create mode 100644 app/_ai_gateway_policies/correlation-id/index.md create mode 100644 app/_ai_gateway_policies/cors/index.md create mode 100644 app/_ai_gateway_policies/datadog/index.md create mode 100644 app/_ai_gateway_policies/datakit/index.md create mode 100644 app/_ai_gateway_policies/degraphql/index.md create mode 100644 app/_ai_gateway_policies/exit-transformer/index.md create mode 100644 app/_ai_gateway_policies/file-log/index.md create mode 100644 app/_ai_gateway_policies/forward-proxy/index.md create mode 100644 app/_ai_gateway_policies/graphql-proxy-cache-advanced/index.md create mode 100644 app/_ai_gateway_policies/graphql-rate-limiting-advanced/index.md create mode 100644 app/_ai_gateway_policies/grpc-gateway/index.md create mode 100644 app/_ai_gateway_policies/grpc-web/index.md create mode 100644 app/_ai_gateway_policies/header-cert-auth/index.md create mode 100644 app/_ai_gateway_policies/hmac-auth/index.md create mode 100644 app/_ai_gateway_policies/http-log/index.md create mode 100644 app/_ai_gateway_policies/injection-protection/index.md create mode 100644 app/_ai_gateway_policies/ip-restriction/index.md create mode 100644 app/_ai_gateway_policies/jq/index.md create mode 100644 app/_ai_gateway_policies/json-threat-protection/index.md create mode 100644 app/_ai_gateway_policies/jwe-decrypt/index.md create mode 100644 app/_ai_gateway_policies/jwt-signer/index.md create mode 100644 app/_ai_gateway_policies/jwt/index.md create mode 100644 app/_ai_gateway_policies/kafka-consume/index.md create mode 100644 app/_ai_gateway_policies/kafka-log/index.md create mode 100644 app/_ai_gateway_policies/kafka-upstream/index.md create mode 100644 app/_ai_gateway_policies/key-auth-enc/index.md create mode 100644 app/_ai_gateway_policies/key-auth/index.md create mode 100644 app/_ai_gateway_policies/ldap-auth-advanced/index.md create mode 100644 app/_ai_gateway_policies/ldap-auth/index.md create mode 100644 app/_ai_gateway_policies/loggly/index.md create mode 100644 app/_ai_gateway_policies/metering-and-billing/index.md create mode 100644 app/_ai_gateway_policies/mocking/index.md create mode 100644 app/_ai_gateway_policies/mtls-auth/index.md create mode 100644 app/_ai_gateway_policies/oas-validation/index.md create mode 100644 app/_ai_gateway_policies/oauth2-introspection/index.md create mode 100644 app/_ai_gateway_policies/oauth2/index.md create mode 100644 app/_ai_gateway_policies/opa/index.md create mode 100644 app/_ai_gateway_policies/openid-connect/index.md create mode 100644 app/_ai_gateway_policies/opentelemetry/index.md create mode 100644 app/_ai_gateway_policies/post-function/index.md create mode 100644 app/_ai_gateway_policies/pre-function/index.md create mode 100644 app/_ai_gateway_policies/prometheus/index.md create mode 100644 app/_ai_gateway_policies/proxy-cache-advanced/index.md create mode 100644 app/_ai_gateway_policies/proxy-cache/index.md create mode 100644 app/_ai_gateway_policies/rate-limiting-advanced/index.md create mode 100644 app/_ai_gateway_policies/rate-limiting/index.md create mode 100644 app/_ai_gateway_policies/redirect/index.md create mode 100644 app/_ai_gateway_policies/request-callout/index.md create mode 100644 app/_ai_gateway_policies/request-size-limiting/index.md create mode 100644 app/_ai_gateway_policies/request-termination/index.md create mode 100644 app/_ai_gateway_policies/request-transformer-advanced/index.md create mode 100644 app/_ai_gateway_policies/request-transformer/index.md create mode 100644 app/_ai_gateway_policies/request-validator/index.md create mode 100644 app/_ai_gateway_policies/response-ratelimiting/index.md create mode 100644 app/_ai_gateway_policies/response-transformer-advanced/index.md create mode 100644 app/_ai_gateway_policies/response-transformer/index.md create mode 100644 app/_ai_gateway_policies/route-by-header/index.md create mode 100644 app/_ai_gateway_policies/route-transformer-advanced/index.md create mode 100644 app/_ai_gateway_policies/saml/index.md create mode 100644 app/_ai_gateway_policies/service-protection/index.md create mode 100644 app/_ai_gateway_policies/session/index.md create mode 100644 app/_ai_gateway_policies/solace-consume/index.md create mode 100644 app/_ai_gateway_policies/solace-log/index.md create mode 100644 app/_ai_gateway_policies/solace-upstream/index.md create mode 100644 app/_ai_gateway_policies/standard-webhooks/index.md create mode 100644 app/_ai_gateway_policies/statsd/index.md create mode 100644 app/_ai_gateway_policies/syslog/index.md create mode 100644 app/_ai_gateway_policies/tcp-log/index.md create mode 100644 app/_ai_gateway_policies/tls-handshake-modifier/index.md create mode 100644 app/_ai_gateway_policies/tls-metadata-headers/index.md create mode 100644 app/_ai_gateway_policies/udp-log/index.md create mode 100644 app/_ai_gateway_policies/upstream-oauth/index.md create mode 100644 app/_ai_gateway_policies/upstream-timeout/index.md create mode 100644 app/_ai_gateway_policies/vault-auth/index.md create mode 100644 app/_ai_gateway_policies/websocket-size-limit/index.md create mode 100644 app/_ai_gateway_policies/websocket-validator/index.md create mode 100644 app/_ai_gateway_policies/xml-threat-protection/index.md create mode 100644 app/_ai_gateway_policies/zipkin/index.md create mode 100644 app/_data/ai-gateway/v2/otel-metrics.yaml create mode 100644 app/_data/ai-gateway/v2/otel-span-attributes.yaml create mode 100644 app/_data/policies/ai-gateway/scopes.json create mode 100644 app/_includes/components/aigw_policy.html create mode 100644 app/_includes/components/aigw_policy.md create mode 100644 app/_includes/info_box/sections/scopes.html create mode 100644 app/_includes/landing_pages/aigw_policy.md create mode 100644 app/_includes/md/ai-gateway/v2/policies/collecting-otel-data.md create mode 100644 app/_includes/md/ai-gateway/v2/policies/metric_tables.md create mode 100644 app/_includes/md/ai-gateway/v2/policies/span_attribute_tables.md create mode 100644 app/_includes/policies/index/filters.html create mode 100644 app/_includes/policies/index/plugin_cards.html create mode 100644 app/_includes/policies/index/search_input.html create mode 100644 app/_layouts/ai_gateway_policies/reference.html create mode 100644 app/_plugins/drops/plugins/aigw_policy_schema.rb create mode 100644 app/_plugins/generators/ai_gateway_policy/generator.rb create mode 100644 app/_plugins/generators/ai_gateway_policy/pages/base.rb create mode 100644 app/_plugins/generators/ai_gateway_policy/pages/overview.rb create mode 100644 app/_plugins/generators/ai_gateway_policy/pages/reference.rb create mode 100644 app/_plugins/generators/ai_gateway_policy/policy.rb create mode 100644 app/_plugins/generators/plugins_ai_gateway_policies.rb create mode 100644 app/_plugins/tags/aigw_policy.rb create mode 100644 app/_schemas/ai-gateway/policies/ACL.json create mode 100644 app/_schemas/ai-gateway/policies/Ace.json create mode 100644 app/_schemas/ai-gateway/policies/Acme.json create mode 100644 app/_schemas/ai-gateway/policies/AiA2aProxy.json create mode 100644 app/_schemas/ai-gateway/policies/AiAwsGuardrails.json create mode 100644 app/_schemas/ai-gateway/policies/AiAzureContentSafety.json create mode 100644 app/_schemas/ai-gateway/policies/AiCustomGuardrail.json create mode 100644 app/_schemas/ai-gateway/policies/AiGcpModelArmor.json create mode 100644 app/_schemas/ai-gateway/policies/AiLakeraGuard.json create mode 100644 app/_schemas/ai-gateway/policies/AiLlmAsJudge.json create mode 100644 app/_schemas/ai-gateway/policies/AiMcpOauth2.json create mode 100644 app/_schemas/ai-gateway/policies/AiMcpProxy.json create mode 100644 app/_schemas/ai-gateway/policies/AiModelSelector.json create mode 100644 app/_schemas/ai-gateway/policies/AiPromptCompressor.json create mode 100644 app/_schemas/ai-gateway/policies/AiPromptDecorator.json create mode 100644 app/_schemas/ai-gateway/policies/AiPromptGuard.json create mode 100644 app/_schemas/ai-gateway/policies/AiPromptTemplate.json create mode 100644 app/_schemas/ai-gateway/policies/AiProxyAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/AiRagInjector.json create mode 100644 app/_schemas/ai-gateway/policies/AiRateLimitingAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/AiRequestTransformer.json create mode 100644 app/_schemas/ai-gateway/policies/AiResponseTransformer.json create mode 100644 app/_schemas/ai-gateway/policies/AiSanitizer.json create mode 100644 app/_schemas/ai-gateway/policies/AiSemanticCache.json create mode 100644 app/_schemas/ai-gateway/policies/AiSemanticPromptGuard.json create mode 100644 app/_schemas/ai-gateway/policies/AiSemanticResponseGuard.json create mode 100644 app/_schemas/ai-gateway/policies/AppDynamics.json create mode 100644 app/_schemas/ai-gateway/policies/AwsLambda.json create mode 100644 app/_schemas/ai-gateway/policies/AzureFunctions.json create mode 100644 app/_schemas/ai-gateway/policies/BasicAuth.json create mode 100644 app/_schemas/ai-gateway/policies/BotDetection.json create mode 100644 app/_schemas/ai-gateway/policies/Canary.json create mode 100644 app/_schemas/ai-gateway/policies/Confluent.json create mode 100644 app/_schemas/ai-gateway/policies/ConfluentConsume.json create mode 100644 app/_schemas/ai-gateway/policies/CorrelationId.json create mode 100644 app/_schemas/ai-gateway/policies/Cors.json create mode 100644 app/_schemas/ai-gateway/policies/Datadog.json create mode 100644 app/_schemas/ai-gateway/policies/Datakit.json create mode 100644 app/_schemas/ai-gateway/policies/Degraphql.json create mode 100644 app/_schemas/ai-gateway/policies/ExitTransformer.json create mode 100644 app/_schemas/ai-gateway/policies/FileLog.json create mode 100644 app/_schemas/ai-gateway/policies/ForwardProxy.json create mode 100644 app/_schemas/ai-gateway/policies/GraphqlProxyCacheAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/GraphqlRateLimitingAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/GrpcGateway.json create mode 100644 app/_schemas/ai-gateway/policies/GrpcWeb.json create mode 100644 app/_schemas/ai-gateway/policies/HeaderCertAuth.json create mode 100644 app/_schemas/ai-gateway/policies/HmacAuth.json create mode 100644 app/_schemas/ai-gateway/policies/HttpLog.json create mode 100644 app/_schemas/ai-gateway/policies/InjectionProtection.json create mode 100644 app/_schemas/ai-gateway/policies/IpRestriction.json create mode 100644 app/_schemas/ai-gateway/policies/Jq.json create mode 100644 app/_schemas/ai-gateway/policies/JsonThreatProtection.json create mode 100644 app/_schemas/ai-gateway/policies/JweDecrypt.json create mode 100644 app/_schemas/ai-gateway/policies/Jwt.json create mode 100644 app/_schemas/ai-gateway/policies/JwtSigner.json create mode 100644 app/_schemas/ai-gateway/policies/KafkaConsume.json create mode 100644 app/_schemas/ai-gateway/policies/KafkaLog.json create mode 100644 app/_schemas/ai-gateway/policies/KafkaUpstream.json create mode 100644 app/_schemas/ai-gateway/policies/KeyAuth.json create mode 100644 app/_schemas/ai-gateway/policies/KeyAuthEnc.json create mode 100644 app/_schemas/ai-gateway/policies/KonnectApplicationAuth.json create mode 100644 app/_schemas/ai-gateway/policies/LdapAuth.json create mode 100644 app/_schemas/ai-gateway/policies/LdapAuthAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/Loggly.json create mode 100644 app/_schemas/ai-gateway/policies/MeteringAndBilling.json create mode 100644 app/_schemas/ai-gateway/policies/Mocking.json create mode 100644 app/_schemas/ai-gateway/policies/MtlsAuth.json create mode 100644 app/_schemas/ai-gateway/policies/OasValidation.json create mode 100644 app/_schemas/ai-gateway/policies/Oauth2.json create mode 100644 app/_schemas/ai-gateway/policies/Oauth2Introspection.json create mode 100644 app/_schemas/ai-gateway/policies/Opa.json create mode 100644 app/_schemas/ai-gateway/policies/OpenidConnect.json create mode 100644 app/_schemas/ai-gateway/policies/Opentelemetry.json create mode 100644 app/_schemas/ai-gateway/policies/PostFunction.json create mode 100644 app/_schemas/ai-gateway/policies/PreFunction.json create mode 100644 app/_schemas/ai-gateway/policies/Prometheus.json create mode 100644 app/_schemas/ai-gateway/policies/ProxyCache.json create mode 100644 app/_schemas/ai-gateway/policies/ProxyCacheAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/RateLimiting.json create mode 100644 app/_schemas/ai-gateway/policies/RateLimitingAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/Redirect.json create mode 100644 app/_schemas/ai-gateway/policies/RequestCallout.json create mode 100644 app/_schemas/ai-gateway/policies/RequestSizeLimiting.json create mode 100644 app/_schemas/ai-gateway/policies/RequestTermination.json create mode 100644 app/_schemas/ai-gateway/policies/RequestTransformer.json create mode 100644 app/_schemas/ai-gateway/policies/RequestTransformerAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/RequestValidator.json create mode 100644 app/_schemas/ai-gateway/policies/ResponseRatelimiting.json create mode 100644 app/_schemas/ai-gateway/policies/ResponseTransformer.json create mode 100644 app/_schemas/ai-gateway/policies/ResponseTransformerAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/RouteByHeader.json create mode 100644 app/_schemas/ai-gateway/policies/RouteTransformerAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/Saml.json create mode 100644 app/_schemas/ai-gateway/policies/ServiceProtection.json create mode 100644 app/_schemas/ai-gateway/policies/Session.json create mode 100644 app/_schemas/ai-gateway/policies/SolaceConsume.json create mode 100644 app/_schemas/ai-gateway/policies/SolaceLog.json create mode 100644 app/_schemas/ai-gateway/policies/SolaceUpstream.json create mode 100644 app/_schemas/ai-gateway/policies/StandardWebhooks.json create mode 100644 app/_schemas/ai-gateway/policies/Statsd.json create mode 100644 app/_schemas/ai-gateway/policies/StatsdAdvanced.json create mode 100644 app/_schemas/ai-gateway/policies/Syslog.json create mode 100644 app/_schemas/ai-gateway/policies/TcpLog.json create mode 100644 app/_schemas/ai-gateway/policies/TlsHandshakeModifier.json create mode 100644 app/_schemas/ai-gateway/policies/TlsMetadataHeaders.json create mode 100644 app/_schemas/ai-gateway/policies/UdpLog.json create mode 100644 app/_schemas/ai-gateway/policies/UpstreamOauth.json create mode 100644 app/_schemas/ai-gateway/policies/UpstreamTimeout.json create mode 100644 app/_schemas/ai-gateway/policies/VaultAuth.json create mode 100644 app/_schemas/ai-gateway/policies/WebsocketSizeLimit.json create mode 100644 app/_schemas/ai-gateway/policies/WebsocketValidator.json create mode 100644 app/_schemas/ai-gateway/policies/XmlThreatProtection.json create mode 100644 app/_schemas/ai-gateway/policies/Zipkin.json create mode 100644 app/ai-gateway/ai-logs.md create mode 100644 app/ai-gateway/policies/index.html create mode 100644 spec/app/_plugins/drops/plugins/aigw_policy_schema_spec.rb create mode 100644 spec/app/_plugins/drops/plugins/schema_spec.rb create mode 100644 spec/app/_plugins/generators/ai_gateway_policy/pages/base_spec.rb create mode 100644 spec/app/_plugins/generators/ai_gateway_policy/pages/overview_spec.rb create mode 100644 spec/app/_plugins/generators/ai_gateway_policy/pages/reference_spec.rb create mode 100644 spec/app/_plugins/generators/ai_gateway_policy/policy_spec.rb create mode 100644 spec/app/_plugins/hooks/site_post_write_spec.rb create mode 100644 spec/integration/llms_txt_writer_spec.rb create mode 100644 spec/support/page_double.rb create mode 100644 tools/aigw-policy-scopes/README.md create mode 100644 tools/aigw-policy-scopes/fetch-scopes.js create mode 100644 tools/aigw-policy-scopes/package-lock.json create mode 100644 tools/aigw-policy-scopes/package.json diff --git a/.claude/skills/ai-gateway-migration-review/SKILL.md b/.claude/skills/ai-gateway-migration-review/SKILL.md new file mode 100644 index 00000000000..a1a7ad2514a --- /dev/null +++ b/.claude/skills/ai-gateway-migration-review/SKILL.md @@ -0,0 +1,213 @@ +--- +name: ai-gateway-migration-review +description: > + Reviews AI Gateway documentation files for correctness during the v1 → v2 migration. + Use this skill whenever you need to audit or fix AI Gateway docs for migration issues — + whether reviewing specific files or all AI Gateway files across how-tos, landing pages, + and reference pages. Triggers on requests like "review this ai-gateway file", "check + my migration", "audit ai-gateway docs for v2", "find v1 references in ai-gateway pages", + "update this file for AI Gateway v2", or any time someone is working on AI Gateway + content under app/_how-tos/ai-gateway, app/_landing-pages/ai-gateway, or app/ai-gateway. +--- + +# AI Gateway Migration Review Skill + +This skill audits and optionally fixes AI Gateway documentation files for the v1 → v2 migration. + +## Step 1: Ask the user two questions upfront + +Before doing any work, ask (you can ask both in one message): + +1. **Scope**: Do they want to review a specific files or directories or all AI Gateway files? + - If specific files or directories, ask for the path. + - If all files, you'll scan these directories: + - `app/_how-tos/ai-gateway/` + - `app/_landing_pages/ai-gateway/` + - `app/ai-gateway/` + +2. **Mode**: Should you make changes directly, or produce a report of issues to fix? + +## Step 2: Perform the review + +Apply the rules below. For **report mode**, collect all findings and present them as a structured report at the end. For **edit mode**, apply fixes directly and summarize what changed. + +--- + +## Rules for v1 files (under any `v1/` subdirectory) + +These files are the legacy v1 content. They need their own internal consistency: + +- **Breadcrumbs and links**: Any breadcrumbs or links starting with `/ai-gateway/` must use `/ai-gateway/v1/` (not the bare `/ai-gateway/` path). +- **Permalinks**: If the file has a `permalink:` frontmatter field, it must contain `/v1/` in the path. +- **Include and data file references**: References to AI Gateway include files (`{% include_content ... %}`, `{% include ... %}`) and data files must use the `/v1/` variant, e.g. `ai-gateway/v1/some-include` not `ai-gateway/some-include`. + +--- + +## Rules for v2 files (current, non-v1 AI Gateway files) + +### Frontmatter requirements + +Every v2 AI Gateway page must have this exact frontmatter shape for these fields: + +```yaml +products: + - ai-gateway # Only ai-gateway, no other products +works_on: + - konnect # Only konnect, no on-prem +tools: + - konnect-api # Optional field, if it exists, must be only konnect-api +min_version: + ai-gateway: '2.0' +``` + +Flag any deviation: +- `products` containing anything other than `ai-gateway` +- `works_on` containing `on-prem` or anything other than `konnect` +- `tools` containing `deck`, `admin-api`, or anything other than `konnect-api` +- Missing or wrong `min_version` (must be `ai-gateway: '2.0'`) + +### Plugin → AI Policy migration + +Plugins have been replaced by AI Policies in v2. The four plugins that do **not** exist as policies are exceptions: +- AI A2A Proxy +- AI MCP Proxy +- AI Proxy +- AI Proxy Advanced + +For everything else: + +- **Rename in prose**: Replace "X plugin" with "X Policy". For example: + - "AI Request Transformer plugin" → "AI Request Transformer Policy" + - "AI Prompt Guard plugin" → "AI Prompt Guard Policy" + +- **Links to plugins**: Replace `/plugins/` path with `/ai-gateway/policies/`. For example: + - `/plugins/ai-prompt-guard/` → `/ai-gateway/policies/ai-prompt-guard/` + - `/plugins/?category=ai` → `/ai-gateway/policies/` + +- **Exception — flag these**: Any reference to AI A2A Proxy, AI MCP Proxy, AI Proxy, or AI Proxy Advanced as plugins should be flagged for manual review (these don't have policy equivalents). + +- **Landing page plugin blocks**: In YAML landing pages (`.yaml` files under `_landing_pages/`), replace `type: plugin` blocks with `type: aigw_policy`. Example: + ```yaml + # Before (v1) + - type: plugin + config: + slug: ai-prompt-guard + + # After (v2) + - type: aigw_policy + config: + slug: ai-prompt-guard + ``` + +### Include and data file references + +References to AI Gateway include files and data files must use `/v2/`. For example: +- `ai-gateway/circuit-breaker` → `ai-gateway/v2/circuit-breaker` +- `_includes/md/ai-gateway/circuit-breaker.md` → `_includes/md/ai-gateway/v2/circuit-breaker.md` + +Flag any `{% include /plugins/` tags — v2 AI Gateway pages must not pull in plugin includes. These should be removed or replaced with the appropriate AI Policy equivalent. For example: + +``` +{% include /plugins/ai-a2a-proxy/log-output-fields.md %} +``` + +This should be replaced with a corresponding AI Policy include (e.g. under `_includes/md/ai-gateway/v2/`) or removed if no equivalent exists. + +### Code block style + +Example codeblocks in how-to guides should use `{% konnect_api_request %}` rather than raw curl or deck commands where they're making API calls. Flag any `curl` commands or `deck` commands in example steps that should be `{% konnect_api_request %}` blocks. + +### Konnect-only deployments + +v2 AI Gateway is Konnect-only. Flag any references to on-premises deployments, self-hosted Kong Gateway, or any instructions that only apply to on-prem. + +### Kong Gateway → AI Gateway + +Most references to Kong Gateway or `{{site.base_gateway}}` should be replaced with `{{site.ai_gateway}}`. However, some are legitimate — when a sentence genuinely compares or contrasts AI Gateway with Kong Gateway (e.g. "When operating {{site.ai_gateway}} alongside {{site.base_gateway}}…"), the `{{site.base_gateway}}` reference may be intentional. Flag these for manual review rather than replacing them automatically. + +### AI Gateway entity names + +All AI Gateway entity names (from `app/_ai_gateway_entities/`) must be capitalized and prefixed with "AI". Known entities: +- AI Agent +- AI Consumer +- AI Consumer Credential +- AI Consumer Group +- AI Data Plane Certificate +- AI Data Plane Node +- AI Gateway +- AI MCP Server +- AI Model +- AI Policy +- AI Provider +- AI Vault + +Flag any references to these entities without the "AI" prefix, in both singular and plural forms. For example: +- "model" or "models" → "AI Model" / "AI Models" +- "provider" or "providers" → "AI Provider" / "AI Providers" +- "policy" or "policies" → "AI Policy" / "AI Policies" +- "agent" or "agents" → "AI Agent" / "AI Agents" +- "consumer" or "consumers" → "AI Consumer" / "AI Consumers" +- "vault" → "AI Vault" + +**Check the entire file including frontmatter** — FAQs, `related_resources` links, and all entity references in link text must use the full "AI" prefix (e.g., `[AI Policies](/ai-gateway/entities/ai-policy/)` not `[Policies](/ai-gateway/entities/ai-policy/)`). + +### Links to unmigrated how-to guides + +Not all v1 how-to guides have been migrated to v2. Before checking links, build a list of invalid v1 permalinks by reading every `.md` file under `app/_how-tos/ai-gateway/v1/` and extracting their `permalink:` frontmatter values. + +Then, in the file being reviewed, flag any link whose URL appears in that list. These point to legacy v1 pages and should be removed or updated to point to the v2 equivalent if one exists. + +### v1 release tracking (`app/_config/releases/ai-gateway/v1.yml`) + +This file tracks every v1 page and whether a v2 equivalent has been written. Each entry looks like: + +```yaml +app/_how-tos/ai-gateway/v1/some-guide.md: + status: pending # still needs a v2 equivalent + canonical_url: # should point to the v2 page once written +``` + +When a new v2 page is created, the corresponding v1 entry in this file must be updated: +- Remove `status: pending` +- Set `canonical_url` to the new v2 page's permalink + +When reviewing a newly created v2 file, check whether its v1 counterpart exists in `v1.yml` and still has `status: pending`. If so, flag it: the reviewer should remove `status: pending` and set `canonical_url` to the new page's permalink. + +When reviewing all files, read `app/_config/releases/ai-gateway/v1.yml` and report all entries that still have `status: pending` — these are v1 pages that have not yet been migrated. + +--- + +## Reporting format + +When producing a **report**, structure it like this for each file reviewed: + +``` +### + +**Frontmatter issues:** +- + +**Plugin → AI Policy issues:** +- + +**Include/data file references (including `{% include /plugins/` tags):** +- + +**Unmigrated how-to links:** +- — not yet migrated, remove or update + +**v1 release tracking (`v1.yml`):** +- — still has `status: pending`, set `canonical_url` to + +**On-prem references:** +- Line N: — flag for removal + +**Entity naming:** +- + +**No issues found** (if clean) +``` + +For a **single-file edit**, after making changes, produce a brief summary of every change made. + +For **all-files edit**, process files one at a time and produce a per-file summary at the end. diff --git a/.github/workflows/automated-tests.yaml b/.github/workflows/automated-tests.yaml index 90221b02a33..e4a3e5229c9 100644 --- a/.github/workflows/automated-tests.yaml +++ b/.github/workflows/automated-tests.yaml @@ -48,7 +48,7 @@ jobs: env: KONG_LICENSE_DATA: ${{ steps.getLicense.outputs.license }} DEPLOYMENT_MODEL: on-prem - PRODUCTS: ai-gateway,gateway + PRODUCTS: gateway GATEWAY_VERSION: ${{ matrix.gateway }} run: | DEBUG=tests:*,debug npm run run-tests diff --git a/app/_ai_gateway_policies/ace/index.md b/app/_ai_gateway_policies/ace/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ace/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/acl/index.md b/app/_ai_gateway_policies/acl/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/acl/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/acme/index.md b/app/_ai_gateway_policies/acme/index.md new file mode 100644 index 00000000000..e0b91320d1e --- /dev/null +++ b/app/_ai_gateway_policies/acme/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Let's Encrypt and ACMEv2 integration with {{site.ai_gateway_name}} +--- diff --git a/app/_ai_gateway_policies/ai-aws-guardrails/index.md b/app/_ai_gateway_policies/ai-aws-guardrails/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-aws-guardrails/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-azure-content-safety/index.md b/app/_ai_gateway_policies/ai-azure-content-safety/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-azure-content-safety/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-custom-guardrail/index.md b/app/_ai_gateway_policies/ai-custom-guardrail/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-custom-guardrail/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-gcp-model-armor/index.md b/app/_ai_gateway_policies/ai-gcp-model-armor/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-gcp-model-armor/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-lakera-guard/index.md b/app/_ai_gateway_policies/ai-lakera-guard/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-lakera-guard/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-llm-as-judge/index.md b/app/_ai_gateway_policies/ai-llm-as-judge/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-llm-as-judge/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-mcp-oauth2/index.md b/app/_ai_gateway_policies/ai-mcp-oauth2/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-mcp-oauth2/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-prompt-compressor/index.md b/app/_ai_gateway_policies/ai-prompt-compressor/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-prompt-compressor/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-prompt-decorator/index.md b/app/_ai_gateway_policies/ai-prompt-decorator/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-prompt-decorator/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-prompt-guard/index.md b/app/_ai_gateway_policies/ai-prompt-guard/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-prompt-guard/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-prompt-template/index.md b/app/_ai_gateway_policies/ai-prompt-template/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-prompt-template/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-rag-injector/index.md b/app/_ai_gateway_policies/ai-rag-injector/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-rag-injector/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-rate-limiting-advanced/index.md b/app/_ai_gateway_policies/ai-rate-limiting-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-rate-limiting-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-request-transformer/index.md b/app/_ai_gateway_policies/ai-request-transformer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-request-transformer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-response-transformer/index.md b/app/_ai_gateway_policies/ai-response-transformer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-response-transformer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-sanitizer/index.md b/app/_ai_gateway_policies/ai-sanitizer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-sanitizer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-semantic-cache/index.md b/app/_ai_gateway_policies/ai-semantic-cache/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-semantic-cache/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-semantic-prompt-guard/index.md b/app/_ai_gateway_policies/ai-semantic-prompt-guard/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-semantic-prompt-guard/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ai-semantic-response-guard/index.md b/app/_ai_gateway_policies/ai-semantic-response-guard/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ai-semantic-response-guard/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/app-dynamics/index.md b/app/_ai_gateway_policies/app-dynamics/index.md new file mode 100644 index 00000000000..86bb3e3da4a --- /dev/null +++ b/app/_ai_gateway_policies/app-dynamics/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Integrate {{site.ai_gateway_name}} with the AppDynamics APM Platform +--- diff --git a/app/_ai_gateway_policies/aws-lambda/index.md b/app/_ai_gateway_policies/aws-lambda/index.md new file mode 100644 index 00000000000..3573ab8e78e --- /dev/null +++ b/app/_ai_gateway_policies/aws-lambda/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Invoke and manage AWS Lambda functions from {{site.ai_gateway_name}} +--- diff --git a/app/_ai_gateway_policies/azure-functions/index.md b/app/_ai_gateway_policies/azure-functions/index.md new file mode 100644 index 00000000000..c0362d5f229 --- /dev/null +++ b/app/_ai_gateway_policies/azure-functions/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Invoke and manage Azure functions from {{site.ai_gateway_name}} +--- diff --git a/app/_ai_gateway_policies/basic-auth/index.md b/app/_ai_gateway_policies/basic-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/basic-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/bot-detection/index.md b/app/_ai_gateway_policies/bot-detection/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/bot-detection/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/canary/index.md b/app/_ai_gateway_policies/canary/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/canary/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/confluent-consume/index.md b/app/_ai_gateway_policies/confluent-consume/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/confluent-consume/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/confluent/index.md b/app/_ai_gateway_policies/confluent/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/confluent/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/correlation-id/index.md b/app/_ai_gateway_policies/correlation-id/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/correlation-id/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/cors/index.md b/app/_ai_gateway_policies/cors/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/cors/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/datadog/index.md b/app/_ai_gateway_policies/datadog/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/datadog/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/datakit/index.md b/app/_ai_gateway_policies/datakit/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/datakit/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/degraphql/index.md b/app/_ai_gateway_policies/degraphql/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/degraphql/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/exit-transformer/index.md b/app/_ai_gateway_policies/exit-transformer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/exit-transformer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/file-log/index.md b/app/_ai_gateway_policies/file-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/file-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/forward-proxy/index.md b/app/_ai_gateway_policies/forward-proxy/index.md new file mode 100644 index 00000000000..6680c5d291e --- /dev/null +++ b/app/_ai_gateway_policies/forward-proxy/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Allows {{site.ai_gateway_name}} to connect to intermediary transparent HTTP +--- diff --git a/app/_ai_gateway_policies/graphql-proxy-cache-advanced/index.md b/app/_ai_gateway_policies/graphql-proxy-cache-advanced/index.md new file mode 100644 index 00000000000..bc855d09d7a --- /dev/null +++ b/app/_ai_gateway_policies/graphql-proxy-cache-advanced/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Cache and serve commonly requested responses in {{site.ai_gateway_name}} +--- diff --git a/app/_ai_gateway_policies/graphql-rate-limiting-advanced/index.md b/app/_ai_gateway_policies/graphql-rate-limiting-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/graphql-rate-limiting-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/grpc-gateway/index.md b/app/_ai_gateway_policies/grpc-gateway/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/grpc-gateway/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/grpc-web/index.md b/app/_ai_gateway_policies/grpc-web/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/grpc-web/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/header-cert-auth/index.md b/app/_ai_gateway_policies/header-cert-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/header-cert-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/hmac-auth/index.md b/app/_ai_gateway_policies/hmac-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/hmac-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/http-log/index.md b/app/_ai_gateway_policies/http-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/http-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/injection-protection/index.md b/app/_ai_gateway_policies/injection-protection/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/injection-protection/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ip-restriction/index.md b/app/_ai_gateway_policies/ip-restriction/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ip-restriction/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/jq/index.md b/app/_ai_gateway_policies/jq/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/jq/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/json-threat-protection/index.md b/app/_ai_gateway_policies/json-threat-protection/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/json-threat-protection/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/jwe-decrypt/index.md b/app/_ai_gateway_policies/jwe-decrypt/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/jwe-decrypt/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/jwt-signer/index.md b/app/_ai_gateway_policies/jwt-signer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/jwt-signer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/jwt/index.md b/app/_ai_gateway_policies/jwt/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/jwt/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/kafka-consume/index.md b/app/_ai_gateway_policies/kafka-consume/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/kafka-consume/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/kafka-log/index.md b/app/_ai_gateway_policies/kafka-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/kafka-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/kafka-upstream/index.md b/app/_ai_gateway_policies/kafka-upstream/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/kafka-upstream/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/key-auth-enc/index.md b/app/_ai_gateway_policies/key-auth-enc/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/key-auth-enc/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/key-auth/index.md b/app/_ai_gateway_policies/key-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/key-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ldap-auth-advanced/index.md b/app/_ai_gateway_policies/ldap-auth-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ldap-auth-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/ldap-auth/index.md b/app/_ai_gateway_policies/ldap-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/ldap-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/loggly/index.md b/app/_ai_gateway_policies/loggly/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/loggly/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/metering-and-billing/index.md b/app/_ai_gateway_policies/metering-and-billing/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/metering-and-billing/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/mocking/index.md b/app/_ai_gateway_policies/mocking/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/mocking/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/mtls-auth/index.md b/app/_ai_gateway_policies/mtls-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/mtls-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/oas-validation/index.md b/app/_ai_gateway_policies/oas-validation/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/oas-validation/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/oauth2-introspection/index.md b/app/_ai_gateway_policies/oauth2-introspection/index.md new file mode 100644 index 00000000000..d09714deba1 --- /dev/null +++ b/app/_ai_gateway_policies/oauth2-introspection/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Integrate {{site.ai_gateway_name}} with a third-party OAuth 2.0 Authorization +--- diff --git a/app/_ai_gateway_policies/oauth2/index.md b/app/_ai_gateway_policies/oauth2/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/oauth2/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/opa/index.md b/app/_ai_gateway_policies/opa/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/opa/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/openid-connect/index.md b/app/_ai_gateway_policies/openid-connect/index.md new file mode 100644 index 00000000000..5e14adb700a --- /dev/null +++ b/app/_ai_gateway_policies/openid-connect/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Integrate {{site.ai_gateway_name}} with a third-party OpenID Connect provider +--- diff --git a/app/_ai_gateway_policies/opentelemetry/index.md b/app/_ai_gateway_policies/opentelemetry/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/opentelemetry/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/post-function/index.md b/app/_ai_gateway_policies/post-function/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/post-function/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/pre-function/index.md b/app/_ai_gateway_policies/pre-function/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/pre-function/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/prometheus/index.md b/app/_ai_gateway_policies/prometheus/index.md new file mode 100644 index 00000000000..6cd8dc10a0e --- /dev/null +++ b/app/_ai_gateway_policies/prometheus/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Expose metrics related to {{site.ai_gateway_name}} in Prometheus exposition format +--- diff --git a/app/_ai_gateway_policies/proxy-cache-advanced/index.md b/app/_ai_gateway_policies/proxy-cache-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/proxy-cache-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/proxy-cache/index.md b/app/_ai_gateway_policies/proxy-cache/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/proxy-cache/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/rate-limiting-advanced/index.md b/app/_ai_gateway_policies/rate-limiting-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/rate-limiting-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/rate-limiting/index.md b/app/_ai_gateway_policies/rate-limiting/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/rate-limiting/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/redirect/index.md b/app/_ai_gateway_policies/redirect/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/redirect/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-callout/index.md b/app/_ai_gateway_policies/request-callout/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-callout/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-size-limiting/index.md b/app/_ai_gateway_policies/request-size-limiting/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-size-limiting/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-termination/index.md b/app/_ai_gateway_policies/request-termination/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-termination/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-transformer-advanced/index.md b/app/_ai_gateway_policies/request-transformer-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-transformer-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-transformer/index.md b/app/_ai_gateway_policies/request-transformer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-transformer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/request-validator/index.md b/app/_ai_gateway_policies/request-validator/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/request-validator/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/response-ratelimiting/index.md b/app/_ai_gateway_policies/response-ratelimiting/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/response-ratelimiting/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/response-transformer-advanced/index.md b/app/_ai_gateway_policies/response-transformer-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/response-transformer-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/response-transformer/index.md b/app/_ai_gateway_policies/response-transformer/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/response-transformer/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/route-by-header/index.md b/app/_ai_gateway_policies/route-by-header/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/route-by-header/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/route-transformer-advanced/index.md b/app/_ai_gateway_policies/route-transformer-advanced/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/route-transformer-advanced/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/saml/index.md b/app/_ai_gateway_policies/saml/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/saml/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/service-protection/index.md b/app/_ai_gateway_policies/service-protection/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/service-protection/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/session/index.md b/app/_ai_gateway_policies/session/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/session/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/solace-consume/index.md b/app/_ai_gateway_policies/solace-consume/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/solace-consume/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/solace-log/index.md b/app/_ai_gateway_policies/solace-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/solace-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/solace-upstream/index.md b/app/_ai_gateway_policies/solace-upstream/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/solace-upstream/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/standard-webhooks/index.md b/app/_ai_gateway_policies/standard-webhooks/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/standard-webhooks/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/statsd/index.md b/app/_ai_gateway_policies/statsd/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/statsd/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/syslog/index.md b/app/_ai_gateway_policies/syslog/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/syslog/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/tcp-log/index.md b/app/_ai_gateway_policies/tcp-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/tcp-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/tls-handshake-modifier/index.md b/app/_ai_gateway_policies/tls-handshake-modifier/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/tls-handshake-modifier/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/tls-metadata-headers/index.md b/app/_ai_gateway_policies/tls-metadata-headers/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/tls-metadata-headers/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/udp-log/index.md b/app/_ai_gateway_policies/udp-log/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/udp-log/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/upstream-oauth/index.md b/app/_ai_gateway_policies/upstream-oauth/index.md new file mode 100644 index 00000000000..3247b425da9 --- /dev/null +++ b/app/_ai_gateway_policies/upstream-oauth/index.md @@ -0,0 +1,10 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +description: Configure {{site.ai_gateway_name}} to obtain an OAuth2 token to consume an upstream API +--- diff --git a/app/_ai_gateway_policies/upstream-timeout/index.md b/app/_ai_gateway_policies/upstream-timeout/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/upstream-timeout/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/vault-auth/index.md b/app/_ai_gateway_policies/vault-auth/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/vault-auth/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/websocket-size-limit/index.md b/app/_ai_gateway_policies/websocket-size-limit/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/websocket-size-limit/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/websocket-validator/index.md b/app/_ai_gateway_policies/websocket-validator/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/websocket-validator/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/xml-threat-protection/index.md b/app/_ai_gateway_policies/xml-threat-protection/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/xml-threat-protection/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_ai_gateway_policies/zipkin/index.md b/app/_ai_gateway_policies/zipkin/index.md new file mode 100644 index 00000000000..ca3f31a2e3a --- /dev/null +++ b/app/_ai_gateway_policies/zipkin/index.md @@ -0,0 +1,9 @@ +--- +min_version: + ai-gateway: '2.0' +works_on: + - konnect +products: + - ai-gateway +content_type: plugin +--- diff --git a/app/_assets/javascripts/apps/components/SearchModalResultItem.vue b/app/_assets/javascripts/apps/components/SearchModalResultItem.vue index 81fb11a4d62..5c95f2dc191 100644 --- a/app/_assets/javascripts/apps/components/SearchModalResultItem.vue +++ b/app/_assets/javascripts/apps/components/SearchModalResultItem.vue @@ -59,7 +59,7 @@ export default { return this.item.title; } if (this.item.content_type === 'plugin') { - if (this.item.products && (this.item.products.includes('mesh') || this.item.products.includes('event-gateway'))) { + if (this.item.products && (this.item.products.includes('mesh') || this.item.products.includes('event-gateway') || this.item.products.includes('ai-gateway'))) { return `${this.item.hierarchy.lvl1} Policy`; } else { return `${this.item.hierarchy.lvl1} Plugin`; @@ -79,7 +79,7 @@ export default { .map(([key, value]) => value); if (this.item.content_type === 'plugin') { - if (this.item.products && (this.item.products.includes('mesh') || this.item.products.includes('event-gateway'))) { + if (this.item.products && (this.item.products.includes('mesh') || this.item.products.includes('event-gateway') || this.item.products.includes('ai-gateway'))) { levels.unshift('Policies') } else { levels.unshift('Plugins') diff --git a/app/_config/releases/ai-gateway/v1.yml b/app/_config/releases/ai-gateway/v1.yml index ba789e9bc75..a061638f9e7 100644 --- a/app/_config/releases/ai-gateway/v1.yml +++ b/app/_config/releases/ai-gateway/v1.yml @@ -426,5 +426,5 @@ app/ai-gateway/v1/semantic-similarity.md: status: pending canonical_url: app/ai-gateway/v1/streaming.md: - status: pending - canonical_url: + # status: pending + canonical_url: /ai-gateway/streaming/ diff --git a/app/_data/ai-gateway/v2/otel-metrics.yaml b/app/_data/ai-gateway/v2/otel-metrics.yaml new file mode 100644 index 00000000000..9b8da8980f0 --- /dev/null +++ b/app/_data/ai-gateway/v2/otel-metrics.yaml @@ -0,0 +1,332 @@ +metrics: + - name: gen_ai.client.operation.duration + min_version: "" + description: Total time Kong spends processing a Gen AI operation, such as an LLM request. Requires `enable_request_metrics` to populate the `error.type` attribute. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - error.type + - name: gen_ai.server.request.duration + min_version: "" + description: Time the LLM provider spends processing the request. Requires `enable_latency_metrics` set to `true`. Requires `enable_request_metrics` to populate the `error.type` attribute. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - error.type + - name: gen_ai.client.token.usage + min_version: "" + description: Number of tokens consumed by the Gen AI operation. + unit: "{token}" + type: Sum + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.token.type + - gen_ai.operation.name + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: gen_ai.server.time_to_first_token + min_version: "" + description: Time from when the model server receives the request until the first output token is generated. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: gen_ai.server.time_per_output_token + min_version: "" + description: Time between successive output tokens generated by the model server after the first token. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.llm.cost + min_version: "" + description: Cost of AI requests. + unit: "{cost}" + type: Sum + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.gen_ai.cache.status + - kong.gen_ai.vector_db + - kong.gen_ai.embeddings.provider + - kong.gen_ai.embeddings.model + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.cache.fetch.latency + min_version: "" + description: Time to fetch a response from the semantic cache. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.gen_ai.cache.status + - kong.gen_ai.vector_db + - kong.gen_ai.embeddings.provider + - kong.gen_ai.embeddings.model + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.cache.embeddings.latency + min_version: "" + description: Time to generate embeddings during cache operations. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.gen_ai.cache.status + - kong.gen_ai.vector_db + - kong.gen_ai.embeddings.provider + - kong.gen_ai.embeddings.model + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.rag.fetch.latency + min_version: "" + description: Time to fetch data from a RAG source. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.gen_ai.cache.status + - kong.gen_ai.vector_db + - kong.gen_ai.embeddings.provider + - kong.gen_ai.embeddings.model + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.rag.embeddings.latency + min_version: "" + description: Time to generate embeddings for RAG operations. + unit: "s" + type: Histogram + attributes: + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + - gen_ai.operation.name + - kong.gen_ai.cache.status + - kong.gen_ai.vector_db + - kong.gen_ai.embeddings.provider + - kong.gen_ai.embeddings.model + - kong.workspace.name + - kong.auth.consumer.name + - kong.gen_ai.request.mode + - name: kong.gen_ai.aws.guardrails.latency + min_version: "" + description: Time for AWS Guardrails to process a request. + unit: "s" + type: Histogram + attributes: + - kong.gen_ai.aws.guardrails.id + - kong.gen_ai.aws.guardrails.version + - kong.gen_ai.aws.guardrails.mode + - kong.gen_ai.aws.guardrails.region + - kong.workspace.name + - kong.auth.consumer.name + - name: kong.gen_ai.mcp.response.size + min_version: "" + description: Size of the MCP response body in bytes. + unit: "By" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - mcp.method.name + - gen_ai.tool.name + - name: kong.gen_ai.mcp.request.error.count + min_version: "" + description: Number of MCP request errors. + unit: "{error}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - mcp.method.name + - gen_ai.tool.name + - error.type + - name: mcp.client.operation.duration + min_version: "" + description: Duration of the MCP request as observed by the sender. Only available when the MCP entity is in passthrough-listener mode. Requires `enable_latency_metrics` set to `true`. + unit: "s" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - mcp.method.name + - gen_ai.tool.name + - error.type + - gen_ai.operation.name + - name: mcp.server.operation.duration + min_version: "" + description: Duration of the MCP request as observed by the receiver. + unit: "s" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - mcp.method.name + - gen_ai.tool.name + - error.type + - gen_ai.operation.name + - name: kong.gen_ai.mcp.acl.allowed + min_version: "" + description: Number of MCP requests allowed by ACL rules. + unit: "{request}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.mcp.primitive + - kong.gen_ai.mcp.primitive_name + - name: kong.gen_ai.mcp.acl.denied + min_version: "" + description: Number of MCP requests denied by ACL rules. + unit: "{request}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.mcp.primitive + - kong.gen_ai.mcp.primitive_name + - name: kong.gen_ai.a2a.request.count + min_version: "" + description: Total number of A2A requests. + unit: "{request}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.method + - kong.gen_ai.a2a.binding + - name: kong.gen_ai.a2a.request.duration + min_version: "" + description: Duration of an A2A request in seconds. + unit: "s" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.method + - kong.gen_ai.a2a.binding + - name: kong.gen_ai.a2a.response.size + min_version: "" + description: Size of the A2A response body in bytes. + unit: "By" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.method + - kong.gen_ai.a2a.binding + - name: kong.gen_ai.a2a.ttfb + min_version: "" + description: Time to first byte for A2A streaming responses in seconds. + unit: "s" + type: Histogram + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.method + - kong.gen_ai.a2a.binding + - name: kong.gen_ai.a2a.request.error.count + min_version: "" + description: Number of A2A request errors. + unit: "{error}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.method + - kong.gen_ai.a2a.binding + - kong.gen_ai.a2a.error.type + - name: kong.gen_ai.a2a.task.state.count + min_version: "" + description: Number of A2A task state transitions. + unit: "{state}" + type: Sum + attributes: + - kong.service.name + - kong.route.name + - kong.workspace.name + - kong.gen_ai.a2a.task.state + +attributes: + kong.service.name: Name of the Gateway Service. + kong.route.name: Name of the Route. + kong.auth.consumer.name: Name of the authenticated Consumer. + kong.workspace.name: Name of the Workspace. + error.type: Type of error that occurred. + gen_ai.provider.name: Name of the Gen AI provider. + gen_ai.request.model: Model name targeted by the request. + gen_ai.response.model: Model name reported by the provider in the response. + gen_ai.operation.name: "Operation requested, such as `chat` or `embeddings`." + gen_ai.token.type: "Token category: `input`, `output`, or `total`." + kong.gen_ai.request.mode: "Request mode: `oneshot`, `stream`, or `realtime`." + kong.gen_ai.cache.status: "Cache status: `hit` or empty if not cached." + kong.gen_ai.vector_db: "Vector database used for caching, such as `redis`." + kong.gen_ai.embeddings.provider: Embeddings provider used for caching. + kong.gen_ai.embeddings.model: Embeddings model used for caching. + kong.gen_ai.aws.guardrails.id: ID of the AWS Guardrails configuration. + kong.gen_ai.aws.guardrails.version: Version of the AWS Guardrails configuration. + kong.gen_ai.aws.guardrails.mode: Mode of the AWS Guardrails evaluation. + kong.gen_ai.aws.guardrails.region: AWS region of the Guardrails service. + mcp.method.name: "MCP method name, such as `tools/call`." + gen_ai.tool.name: Name of the MCP tool invoked. + kong.gen_ai.mcp.primitive: "MCP primitive type, such as `tool`." + kong.gen_ai.mcp.primitive_name: Name of the MCP primitive. + kong.gen_ai.a2a.method: A2A method name. + kong.gen_ai.a2a.binding: A2A binding type. + kong.gen_ai.a2a.error.type: Type of the A2A error. + kong.gen_ai.a2a.task.state: "Task state, such as `completed`, `failed`, or `in_progress`." diff --git a/app/_data/ai-gateway/v2/otel-span-attributes.yaml b/app/_data/ai-gateway/v2/otel-span-attributes.yaml new file mode 100644 index 00000000000..a4c73882637 --- /dev/null +++ b/app/_data/ai-gateway/v2/otel-span-attributes.yaml @@ -0,0 +1,75 @@ +spans: + - name: kong.gen_ai + title: Gen AI span attributes + min_version: "" + description: Gen AI tracing span emitted for LLM requests. + attributes: + - gen_ai.operation.name + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.request.max_tokens + - gen_ai.request.temperature + - gen_ai.input.messages + - gen_ai.output.type + - gen_ai.output.messages + - gen_ai.response.id + - gen_ai.response.model + - gen_ai.response.finish_reasons + - gen_ai.usage.input_tokens + - gen_ai.usage.output_tokens + - name: kong.gen_ai + title: Gen AI tool call span attributes + min_version: "" + description: Gen AI tracing span emitted when the provider response includes a tool call. + attributes: + - gen_ai.operation.name + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.request.max_tokens + - gen_ai.request.temperature + - gen_ai.response.finish_reasons + - gen_ai.response.id + - gen_ai.response.model + - gen_ai.tool.call.id + - gen_ai.tool.name + - gen_ai.tool.type + - gen_ai.usage.input_tokens + - gen_ai.usage.output_tokens + - gen_ai.output.type + - name: kong.a2a + title: A2A span attributes + min_version: "" + description: A2A tracing span emitted for agent-to-agent requests. + attributes: + - kong.a2a.protocol.version + - rpc.system + - rpc.method + - kong.a2a.task.id + - kong.a2a.task.state + - kong.a2a.context.id + - kong.a2a.operation + +attributes: + gen_ai.operation.name: "Operation requested, such as `chat` or `embeddings`." + gen_ai.provider.name: Name of the Gen AI provider. + gen_ai.request.model: Model name targeted by the request. + gen_ai.request.max_tokens: Maximum token limit configured for the request. + gen_ai.request.temperature: Sampling temperature configured for the request. + gen_ai.input.messages: Array of input messages sent to the model. + gen_ai.output.type: Output payload type, such as `json`. + gen_ai.output.messages: Array containing the full model response payload. + gen_ai.response.id: Unique identifier returned by the provider for the response. + gen_ai.response.model: Model name reported by the provider in the response. + gen_ai.response.finish_reasons: Array of finish reasons returned by the provider. + gen_ai.usage.input_tokens: Number of input tokens consumed by the request. + gen_ai.usage.output_tokens: Number of output tokens generated in the response. + gen_ai.tool.call.id: Unique identifier for the specific tool call. + gen_ai.tool.name: Name of the tool or function requested by the model. + gen_ai.tool.type: Tool type, such as `function`. + kong.a2a.protocol.version: A2A protocol version used for the request. + rpc.system: RPC protocol used by the request, such as `jsonrpc`. + rpc.method: RPC method invoked by the client. + kong.a2a.task.id: Identifier of the A2A task. + kong.a2a.task.state: Current state of the A2A task. + kong.a2a.context.id: Identifier of the A2A conversation context. + kong.a2a.operation: A2A operation name, such as `message/send`. diff --git a/app/_data/policies/ai-gateway/scopes.json b/app/_data/policies/ai-gateway/scopes.json new file mode 100644 index 00000000000..8f997b75ff9 --- /dev/null +++ b/app/_data/policies/ai-gateway/scopes.json @@ -0,0 +1,1050 @@ +[ + { + "name": "ace", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "acl", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "acme", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "ai-aws-guardrails", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-azure-content-safety", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-custom-guardrail", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-gcp-model-armor", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-lakera-guard", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-llm-as-judge", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-mcp-oauth2", + "scopes": [ + "mcp-servers", + "global" + ] + }, + { + "name": "ai-prompt-compressor", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-prompt-decorator", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-prompt-guard", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-prompt-template", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-rag-injector", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-rate-limiting-advanced", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-request-transformer", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-response-transformer", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-sanitizer", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-semantic-cache", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-semantic-prompt-guard", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ai-semantic-response-guard", + "scopes": [ + "models", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "app-dynamics", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "aws-lambda", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "azure-functions", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "basic-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "bot-detection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "canary", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "confluent", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "confluent-consume", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "correlation-id", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "cors", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "datadog", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "datakit", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "degraphql", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "exit-transformer", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "file-log", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "forward-proxy", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "graphql-proxy-cache-advanced", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "graphql-rate-limiting-advanced", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "grpc-gateway", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "grpc-web", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "header-cert-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "hmac-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "http-log", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "injection-protection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "ip-restriction", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "jq", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "json-threat-protection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "jwe-decrypt", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "jwt", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "jwt-signer", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "kafka-consume", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "kafka-log", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "kafka-upstream", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "key-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "ldap-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "ldap-auth-advanced", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "loggly", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "metering-and-billing", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "mocking", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "mtls-auth", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "oas-validation", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "oauth2-introspection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "opa", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "openid-connect", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "opentelemetry", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "post-function", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "pre-function", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "prometheus", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "proxy-cache", + "scopes": [ + "consumers", + "consumer-groups", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "proxy-cache-advanced", + "scopes": [ + "consumers", + "consumer-groups", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "rate-limiting", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "rate-limiting-advanced", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "redirect", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-callout", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-size-limiting", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-termination", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-transformer", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-transformer-advanced", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "request-validator", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "response-ratelimiting", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "response-transformer", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "response-transformer-advanced", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "route-by-header", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "global" + ] + }, + { + "name": "route-transformer-advanced", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "global" + ] + }, + { + "name": "saml", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "service-protection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "session", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "solace-consume", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "solace-log", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "solace-upstream", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "standard-webhooks", + "scopes": [ + "consumer-groups", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "statsd", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "syslog", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "tcp-log", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "tls-handshake-modifier", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "tls-metadata-headers", + "scopes": [ + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "udp-log", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "upstream-oauth", + "scopes": [ + "consumers", + "consumer-groups", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "upstream-timeout", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + }, + { + "name": "websocket-size-limit", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "websocket-validator", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "xml-threat-protection", + "scopes": [ + "models", + "mcp-servers", + "agents", + "consumers", + "consumer-groups", + "global" + ] + }, + { + "name": "zipkin", + "scopes": [ + "consumers", + "models", + "mcp-servers", + "agents", + "global" + ] + } +] diff --git a/app/_includes/banners/cross_major_banner.md b/app/_includes/banners/cross_major_banner.md index 833b81a5a2f..1656aba2460 100644 --- a/app/_includes/banners/cross_major_banner.md +++ b/app/_includes/banners/cross_major_banner.md @@ -1,5 +1,5 @@ {% if include.major_version -%} {:.warning} -> _You are browsing documentation for an older major version - {{page.cross_major_banner_info.major_version}} - of {{page.cross_major_banner_info.product}}._ +> _You are browsing documentation for an older version of {{page.cross_major_banner_info.product}}._ > _See the latest documentation [here]({{ include.canonical_url }})._ {% endif %} \ No newline at end of file diff --git a/app/_includes/cards/plugin.html b/app/_includes/cards/plugin.html index 2d93aa989fa..262ee2c505d 100644 --- a/app/_includes/cards/plugin.html +++ b/app/_includes/cards/plugin.html @@ -16,7 +16,9 @@ data-trusted-content="{{trusted_content}}" {% if plugin.tier %}data-tier="{{plugin.tier}}"{% endif %} > - +{% assign url = plugin.url %} +{% if plugin.overview_url %}{% assign url = plugin.overview_url %}{% endif %} +
diff --git a/app/_includes/components/aigw_policy.html b/app/_includes/components/aigw_policy.html new file mode 100644 index 00000000000..cb9876614c0 --- /dev/null +++ b/app/_includes/components/aigw_policy.html @@ -0,0 +1 @@ +{% include card.html icon=policy.icon title=policy.name description=policy.description cta_url=policy.overview_url cta_text='See policy' %} \ No newline at end of file diff --git a/app/_includes/components/aigw_policy.md b/app/_includes/components/aigw_policy.md new file mode 100644 index 00000000000..3c1101d17cd --- /dev/null +++ b/app/_includes/components/aigw_policy.md @@ -0,0 +1 @@ +{% include card.md icon=policy.icon title=policy.name description=policy.description cta_url=policy.overview_url cta_text='See policy' heading_level=heading_level %} \ No newline at end of file diff --git a/app/_includes/header.html b/app/_includes/header.html index 99dcc8dbd9d..a608d053d34 100644 --- a/app/_includes/header.html +++ b/app/_includes/header.html @@ -190,7 +190,7 @@ {% include_cached header/menu_caret.html %} - + +
+
+ +
+ AI Gateway Policies +
+ {% for category in site.data.plugin_categories %} + + {% include_svg category.icon width="20" height="20" %} + {{category.text}} + + {% endfor %} +
+ View all → +
diff --git a/app/_includes/info_box/plugin.html b/app/_includes/info_box/plugin.html index d311f14ba49..461d47ae3d0 100644 --- a/app/_includes/info_box/plugin.html +++ b/app/_includes/info_box/plugin.html @@ -22,6 +22,10 @@ {% include_cached info_box/sections/priority.html priority=page.priority %} {% endif %} +{% if page.scopes %} +{% include_cached info_box/sections/scopes.html scopes=page.scopes %} +{% endif %} + {% if page.min_version %} {% include_cached info_box/sections/min_version.html min_version=page.min_version %} {% endif %} diff --git a/app/_includes/info_box/sections/scopes.html b/app/_includes/info_box/sections/scopes.html new file mode 100644 index 00000000000..c3e91d913aa --- /dev/null +++ b/app/_includes/info_box/sections/scopes.html @@ -0,0 +1,20 @@ +
+
+ Scopes +
+
+ {% for scope in include.scopes %} +
+ {% if scope == 'global' %} + Global + {% else %} +
+ {% include mask_image.html image_url='/assets/icons/service-document.svg' css_classes="w-5 h-5 shrink-0 !bg-icon" %} + {% assign entity_page = site.ai_gateway_entities | where: "slug", scope | first %} + {{ entity_page.title }} +
+ {% endif %} +
+ {% endfor %} +
+
\ No newline at end of file diff --git a/app/_includes/landing_pages/aigw_policy.md b/app/_includes/landing_pages/aigw_policy.md new file mode 100644 index 00000000000..5d669d04cd9 --- /dev/null +++ b/app/_includes/landing_pages/aigw_policy.md @@ -0,0 +1 @@ +{% aigw_policy include.config %} \ No newline at end of file diff --git a/app/_includes/layouts/policies/nav_header.html b/app/_includes/layouts/policies/nav_header.html index a5506a52cd0..6ea6e8b5605 100644 --- a/app/_includes/layouts/policies/nav_header.html +++ b/app/_includes/layouts/policies/nav_header.html @@ -2,7 +2,7 @@
- Overview + {% if page.has_overview? %}Overview{% endif %} {% if page.get_started_url %}Examples{% endif %} Configuration reference
diff --git a/app/_includes/md/ai-gateway/v2/policies/collecting-otel-data.md b/app/_includes/md/ai-gateway/v2/policies/collecting-otel-data.md new file mode 100644 index 00000000000..39681c13ddc --- /dev/null +++ b/app/_includes/md/ai-gateway/v2/policies/collecting-otel-data.md @@ -0,0 +1,19 @@ +## Collecting telemetry data + +To set up an OpenTelemetry backend for {{site.ai_gateway}}, you need support for OTLP over HTTP with Protobuf encoding. You can: + +* Send data directly to an OpenTelemetry-compatible backend that natively supports OTLP over HTTP with Protobuf encoding, like Jaeger (v1.35.0+). + + This is the simplest setup, since it doesn't require any additional components between the data plane and the backend. + +* Use the OpenTelemetry Collector, which acts as an intermediary between the data plane and one or more backends. + + OTEL Collector can receive all OpenTelemetry signals supported by the {{site.ai_gateway}} OpenTelemetry Policy, including traces, metrics, and logs, and then process, transform, or route that data before exporting it to a compatible backend. + + This option is useful when you need capabilities such as signal fan-out, filtering, enrichment, batching, or exporting to multiple backends. The OpenTelemetry Collector supports a wide range of exporters, available at [open-telemetry/opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter). + +{% assign policy = include.policy | default: "default" %} +{% unless policy == "OpenTelemetry" %} +{:.info} +> Check [OpenTelemetry Policy](/ai-gateway/entities/ai-opentelemetry-policy/) and [{{site.base_gateway}} tracing](/gateway/tracing/) documentation for more details about OpenTelemetry and tracing in {{site.ai_gateway}}. +{% endunless %} diff --git a/app/_includes/md/ai-gateway/v2/policies/metric_tables.md b/app/_includes/md/ai-gateway/v2/policies/metric_tables.md new file mode 100644 index 00000000000..a0c6ec13f44 --- /dev/null +++ b/app/_includes/md/ai-gateway/v2/policies/metric_tables.md @@ -0,0 +1,43 @@ +{%- assign metrics = site.data.ai-gateway.v2.otel-metrics.metrics -%} +{%- assign attributes = site.data.ai-gateway.v2.otel-metrics.attributes -%} +{% for metric in metrics %} +{% if include.metric_prefixes %} +{% assign found = false %} +{% assign prefixes = include.metric_prefixes | split: ',' %} +{% for prefix in prefixes %} +{% assign prefix_stripped = prefix | strip %} +{% assign metric_prefix = metric.name | slice: 0, prefix_stripped.size | strip %} +{% if metric_prefix == prefix_stripped %} +{% assign found = true %} +{% break %} +{% endif %} +{% endfor %} +{% unless found %}{% continue %}{% endunless %} +{% endif %} +#### {{metric.name}}{% if metric.min_version != "" %} {% new_in metric.min_version %}{% endif %} + +{{metric.description}} + +{% if metric.unit %}- **Instrument unit**: `{{metric.unit}}`{% endif %} +{% if metric.type %}- **Instrument type**: `{{metric.type}}`{% endif %} +{% if metric.attributes %}- **Attributes**: +{% capture attrs_table %} +{% table %} +vertical_align: middle +columns: + - title: Attribute + key: attribute + - title: Attribute description + key: description +rows: +{% for attribute in metric.attributes %} + - id: "{{attribute}}" + attribute: "`{{ attribute }}`" + description: | +{{attributes[attribute] | indent: 6}} +{% endfor %} +{% endtable %} +{% endcapture %} +{{attrs_table | indent: 2}} +{% else %}- **No attributes**{% endif %} +{% endfor %} diff --git a/app/_includes/md/ai-gateway/v2/policies/span_attribute_tables.md b/app/_includes/md/ai-gateway/v2/policies/span_attribute_tables.md new file mode 100644 index 00000000000..838ec60066e --- /dev/null +++ b/app/_includes/md/ai-gateway/v2/policies/span_attribute_tables.md @@ -0,0 +1,30 @@ +{%- assign spans = site.data.ai-gateway.v2.otel-span-attributes.spans -%} +{%- assign attributes = site.data.ai-gateway.v2.otel-span-attributes.attributes -%} +{% for span in spans %} +#### {{ span.title | default: span.name }}{% if span.min_version != "" %} {% new_in span.min_version %}{% endif %} + +{{ span.description }} + +{% if span.title and span.title != span.name %} The following span attributes use the `{{ span.name }}` prefix{% if span.name == "kong.a2a" %} or the `rpc` prefix{% endif %}:{% endif %} + + +{% capture attrs_table %} +{% table %} +vertical_align: middle +columns: + - title: Attribute + key: attribute + - title: Attribute description + key: description +rows: +{% for attribute in span.attributes %} + - id: "{{attribute}}" + attribute: "`{{ attribute }}`" + description: | +{{attributes[attribute] | indent: 6}} +{% endfor %} +{% endtable %} +{% endcapture %} +{{attrs_table | indent: 2}} +{% endfor %} + diff --git a/app/_includes/plugins/ai-a2a-proxy/log-output-fields.md b/app/_includes/plugins/ai-a2a-proxy/log-output-fields.md index 240d0295692..6d9a9533b73 100644 --- a/app/_includes/plugins/ai-a2a-proxy/log-output-fields.md +++ b/app/_includes/plugins/ai-a2a-proxy/log-output-fields.md @@ -1,4 +1,4 @@ -When `config.logging.log_statistics` is enabled, the plugin writes the following fields to the +When `config.logging.log_statistics` is enabled, it writes the following fields to the `ai.a2a.rpc[]` array: {% table %} diff --git a/app/_includes/policies/index/filters.html b/app/_includes/policies/index/filters.html new file mode 100644 index 00000000000..d5d33a1a08e --- /dev/null +++ b/app/_includes/policies/index/filters.html @@ -0,0 +1,80 @@ +
+ +
\ No newline at end of file diff --git a/app/_includes/policies/index/plugin_cards.html b/app/_includes/policies/index/plugin_cards.html new file mode 100644 index 00000000000..56d11ed6db1 --- /dev/null +++ b/app/_includes/policies/index/plugin_cards.html @@ -0,0 +1,29 @@ +
+ {% for cat in include.categories %} + {% assign plugins_for_category = include.plugins | where_exp: "plugin", "plugin.categories contains cat.slug" | sort: + "name" %} + {% if plugins_for_category.size > 0 %} +
+

{{ cat.text }}

+ +
+ {% for plugin in plugins_for_category %} + {% include cards/plugin.html plugin=plugin %} + {% endfor %} +
+
+ {% endif %} + {% endfor %} + + {% if include.third_party_plugins.size > 0 %} +
+

3rd Party Plugins

+ +
+ {% for plugin in include.third_party_plugins %} + {% include cards/plugin.html plugin=plugin %} + {% endfor %} +
+
+ {% endif %} +
\ No newline at end of file diff --git a/app/_includes/policies/index/search_input.html b/app/_includes/policies/index/search_input.html new file mode 100644 index 00000000000..44cc2cf81b1 --- /dev/null +++ b/app/_includes/policies/index/search_input.html @@ -0,0 +1,21 @@ +
+
+
+ + + + +
+
+ +
+ +
+
\ No newline at end of file diff --git a/app/_landing_pages/ai-gateway.yaml b/app/_landing_pages/ai-gateway.yaml index 2f259c8706b..9278558e9fa 100644 --- a/app/_landing_pages/ai-gateway.yaml +++ b/app/_landing_pages/ai-gateway.yaml @@ -4,10 +4,10 @@ metadata: description: This page is an introduction to {{site.ai_gateway}}. products: - ai-gateway - - gateway works_on: - - on-prem - konnect + min_version: + ai-gateway: '2.0' tags: - ai @@ -132,7 +132,7 @@ rows: description: Secure Claude with single sign-on authentication through {{site.ai_gateway}}. icon: /assets/icons/security.svg cta: - url: /cookbooks/claude-sso/ + url: /cookbooks/claude-code-sso/ align: end - blocks: - type: card @@ -180,8 +180,6 @@ rows: - type: unordered_list items: - "[{{site.ai_gateway}} resource sizing guidelines](/ai-gateway/resource-sizing-guidelines-ai/): Review recommended resource allocation guidelines for {{site.ai_gateway}}." - - "[Deployment topologies](/gateway/deployment-topologies/): Learn about the different ways to deploy {{ site.base_gateway }}." - - "[Hosting options](/gateway/topology-hosting-options/): Decide where you want to host your Data Plane nodes, and whether you want Kong to host them or host them yourself." - header: type: h2 @@ -248,7 +246,7 @@ rows: type: h2 text: "Govern {{site.ai_gateway}} with entities and policies" description: | - Enforce authentication, rate limiting, guardrails, transformations, and governance by attaching AI Policies to your AI entities. Create Models, Providers, Agents, and MCP Servers to manage your AI traffic. + Enforce authentication, rate limiting, guardrails, transformations, and governance by attaching AI Policies to your AI entities. Create AI Models, AI Providers, AI Agents, and AI MCP Servers to manage your AI traffic. column_count: 3 columns: - blocks: @@ -335,15 +333,15 @@ rows: For more information, see the full list of [Data Governance](/ai-gateway/ai-data-gov/) capabilities. columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-prompt-guard - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-semantic-prompt-guard - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-sanitizer @@ -356,11 +354,11 @@ rows: {{site.ai_gateway}} supports policy-managed prompt capabilities that allow you to set defaults and manipulate prompts as they pass through [AI Model](/ai-gateway/entities/ai-model/) or [AI Agent](/ai-gateway/entities/ai-agent/) traffic. columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-prompt-template - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-prompt-decorator @@ -373,32 +371,32 @@ rows: column_count: 3 columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-azure-content-safety - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-aws-guardrails - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-gcp-model-armor - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-semantic-prompt-guard - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-semantic-response-guard - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-lakera-guard icon: ai-lakera.png - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-custom-guardrail icon: ai-custom-guardrail.png @@ -410,14 +408,13 @@ rows: {{site.ai_gateway}} allows you to use AI technology to augment other API traffic. One example is routing API responses through an AI language translation prompt before returning it to the client. {{site.ai_gateway}} provides two policies that can be used in conjunction with other upstream API services to weave AI capabilities into API request processing. - These policies can be configured independently of AI Proxy. columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-request-transformer - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-response-transformer @@ -443,7 +440,7 @@ rows: - column_count: 2 columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-rag-injector @@ -480,10 +477,9 @@ rows: description: | The {{site.ai_gateway}} helps reduce LLM usage costs by giving you control over how prompts are built and routed. You can compress and structure prompts efficiently using AI Compressor, RAG Injector, and AI Prompt Decorator policies. - For further savings, you can use AI Proxy Advanced to route requests across OpenAI models based on semantic similarity. columns: - blocks: - - type: plugin + - type: aigw_policy config: slug: ai-prompt-compressor - blocks: @@ -495,15 +491,15 @@ rows: cta: url: /metering-and-billing/ align: end - - blocks: - - type: card - config: - title: Save LLM usage costs with semantic load balancing - description: Use semantic load balancing to optimize LLM usage and reduce costs by intelligently routing chat requests across multiple OpenAI models based on semantic similarity. - icon: /assets/icons/money.svg - cta: - url: /how-to/use-semantic-load-balancing - align: end + # - blocks: + # - type: card + # config: + # title: Save LLM usage costs with semantic load balancing + # description: Use semantic load balancing to optimize LLM usage and reduce costs by intelligently routing chat requests across multiple OpenAI models based on semantic similarity. + # icon: /assets/icons/money.svg + # cta: + # url: /how-to/use-semantic-load-balancing + # align: end - header: type: h2 text: "Observability and metrics" @@ -567,9 +563,9 @@ rows: - blocks: - type: faqs config: - - q: Is {{site.ai_gateway}} available for all deployment modes? + - q: How do I deploy {{site.ai_gateway}}? a: | - {{site.ai_gateway}} capabilities (AI, MCP, and A2A traffic management) are available across [deployment modes](/gateway/deployment-topologies/), including {{site.konnect_short_name}}, self-hosted traditional, hybrid, and DB-less, and on Kubernetes via the [{{site.kic_product_name}}](/kubernetes-ingress-controller/). + {{site.ai_gateway}} is managed through {{site.konnect_short_name}}. Data plane nodes run in your environment (self-hosted, cloud, or Kubernetes) and connect to {{site.konnect_short_name}} for configuration and observability. - q: Why should I use {{site.ai_gateway}} instead of adding the LLM's API behind {{site.base_gateway}}? a: | diff --git a/app/_landing_pages/ai-gateway/a2a.yaml b/app/_landing_pages/ai-gateway/a2a.yaml index 2630b78b69a..9e770f0e554 100644 --- a/app/_landing_pages/ai-gateway/a2a.yaml +++ b/app/_landing_pages/ai-gateway/a2a.yaml @@ -4,10 +4,10 @@ metadata: description: Observe Agent-to-Agent (A2A) protocol traffic through {{site.ai_gateway}}. products: - ai-gateway - - gateway works_on: - - on-prem - konnect + min_version: + ai-gateway: '2.0' tags: - ai - a2a @@ -69,15 +69,15 @@ rows: - type: card config: icon: /assets/icons/lock.svg - title: Secure and govern with Policies - description: Secure A2A agents and control access with Policies. + title: Secure and govern with AI Policies + description: Secure A2A agents and control access with AI Policies. ctas: - text: OpenID Connect - url: "/plugins/openid-connect/" + url: "/ai-gateway/policies/openid-connect/" - text: Rate Limiting - url: "/plugins/?category=traffic-control" - - text: Authentication plugins - url: "/plugins/?category=authentication" + url: "/ai-gateway/policies/?category=traffic-control" + - text: Authentication policies + url: "/ai-gateway/policies/?category=authentication" - header: type: h2 diff --git a/app/_landing_pages/ai-gateway/ai-providers.yaml b/app/_landing_pages/ai-gateway/ai-providers.yaml index ea1dfecfd35..3c36f4d5975 100644 --- a/app/_landing_pages/ai-gateway/ai-providers.yaml +++ b/app/_landing_pages/ai-gateway/ai-providers.yaml @@ -5,7 +5,6 @@ metadata: products: - ai-gateway works_on: - - on-prem - konnect breadcrumbs: - /ai-gateway/ diff --git a/app/_landing_pages/ai-gateway/mcp.yaml b/app/_landing_pages/ai-gateway/mcp.yaml index ea967d38a1f..84b13fe4163 100644 --- a/app/_landing_pages/ai-gateway/mcp.yaml +++ b/app/_landing_pages/ai-gateway/mcp.yaml @@ -4,10 +4,10 @@ metadata: description: This page is an introduction to MCP Traffic Gateway capabilities in {{site.ai_gateway}}. products: - ai-gateway - - gateway works_on: - - on-prem - konnect + min_version: + ai-gateway: '2.0' breadcrumbs: - /ai-gateway/ tags: @@ -67,21 +67,21 @@ rows: text: | Attach [AI Policies](/ai-gateway/entities/ai-policy/) to your [AI MCP Server](/ai-gateway/entities/ai-mcp-server/) entities to apply security, governance, and observability controls across your MCP infrastructure. - Use AI Policies and Kong Gateway plugins to: - - Secure access with the MCP OAuth2 policy or other authentication methods + Use AI Policies to: + - Secure access with the MCP OAuth2 AI Policy or other authentication methods - Monitor MCP traffic using AI metrics and AI audit logs - Enforce access controls for MCP tool usage - - Govern usage with rate limiting and traffic control plugins + - Govern usage with rate limiting and traffic control - type: card config: icon: /assets/icons/lock.svg - title: Security and governance with Policies + title: Security and governance with AI Policies description: Secure MCP servers and govern traffic with AI Policies. ctas: - text: MCP OAuth2 policy - url: "/ai-gateway/entities/ai-policy/" + url: "/ai-gateway/policies/ai-mcp-oauth2/" - text: Rate Limiting - url: "/plugins/rate-limiting/" + url: "/ai-gateway/policies/rate-limiting/" - text: Observability url: "/ai-gateway/ai-audit-log-reference/#ai-mcp-logs" diff --git a/app/_layouts/ai_gateway_policies/reference.html b/app/_layouts/ai_gateway_policies/reference.html new file mode 100644 index 00000000000..d10e100b7db --- /dev/null +++ b/app/_layouts/ai_gateway_policies/reference.html @@ -0,0 +1,13 @@ +--- +layout: policies/with_aside +plugin_schema: true +--- + +
+

Configuration

+
+
+ + \ No newline at end of file diff --git a/app/_llms.txt b/app/_llms.txt index f76eb16bead..a3996307c3e 100644 --- a/app/_llms.txt +++ b/app/_llms.txt @@ -32,8 +32,15 @@ This file lists all available documentation pages as Markdown. Each link points - [{{ p.llm_title | liquify }}]({{ site.links.web }}{{ p.url }}): {{ p.description | liquify | rstrip }} {% endfor %} -## Plugins +## API Gateway Plugins {% for p in plugin_pages -%} - [{{ p.llm_title | liquify }}]({{ site.links.web }}{{ p.url }}): {{ p.description | liquify | rstrip }} {% endfor %} + + +## AI Gateway Policies + +{% for p in ai_gateway_policy_pages -%} +- [{{ p.llm_title | liquify }}]({{ site.links.web }}{{ p.url }}): {{ p.description | liquify | rstrip }} +{% endfor %} diff --git a/app/_plugins/drops/plugins/aigw_policy_schema.rb b/app/_plugins/drops/plugins/aigw_policy_schema.rb new file mode 100644 index 00000000000..531bcf6ac7b --- /dev/null +++ b/app/_plugins/drops/plugins/aigw_policy_schema.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'json' + +module Jekyll + module Drops + module Plugins + class AIGWPolicySchema < Liquid::Drop # rubocop:disable Style/Documentation + SCHEMAS_DIR = File.expand_path('../../../_schemas/ai-gateway/policies', __dir__).freeze + FILE_INDEX = Dir.glob(File.join(SCHEMAS_DIR, '*.json')) + .to_h { |f| [File.basename(f).downcase, f] } + .freeze + + def initialize(slug:) # rubocop:disable Lint/MissingSuper + @slug = slug + end + + def as_json(*) + @as_json ||= { 'properties' => { 'config' => schema.dig('properties', 'config') } } + end + + private + + def schema + @schema ||= JSON.parse(File.read(file_path)) + end + + def file_path + @file_path ||= FILE_INDEX["#{@slug.delete('-')}.json"] || + raise(ArgumentError, "Schema file not found for policy `#{@slug}`") + end + end + end + end +end diff --git a/app/_plugins/drops/plugins/schema.rb b/app/_plugins/drops/plugins/schema.rb index a437be4f5a8..f1f8df15369 100644 --- a/app/_plugins/drops/plugins/schema.rb +++ b/app/_plugins/drops/plugins/schema.rb @@ -1,14 +1,18 @@ # frozen_string_literal: true require 'json' -require 'pathname' -require_relative '../../lib/site_accessor' module Jekyll module Drops module Plugins class Schema < Liquid::Drop # rubocop:disable Style/Documentation - include Jekyll::SiteAccessor + SCHEMAS_BASE = File.expand_path('../../../_schemas/gateway/plugins', __dir__).freeze + + FILE_INDEX = Hash.new do |h, dir| + h[dir] = Dir.glob(File.join(dir, '*.json')) + .to_h { |f| [File.basename(f).downcase, f] } + .freeze + end def self.all(plugin:) plugin.releases.map do |release| @@ -46,25 +50,14 @@ def schema end def file_path - @file_path ||= if @plugin.third_party? - third_party_file_path - else - kong_schema_file_path - end + @file_path ||= @plugin.third_party? ? third_party_file_path : kong_schema_file_path end def kong_schema_file_path @kong_schema_file_path ||= begin - path = File.join( - site.config['plugin_schemas_path'], - release.number, - "#{plugin_slug.split('-').map(&:capitalize).join}.json" - ) - dir = File.dirname(path) - filename = File.basename(path) - Dir.glob("#{dir}/*", File::FNM_CASEFOLD).find do |file| - File.basename(file).downcase == filename.downcase - end + dir = File.join(SCHEMAS_BASE, release.number) + FILE_INDEX[dir]["#{plugin_slug.delete('-')}.json"] || + raise(ArgumentError, "Schema file not found for plugin `#{plugin_slug}` release `#{release.number}`") end end diff --git a/app/_plugins/generators/ai_gateway_policy/generator.rb b/app/_plugins/generators/ai_gateway_policy/generator.rb new file mode 100644 index 00000000000..45911beddee --- /dev/null +++ b/app/_plugins/generators/ai_gateway_policy/generator.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require_relative '../policies/generator' +require_relative '../policies/generator_base' + +module Jekyll + module AIGatewayPolicyPages + class Generator # rubocop:disable Style/Documentation + include Policies::Generator + include Policies::GeneratorBase + + def self.policies_folder + '_ai_gateway_policies' + end + + def key + @key ||= 'ai_gateway_policies' + end + + def skip? + site.config.dig('skip', 'ai_gateway_policy') + end + + # TODO: for now, until we have overviews and examples + def generate_pages(policy) + reference = generate_reference_page(policy) + + site.data[key][policy.slug] = reference + end + end + end +end diff --git a/app/_plugins/generators/ai_gateway_policy/pages/base.rb b/app/_plugins/generators/ai_gateway_policy/pages/base.rb new file mode 100644 index 00000000000..e19facb1985 --- /dev/null +++ b/app/_plugins/generators/ai_gateway_policy/pages/base.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative '../../policies/pages/base' + +module Jekyll + module AIGatewayPolicyPages + module Pages + class Base # rubocop:disable Style/Documentation + include Policies::Pages::Base + + def self.base_url + '/ai-gateway/policies/' + end + + def breadcrumbs + @breadcrumbs ||= ['/ai-gateway/', '/ai-gateway/policies/'] + end + + def data + super + .merge( + 'schema' => @policy.schema, + 'has_overview?' => false, + 'title' => "#{@policy.metadata['title']} Policy" + ) + end + + def icon + return unless @policy.icon + + "/assets/icons/plugins/#{@policy.icon}" + end + end + end + end +end diff --git a/app/_plugins/generators/ai_gateway_policy/pages/overview.rb b/app/_plugins/generators/ai_gateway_policy/pages/overview.rb new file mode 100644 index 00000000000..0c4c10348e4 --- /dev/null +++ b/app/_plugins/generators/ai_gateway_policy/pages/overview.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require_relative '../../policies/pages/overview' + +module Jekyll + module AIGatewayPolicyPages + module Pages + class Overview < Base + include Policies::Pages::Overview + end + end + end +end diff --git a/app/_plugins/generators/ai_gateway_policy/pages/reference.rb b/app/_plugins/generators/ai_gateway_policy/pages/reference.rb new file mode 100644 index 00000000000..c7c9609bea8 --- /dev/null +++ b/app/_plugins/generators/ai_gateway_policy/pages/reference.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative '../../policies/pages/reference' + +module Jekyll + module AIGatewayPolicyPages + module Pages + class Reference < Base + include Policies::Pages::Reference + + MARKDOWN_CONTENT = File.read('app/_includes/plugins/reference.md') + + def layout + 'ai_gateway_policies/reference' + end + + def markdown_content + MARKDOWN_CONTENT + end + + def data + super.merge('reference_type' => 'base', 'versioned' => false) + end + end + end + end +end diff --git a/app/_plugins/generators/ai_gateway_policy/policy.rb b/app/_plugins/generators/ai_gateway_policy/policy.rb new file mode 100644 index 00000000000..1cc5442da46 --- /dev/null +++ b/app/_plugins/generators/ai_gateway_policy/policy.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require_relative '../policies/base' +require_relative '../../drops/plugins/aigw_policy_schema' + +module Jekyll + module AIGatewayPolicyPages + class Policy # rubocop:disable Style/Documentation + include Policies::Base + include Policies::GeneratorBase + + def schema + @schema ||= Jekyll::Drops::Plugins::AIGWPolicySchema.new(slug: @slug) + end + + def examples + @examples ||= [] + end + + def metadata + @metadata ||= api_plugin + .data['plugin'] + .metadata.slice(*policies_metadata.fetch('keep')) + .merge('schema' => schema, 'scopes' => scopes) + .merge(super) + end + + private + + def api_plugin + @api_plugin ||= site.data['kong_plugins'].fetch(@slug) + end + + def policies_metadata + @policies_metadata ||= site.config.dig('ai_gateway_policies', 'metadata') + end + + def scopes + @scopes ||= site.data.dig('policies', 'ai-gateway', 'scopes') + &.find { |entry| entry['name'] == @slug } + &.fetch('scopes', []) + &.map { |s| normalize_scope(s) } || [] + end + + def normalize_scope(scope) + return scope if scope == 'global' + + "ai-#{scope.chomp('s')}" + end + end + end +end diff --git a/app/_plugins/generators/broken_links.rb b/app/_plugins/generators/broken_links.rb index a887a7bfc9e..66e86544218 100644 --- a/app/_plugins/generators/broken_links.rb +++ b/app/_plugins/generators/broken_links.rb @@ -6,6 +6,16 @@ module Jekyll class BrokenLinks < Generator priority :lowest + class Page < Jekyll::Page + def initialize(site, sources) + @site = site + @data = {} + @content = JSON.pretty_generate(sources) + + process('sources_urls_mapping.json') + end + end + def generate(site) return if ENV['JEKYLL_ENV'] == 'production' @@ -21,7 +31,7 @@ def generate(site) sources[file_path(doc)] << doc.url end - site.pages << build_page(site, sources) + site.pages << Page.new(site, sources) end def file_path(page) @@ -29,12 +39,5 @@ def file_path(page) "app/#{page.relative_path}" end - - def build_page(site, sources) - PageWithoutAFile.new(site, site.source, '', 'sources_urls_mapping.json').tap do |page| - page.data['layout'] = nil - page.content = JSON.pretty_generate(sources) - end - end end end diff --git a/app/_plugins/generators/data/llm_metadata.rb b/app/_plugins/generators/data/llm_metadata.rb index 2087c1dc7b8..2e15d4ed346 100644 --- a/app/_plugins/generators/data/llm_metadata.rb +++ b/app/_plugins/generators/data/llm_metadata.rb @@ -48,6 +48,7 @@ def frontmatter data['tags'] = @page.data['tags'] if @page.data.fetch('tags', []).any? data['canonical'] = @page.data['canonical?'] unless @page.data['canonical?'].nil? data['works_on'] = @page.data['works_on'] if @page.data.fetch('works_on', []).any? + data['scopes'] = @page.data['scopes'] if @page.data.fetch('scopes', []).any? data.merge!(plugin_metadata) if plugin_metadata.any? data.merge!(skill_metadata) if skill_metadata.any? diff --git a/app/_plugins/generators/data/title/base.rb b/app/_plugins/generators/data/title/base.rb index 7c7a8dd93e9..07d05fced5e 100644 --- a/app/_plugins/generators/data/title/base.rb +++ b/app/_plugins/generators/data/title/base.rb @@ -9,7 +9,7 @@ def self.make_for(page:, site:) # rubocop:disable Metrics/AbcSize,Metrics/Cyclom APIPage.new(page:, site:) elsif page.url.start_with?('/plugins/') Plugin.new(page:, site:) - elsif page.url.start_with?('/mesh/policies/') || page.url.start_with?('/event-gateway/policies/') + elsif page.url.start_with?('/mesh/policies/') || page.url.start_with?('/event-gateway/policies/') || page.url.start_with?('/ai-gateway/policies/') Policy.new(page:, site:) elsif page.data['content_type'] && page.data['content_type'] == 'reference' Reference.new(page:, site:) diff --git a/app/_plugins/generators/plugins_ai_gateway_policies.rb b/app/_plugins/generators/plugins_ai_gateway_policies.rb new file mode 100644 index 00000000000..38d8d445093 --- /dev/null +++ b/app/_plugins/generators/plugins_ai_gateway_policies.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Jekyll + class AIGatewayPoliciesGenerator < Jekyll::Generator # rubocop:disable Style/Documentation + # This generator depends on the Kong Plugins pages, + # so we need to run after the KongPluginsGenerator first to ensure the data is available. + # Hence the file name is prefixed with "plugins_" to ensure it runs after the KongPluginsGenerator. + priority :high + + def generate(site) + site.data['ai_gateway_policies'] ||= {} + Jekyll::AIGatewayPolicyPages::Generator.run(site) + end + end +end diff --git a/app/_plugins/generators/policies/generator.rb b/app/_plugins/generators/policies/generator.rb index f52c713e299..5e0fed625cc 100644 --- a/app/_plugins/generators/policies/generator.rb +++ b/app/_plugins/generators/policies/generator.rb @@ -19,7 +19,7 @@ def initialize(site) @site = site end - def run # rubocop:disable Metrics/AbcSize + def run Dir.glob(File.join(site.source, "#{self.class.policies_folder}/*/")).each do |folder| slug = folder.gsub("#{site.source}/#{self.class.policies_folder}/", '').chomp('/') @@ -51,6 +51,7 @@ def generate_reference_page(policy) .to_jekyll_page site.pages << reference + reference end def generate_example_pages(policy) diff --git a/app/_plugins/generators/policies/pages/base.rb b/app/_plugins/generators/policies/pages/base.rb index a672d08d737..5a427c319a3 100644 --- a/app/_plugins/generators/policies/pages/base.rb +++ b/app/_plugins/generators/policies/pages/base.rb @@ -33,6 +33,7 @@ def data # rubocop:disable Metrics/MethodLength 'overview_url' => @policy.overview_page_class.url(@policy), 'get_started_url' => @policy.examples.first&.url, 'reference_url' => @policy.reference_page_class.url(@policy), + 'has_overview?' => true, 'plugin' => @policy, 'plugin?' => true, 'release' => @policy.latest_release_in_range, diff --git a/app/_plugins/hooks/site_post_write.rb b/app/_plugins/hooks/site_post_write.rb index fac72193de9..b2519b4c9f0 100644 --- a/app/_plugins/hooks/site_post_write.rb +++ b/app/_plugins/hooks/site_post_write.rb @@ -83,6 +83,7 @@ def payload @site.site_payload.merge( 'api_pages' => api_pages, 'plugin_pages' => plugin_pages, + 'ai_gateway_policy_pages' => ai_gateway_policy_pages, 'how_to_pages' => how_to_pages, 'cookbook_pages' => cookbook_pages, 'docs' => docs @@ -98,16 +99,14 @@ def info end def doc_pages - @doc_pages ||= pages - api_pages - plugin_pages - how_to_pages - cookbook_pages + @doc_pages ||= pages - api_pages - plugin_pages - how_to_pages - cookbook_pages - ai_gateway_policy_pages end def docs @docs ||= begin grouped = doc_pages.group_by do |p| products = Array(p.data['products']) - if products.include?('ai-gateway') - 'ai-gateway' - elsif products.any? + if products.any? products.first else Array(p.data['tools']).first @@ -132,6 +131,10 @@ def plugin_pages @plugin_pages ||= pages.select { |p| p.data['plugin?'] && p.data['products'].include?('gateway') } end + def ai_gateway_policy_pages + @ai_gateway_policy_pages ||= pages.select { |p| p.data['plugin?'] && p.data['products'] == ['ai-gateway'] } + end + def api_pages @api_pages ||= pages.select { |p| p.data['content_type'] == 'api' || p.data['layout'] == 'api/errors' } end diff --git a/app/_plugins/lib/link_icon_assigner.rb b/app/_plugins/lib/link_icon_assigner.rb index 5a77b1c78f8..182533466a1 100644 --- a/app/_plugins/lib/link_icon_assigner.rb +++ b/app/_plugins/lib/link_icon_assigner.rb @@ -36,7 +36,7 @@ def process private def determine_icon - icon_for_type || icon_for_url || icon_for_content_type + icon_for_type || icon_for_url || icon_for_aigw_policy || icon_for_content_type end def icon_for_type @@ -49,6 +49,12 @@ def icon_for_url URL_ICON_MAP.find { |pattern, _| @resource['url'] =~ pattern }&.last || 'service-document' end + def icon_for_aigw_policy + # XXX: This is a temporary hack to assign the correct icon for the policies section of the AI Gateway product. + # This should be removed once the policies have their own overview page. + 'plug' if @resource['url'].start_with?('/ai-gateway/policies/') + end + def icon_for_content_type return 'service-document' if Jekyll.env == 'development' && (ENV['KONG_PRODUCTS'] || ENV['PAGE_PATHS']) diff --git a/app/_plugins/tags/aigw_policy.rb b/app/_plugins/tags/aigw_policy.rb new file mode 100644 index 00000000000..d2abaa295b0 --- /dev/null +++ b/app/_plugins/tags/aigw_policy.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require_relative '../monkey_patch' + +module Jekyll + class RenderAIGatewayPolicy < Liquid::Tag + def initialize(tag_name, param, tokens) + super + + @param = param.strip + end + + def render(context) + @context = context + @site = context.registers[:site] + @page = @context.environments.first['page'] + @config = @param.split('.').reduce(context) { |c, key| c[key] } || @param + @slug = @config.is_a?(Hash) ? @config['slug'] : @config + + policy = @site.data['ai_gateway_policies'][@slug] + + unless policy + raise ArgumentError, + "Error rendering {% aigw_policy %} on page: #{@page['path']}. The policy `#{@slug}` doesn't exist." + end + + return '' if policy.data['published'] == false + + context.stack do + context['policy'] = policy + Liquid::Template.parse(template, { line_numbers: true }).render(context) + end + end + + private + + def template + if @page['output_format'] == 'markdown' + File.read(File.expand_path('app/_includes/components/aigw_policy.md')) + else + File.read(File.expand_path('app/_includes/components/aigw_policy.html')) + end + end + end +end + +Liquid::Template.register_tag('aigw_policy', Jekyll::RenderAIGatewayPolicy) diff --git a/app/_redirects b/app/_redirects index b12873fb480..67ac6c8911b 100644 --- a/app/_redirects +++ b/app/_redirects @@ -374,6 +374,9 @@ # MCP landing page /mcp/ /ai-gateway/mcp/ +# AIGW policies overview -> reference for now +/ai-gateway/policies/:slug/ /ai-gateway/policies/:slug/reference 301 + # ai-gateway previous-major wildcard — added by migration skill on 2026-06-15 /ai-gateway/* /ai-gateway/v1/:splat 301 # ai-gateway previous-major how-to redirects — added by migration skill on 2026-06-15 diff --git a/app/_schemas/ai-gateway/policies/ACL.json b/app/_schemas/ai-gateway/policies/ACL.json new file mode 100644 index 00000000000..ceabfc3ec20 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ACL.json @@ -0,0 +1,79 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "hide_groups_header": { + "type": "boolean", + "description": "If enabled (`true`), prevents the `X-Consumer-Groups` header from being sent in the request to the upstream service.", + "default": false + }, + "include_consumer_groups": { + "type": "boolean", + "description": "If enabled (`true`), allows the consumer-groups to be used in the `allow|deny` fields", + "default": false + }, + "always_use_authenticated_groups": { + "type": "boolean", + "description": "If enabled (`true`), the authenticated groups will always be used even when an authenticated consumer already exists. If the authenticated groups don't exist, it will fallback to use the groups associated with the consumer. By default the authenticated groups will only be used when there is no consumer or the consumer is anonymous.", + "default": false + }, + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Arbitrary group names that are allowed to consume the service or route. One of `config.allow` or `config.deny` must be specified." + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Arbitrary group names that are not allowed to consume the service or route. One of `config.allow` or `config.deny` must be specified." + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Ace.json b/app/_schemas/ai-gateway/policies/Ace.json new file mode 100644 index 00000000000..26b568c60c7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Ace.json @@ -0,0 +1,321 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an `anonymous` consumer if authentication fails. If empty (default null), the request will fail with an authentication failure `4xx`. When set, the plugin will skip ACE processing for requests that are already authenticated by other plugins with higher priority." + }, + "match_policy": { + "type": "string", + "enum": [ + "if_present", + "required" + ], + "description": "Determines how the ACE plugin will behave when a request doesn't match an existing operation from an API or API package in Dev Portal. The `required` setting requires every incoming request to match a defined operation. If a request doesn't match, ACE rejects the request outright with a 404. The `if_present` setting makes the ACE plugin only engage with a request when it matches an operation, allowing a request to still be processed by other plugins with a lower priority than ACE.", + "default": "if_present" + }, + "rate_limiting": { + "type": "object", + "properties": { + "sync_rate": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "How often to sync counter data to the central data store. A value of 0 results in synchronous behavior (counter synchronization happens in each request's context and contributes directly to the latency of the request). A value greater than 0 results in asynchronous behavior and specifies the interval (in seconds) for synchronizing counters. The minimum allowed interval is 0.02 seconds (20ms). If omitted, the plugin ignores sync behavior entirely and only stores counters in node memory." + }, + "redis": { + "type": "object", + "properties": { + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + } + } + } + } + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.rate_limiting.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Acme.json b/app/_schemas/ai-gateway/policies/Acme.json new file mode 100644 index 00000000000..d6faa1faf1d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Acme.json @@ -0,0 +1,419 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "eab_hmac_key": { + "type": "string", + "description": "External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don't need to set this unless it is explicitly required by the CA.", + "x-referenceable": true, + "x-encrypted": true + }, + "renew_threshold_days": { + "type": "number", + "description": "Days remaining to renew the certificate before it expires.", + "default": 14 + }, + "storage": { + "type": "string", + "enum": [ + "consul", + "kong", + "redis", + "shm", + "vault" + ], + "description": "The backend storage type to use. In DB-less mode and Konnect, `kong` storage is unavailable. In hybrid mode and Konnect, `shm` storage is unavailable. `shm` storage does not persist during Kong restarts and does not work for Kong running on different machines, so consider using one of `kong`, `redis`, `consul`, or `vault` in production.", + "default": "shm" + }, + "allow_any_domain": { + "type": "boolean", + "description": "If set to `true`, the plugin allows all domains and ignores any values in the `domains` list.", + "default": false + }, + "fail_backoff_minutes": { + "type": "number", + "description": "Minutes to wait for each domain that fails to create a certificate. This applies to both a\nnew certificate and a renewal certificate.", + "default": 5 + }, + "preferred_chain": { + "type": "string", + "description": "A string value that specifies the preferred certificate chain to use when generating certificates." + }, + "enable_ipv4_common_name": { + "type": "boolean", + "description": "A boolean value that controls whether to include the IPv4 address in the common name field of generated certificates.", + "default": true + }, + "api_uri": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "default": "https://acme-v02.api.letsencrypt.org/directory" + }, + "eab_kid": { + "type": "string", + "description": "External account binding (EAB) key id. You usually don't need to set this unless it is explicitly required by the CA.", + "x-referenceable": true, + "x-encrypted": true + }, + "rsa_key_size": { + "type": "integer", + "enum": [ + 2048, + 3072, + 4096 + ], + "description": "RSA private key size for the certificate. The possible values are 2048, 3072, or 4096.", + "default": 4096 + }, + "domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of strings representing hosts. A valid host is a string containing one or more labels separated by periods, with at most one wildcard label ('*')" + }, + "storage_config": { + "type": "object", + "properties": { + "redis": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "extra_options": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "A namespace to prepend to all keys stored in Redis.", + "default": "" + }, + "scan_count": { + "type": "number", + "description": "The number of keys to return in Redis SCAN calls.", + "default": 10 + } + }, + "description": "Custom ACME Redis options" + } + } + }, + "consul": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "kv_path": { + "type": "string", + "description": "KV prefix path." + }, + "timeout": { + "type": "number", + "description": "Timeout in milliseconds." + }, + "token": { + "type": "string", + "description": "Consul ACL token.", + "x-referenceable": true, + "x-encrypted": true + }, + "https": { + "type": "boolean", + "description": "Boolean representation of https.", + "default": false + } + } + }, + "vault": { + "type": "object", + "properties": { + "tls_verify": { + "type": "boolean", + "description": "Turn on TLS verification.", + "default": true + }, + "tls_server_name": { + "type": "string", + "description": "SNI used in request, default to host if omitted." + }, + "jwt_path": { + "type": "string", + "description": "The path to the JWT." + }, + "https": { + "type": "boolean", + "description": "Boolean representation of https.", + "default": false + }, + "timeout": { + "type": "number", + "description": "Timeout in milliseconds." + }, + "token": { + "type": "string", + "description": "Consul ACL token.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_method": { + "type": "string", + "enum": [ + "kubernetes", + "token" + ], + "description": "Auth Method, default to token, can be 'token' or 'kubernetes'.", + "default": "token" + }, + "auth_path": { + "type": "string", + "description": "Vault's authentication path to use." + }, + "auth_role": { + "type": "string", + "description": "The role to try and assign." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "kv_path": { + "type": "string", + "description": "KV prefix path." + } + } + }, + "shm": { + "type": "object", + "properties": { + "shm_name": { + "type": "string", + "description": "Name of shared memory zone used for Kong API gateway storage", + "default": "kong" + } + } + }, + "kong": { + "type": "object", + "additionalProperties": true + } + } + }, + "account_email": { + "type": "string", + "description": "The account identifier. Can be reused in a different plugin instance.", + "x-encrypted": true, + "x-referenceable": true + }, + "cert_type": { + "type": "string", + "enum": [ + "ecc", + "rsa" + ], + "description": "The certificate type to create. The possible values are `rsa` for RSA certificate or `ecc` for EC certificate.", + "default": "rsa" + }, + "account_key": { + "type": "object", + "properties": { + "key_id": { + "type": "string", + "description": "The Key ID.", + "x-encrypted": true + }, + "key_set": { + "type": "string", + "description": "The name of the key set to associate the Key ID with.", + "x-encrypted": true + } + }, + "required": [ + "key_id" + ], + "description": "The private key associated with the account." + }, + "tos_accepted": { + "type": "boolean", + "description": "If you are using Let's Encrypt, you must set this to `true` to agree the terms of service.", + "default": false + } + }, + "required": [ + "account_email" + ] + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ce", + "paths": [ + "config.storage_config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiA2aProxy.json b/app/_schemas/ai-gateway/policies/AiA2aProxy.json new file mode 100644 index 00000000000..c0691c74789 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiA2aProxy.json @@ -0,0 +1,73 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "logging": { + "type": "object", + "properties": { + "log_statistics": { + "type": "boolean", + "description": "If enabled, adds A2A metrics to Kong log plugin(s) output.", + "default": false + }, + "log_payloads": { + "type": "boolean", + "description": "If enabled, logs request/response bodies to Kong log plugin(s) output. Requires log_statistics to be enabled.", + "default": false + }, + "max_payload_size": { + "type": "integer", + "description": "Maximum size in bytes for logged request/response payloads. Payloads exceeding this size will be truncated.", + "default": 1048576 + } + } + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiAwsGuardrails.json b/app/_schemas/ai-gateway/policies/AiAwsGuardrails.json new file mode 100644 index 00000000000..d992504fbcb --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiAwsGuardrails.json @@ -0,0 +1,209 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the SSL certificate of the guardrail service endpoint.", + "default": true + }, + "log_blocked_content": { + "type": "boolean", + "description": "Whether to log prompts and responses that are blocked by the guardrail.", + "default": false + }, + "guardrails_id": { + "type": "string", + "description": "The guardrail identifier used in the request to apply the guardrail." + }, + "aws_role_session_name": { + "type": "string", + "description": "The identifier of the assumed role session" + }, + "proxy_config": { + "type": "object", + "properties": { + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "timeout": { + "type": "number", + "description": "Connection timeout with the guardrail service.", + "default": 10000 + }, + "guarding_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The guardrail mode to use for the request.", + "default": "INPUT" + }, + "allow_masking": { + "type": "boolean", + "description": "Allow masking the request/response instead of blocking it. Streaming will be disabled if this is enabled.", + "default": false + }, + "text_source": { + "type": "string", + "enum": [ + "concatenate_all_content", + "concatenate_user_content" + ], + "description": "Select where to pick the 'text' for the guardrail service request.", + "default": "concatenate_all_content" + }, + "response_buffer_size": { + "type": "number", + "description": "The amount of bytes receiving from upstream to be buffered before sending to the guardrail service. This only applies to the response content guard.", + "default": 100 + }, + "aws_access_key_id": { + "type": "string", + "description": "The AWS access key ID to use for authentication", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "The AWS secret access key to use for authentication", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The target AWS IAM role ARN used to access the guardrails service" + }, + "guardrails_version": { + "type": "string", + "description": "The guardrail version used in the request to apply the guardrail. Note that the value of this field must match the pattern `(([1-9][0-9]{0,7})|(DRAFT))` according to the AWS documentation https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ApplyGuardrail.html#API_runtime_ApplyGuardrail_RequestSyntax." + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + }, + "aws_region": { + "type": "string", + "description": "The AWS region to use for the Bedrock API" + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "Override the STS endpoint URL when assuming a different role" + } + }, + "required": [ + "aws_region", + "guardrails_id", + "guardrails_version" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiAzureContentSafety.json b/app/_schemas/ai-gateway/policies/AiAzureContentSafety.json new file mode 100644 index 00000000000..365fd2e60c6 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiAzureContentSafety.json @@ -0,0 +1,221 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the SSL certificate of the guardrail service endpoint.", + "default": true + }, + "log_blocked_content": { + "type": "boolean", + "description": "Whether to log prompts and responses that are blocked by the guardrail.", + "default": false + }, + "content_safety_url": { + "type": "string", + "description": "Full URL, inc protocol, of the Azure Content Safety instance.", + "x-referenceable": true + }, + "content_safety_key": { + "type": "string", + "description": "If `azure_use_managed_identity` is true, set the API key to call Content Safety.", + "x-encrypted": true, + "x-referenceable": true + }, + "guarding_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The guardrail mode to use for the request.", + "default": "INPUT" + }, + "azure_api_version": { + "type": "string", + "minLength": 1, + "description": "Sets the ?api-version URL parameter, used for defining the Azure Content Services interchange format.", + "default": "2023-10-01" + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "If checked, uses (if set) `azure_client_id`, `azure_client_secret`, and/or `azure_tenant_id` for Azure authentication, via Managed or User-assigned identity", + "default": false + }, + "azure_tenant_id": { + "type": "string", + "description": "If `azure_use_managed_identity` is true, set the tenant ID if required." + }, + "categories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "rejection_level": { + "type": "integer" + } + }, + "required": [ + "name", + "rejection_level" + ] + }, + "description": "Array of categories, and their thresholds, to measure on." + }, + "blocklist_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Use these configured blocklists (in Azure Content Services) when inspecting content." + }, + "halt_on_blocklist_hit": { + "type": "boolean", + "description": "Tells Azure to reject the request if any blocklist filter is hit.", + "default": true + }, + "response_buffer_size": { + "type": "number", + "description": "The amount of bytes receiving from upstream to be buffered before sending to the guardrail service. This only applies to the response content guard.", + "default": 100 + }, + "azure_client_id": { + "type": "string", + "description": "If `azure_use_managed_identity` is true, set the client ID if required." + }, + "azure_client_secret": { + "type": "string", + "description": "If `azure_use_managed_identity` is true, set the client secret if required.", + "x-encrypted": true + }, + "reveal_failure_reason": { + "type": "boolean", + "description": "Set true to tell the caller why their request was rejected, if so.", + "default": true + }, + "output_type": { + "type": "string", + "enum": [ + "EightSeverityLevels", + "FourSeverityLevels" + ], + "description": "See https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/content-filter#content-filtering-categories", + "default": "FourSeverityLevels" + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + }, + "text_source": { + "type": "string", + "enum": [ + "concatenate_all_content", + "concatenate_user_content" + ], + "description": "Select where to pick the 'text' for the guardrail service request.", + "default": "concatenate_all_content" + }, + "proxy_config": { + "type": "object", + "properties": { + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + } + } + } + }, + "required": [ + "content_safety_url" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiCustomGuardrail.json b/app/_schemas/ai-gateway/policies/AiCustomGuardrail.json new file mode 100644 index 00000000000..4c1bdb3b754 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiCustomGuardrail.json @@ -0,0 +1,291 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "timeout": { + "type": "number", + "description": "Connection timeout with the guardrail service.", + "default": 10000 + }, + "response": { + "type": "object", + "properties": { + "block": { + "type": "string", + "description": "template or string to evaluate block field" + }, + "block_message": { + "type": "string", + "description": "template or string to evaluate block_message field" + } + }, + "required": [ + "block", + "block_message" + ], + "description": "Configuration specific to parse guardrail response." + }, + "metrics": { + "type": "object", + "properties": { + "block_reason": { + "type": "string", + "description": "Metric to indicate the reason for blocking the input." + }, + "block_detail": { + "type": "string", + "description": "Metric to indicate the detail for blocking the input." + }, + "masked": { + "type": "string", + "description": "Metric to indicate whether the input was masked." + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true, + "x-lua-required": true + }, + "description": "Parameters to be used in the guardrail service request. Keys are the parameter name and values can be either Lua expressions in the form `$(some_lua_expression)`or string. For expression, it will be evaluated as the value for the corresponding key. For string, it will be attempted to be parsed as string in JSON format, otherwise it will be used as is." + }, + "request": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "the url string or a template to generate one" + }, + "body": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "A map used to evaluate a JSON object. Keys are the field names in the new object, and values can be either Lua expressions in the form `$(some_lua_expression)`or string. For expression, it will be evaluated as the value for the corresponding key. For string, it will be decoded as string in JSON format or be used as is." + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "A map used to evaluate a JSON object. Keys are the field names in the new object, and values can be either Lua expressions in the form `$(some_lua_expression)`or string. For expression, it will be evaluated as the value for the corresponding key. For string, it will be decoded as string in JSON format or be used as is." + }, + "queries": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "A map used to evaluate a JSON object. Keys are the field names in the new object, and values can be either Lua expressions in the form `$(some_lua_expression)`or string. For expression, it will be evaluated as the value for the corresponding key. For string, it will be decoded as string in JSON format or be used as is." + }, + "auth": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Specify name here.", + "x-referenceable": true + }, + "value": { + "type": "string", + "description": "Specify the full token value for 'name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "location": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body.", + "default": "header" + } + }, + "description": "Authentication configuration for HTTP request." + } + }, + "required": [ + "url" + ], + "description": "Configuration specific to guardrail request. Fields below support template evaluation. Warning: if template is used, please verify that the client is from a trusted source to prevent injection." + }, + "functions": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-lua-required": true + }, + "description": "Custom functions to be used in expression templates." + }, + "custom_metrics": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "A list of custom metrics to be recorded." + }, + "proxy_config": { + "type": "object", + "properties": { + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the SSL certificate of the guardrail service endpoint.", + "default": true + }, + "guarding_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The guardrail mode to use for the request.", + "default": "INPUT" + }, + "allow_masking": { + "type": "boolean", + "description": "Allow masking the request/response instead of blocking it. Streaming will be disabled if this is enabled.", + "default": false + }, + "response_buffer_size": { + "type": "number", + "description": "The amount of bytes receiving from upstream to be buffered before sending to the guardrail service. This only applies to the response content guard.", + "default": 100 + }, + "text_source": { + "type": "string", + "enum": [ + "concatenate_all_content", + "concatenate_user_content", + "last_message" + ], + "description": "Select where to pick the 'text' for the guardrail service request.", + "default": "last_message" + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + } + }, + "required": [ + "request", + "response" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiGcpModelArmor.json b/app/_schemas/ai-gateway/policies/AiGcpModelArmor.json new file mode 100644 index 00000000000..5be323d9ea4 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiGcpModelArmor.json @@ -0,0 +1,221 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "project_id": { + "type": "string", + "description": "GCP Project ID for the GCP Model Armor subscription." + }, + "location_id": { + "type": "string", + "description": "GCP Location ID for the GCP Model Armor subscription." + }, + "enable_multi_language_detection": { + "type": "boolean", + "description": "Enables multi-language detection mode. Must be used with 'source_language'.", + "default": false + }, + "timeout": { + "type": "number", + "description": "Connection timeout with the guardrail service.", + "default": 10000 + }, + "text_source": { + "type": "string", + "enum": [ + "concatenate_all_content", + "concatenate_user_content", + "last_message" + ], + "description": "Select where to pick the 'text' for the guardrail service request.", + "default": "last_message" + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT` or from the instance/container metadata service.", + "x-referenceable": true, + "x-encrypted": true + }, + "proxy_config": { + "type": "object", + "properties": { + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + } + } + }, + "log_blocked_content": { + "type": "boolean", + "description": "Whether to log prompts and responses that are blocked by the guardrail.", + "default": false + }, + "request_failure_message": { + "type": "string", + "description": "The message to return when a failure occurs on the request phase.", + "default": "Request was filtered by GCP Model Armor" + }, + "response_failure_message": { + "type": "string", + "description": "The message to return when a failure occurs on the response phase.", + "default": "Response was filtered by GCP Model Armor" + }, + "response_buffer_size": { + "type": "number", + "description": "The amount of bytes receiving from upstream to be buffered before sending to the guardrail service. This only applies to the response content guard.", + "default": 100 + }, + "template_id": { + "type": "string", + "description": "GCP Model Armor Template ID to enforce." + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "source_language": { + "type": "string", + "description": "Source language (ISO code) to use when 'enable_multi_language_detection' is enabled." + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + }, + "guarding_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The guardrail mode to use for the request.", + "default": "INPUT" + }, + "reveal_failure_categories": { + "type": "boolean", + "description": "Whether to reveal failure categories in the response to the caller.", + "default": false + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + } + }, + "required": [ + "location_id", + "project_id", + "template_id" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiLakeraGuard.json b/app/_schemas/ai-gateway/policies/AiLakeraGuard.json new file mode 100644 index 00000000000..8a74ac9bb4b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiLakeraGuard.json @@ -0,0 +1,193 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "lakera_service_url": { + "type": "string", + "description": "The guard-operation URL of the Lakera Guard service. Defaults to the SaaS /v2/guard endpoint. It can be set to a locally hosted instance of Lakera Guard.", + "default": "https://api.lakera.ai/v2/guard", + "x-referenceable": true + }, + "api_key": { + "type": "string", + "description": "API key for the Lakera Guard subscription.", + "x-referenceable": true, + "x-encrypted": true + }, + "project_id": { + "type": "string", + "description": "Project ID to apply filters from. If null, it will use the subscription's default project.", + "x-referenceable": true + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + }, + "response_failure_message": { + "type": "string", + "description": "The message to return when a failure occurs on the response phase.", + "default": "Response was filtered by Lakera Guard" + }, + "response_buffer_size": { + "type": "number", + "description": "The amount of bytes receiving from upstream to be buffered before sending to the guardrail service. This only applies to the response content guard.", + "default": 100 + }, + "verify_ssl": { + "type": "boolean", + "description": "Whether to verify the SSL certificate of the guardrail service endpoint.", + "default": true + }, + "timeout": { + "type": "number", + "description": "Connection timeout with the guardrail service.", + "default": 10000 + }, + "guarding_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The guardrail mode to use for the request.", + "default": "INPUT" + }, + "reveal_failure_categories": { + "type": "boolean", + "description": "Whether to reveal failure categories in the response to the caller.", + "default": false + }, + "request_failure_message": { + "type": "string", + "description": "The message to return when a failure occurs on the request phase.", + "default": "Request was filtered by Lakera Guard" + }, + "text_source": { + "type": "string", + "enum": [ + "concatenate_all_content", + "concatenate_user_content", + "last_message" + ], + "description": "Select where to pick the 'text' for the Lakera Guard request (when text/generation is selected).", + "default": "concatenate_all_content" + }, + "proxy_config": { + "type": "object", + "properties": { + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + } + } + }, + "log_blocked_content": { + "type": "boolean", + "description": "Whether to log prompts and responses that are blocked by the guardrail.", + "default": false + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiLlmAsJudge.json b/app/_schemas/ai-gateway/policies/AiLlmAsJudge.json new file mode 100644 index 00000000000..c8137c1d267 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiLlmAsJudge.json @@ -0,0 +1,593 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "prompt": { + "type": "string", + "description": "Use this prompt to tune the LLM system/assistant message for the llm as a judge prompt.", + "default": "You are a strict evaluator. You will be given a prompt and a response. Your task is to judge whether the response is correct or incorrect. You must assign a score between 1 and 100, where: 100 represents a completely correct and ideal response, 1 represents a completely incorrect or irrelevant response. Your score must be a single number only — no text, labels, or explanations. Use the full range of values (e.g., 13, 47, 86), not just round numbers like 10, 50, or 100. Be accurate and consistent, as this score will be used by another model for learning and evaluation." + }, + "ignore_system_prompts": { + "type": "boolean", + "description": "Ignore and discard any system prompts when evaluating the request", + "default": true + }, + "ignore_assistant_prompts": { + "type": "boolean", + "description": "Ignore and discard any assistant prompts when evaluating the request", + "default": true + }, + "http_timeout": { + "type": "integer", + "description": "Timeout in milliseconds for the AI upstream service.", + "default": 60000 + }, + "https_verify": { + "type": "boolean", + "description": "Verify the TLS certificate of the AI upstream service.", + "default": true + }, + "sampling_rate": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Judging request sampling rate for configuring the probability-based sampler.", + "default": 1 + }, + "inject_score_header": { + "type": "boolean", + "description": "Expose the computed judge score in a response header.", + "default": false + }, + "message_countback": { + "type": "number", + "maximum": 1000, + "minimum": 1, + "description": "Number of messages in the chat history to use for evaluating the request", + "default": 1 + }, + "ignore_tool_prompts": { + "type": "boolean", + "description": "Ignore and discard any tool prompts when evaluating the request", + "default": true + }, + "proxy_config": { + "type": "object", + "properties": { + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + } + } + }, + "score_header_name": { + "type": "string", + "description": "Name of the response header used to expose the judge score.", + "default": "X-Kong-LLM-Accuracy-Score" + }, + "llm": { + "type": "object", + "properties": { + "model": { + "type": "object", + "properties": { + "model_alias": { + "type": "string", + "description": "The model name parameter from the request that this model should map to." + }, + "options": { + "type": "object", + "properties": { + "azure_instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "llama2_format": { + "type": "string", + "enum": [ + "ollama", + "openai", + "raw" + ], + "description": "If using llama2 provider, select the upstream message format." + }, + "bedrock": { + "type": "object", + "properties": { + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "input_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in your prompt." + }, + "anthropic_version": { + "type": "string", + "description": "Defines the schema/API version, if using Anthropic provider." + }, + "azure_api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "mistral_format": { + "type": "string", + "enum": [ + "ollama", + "openai" + ], + "description": "If using mistral provider, select the upstream message format." + }, + "upstream_url": { + "type": "string", + "description": "Manually specify or override the full URL to the AI operation endpoints, when calling (self-)hosted models, or for running via a private endpoint. Variable substitution is supported. Warning: if variable substitution is used, please verify that the client is from a trusted source to prevent injection." + }, + "embeddings_dimensions": { + "type": "integer", + "description": "If using embeddings models, set the number of dimensions to generate." + }, + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + }, + "endpoint_id": { + "type": "string", + "description": "If running Gemini on Vertex Model Garden, specify the endpoint ID." + } + } + }, + "kimi": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Kimi/Moonshot AI endpoints are available: `api.moonshot.cn` (mainland China) and\n`api.moonshot.ai` (international, default). Set this to `false` to use the mainland China endpoint.\n", + "default": true + } + } + }, + "azure_deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + }, + "huggingface": { + "type": "object", + "properties": { + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + }, + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + } + } + }, + "cohere": { + "type": "object", + "properties": { + "api_version": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "description": "Cohere API version for chat route type: v1 (legacy, /v1/chat) or v2 (default, /v2/chat, supports tools).", + "default": "v2" + }, + "embedding_input_type": { + "type": "string", + "enum": [ + "classification", + "clustering", + "image", + "search_document", + "search_query" + ], + "description": "The purpose of the input text to calculate embedding vectors.", + "default": "classification" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "dashscope": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Dashscope endpoints are available, and the international endpoint will be used when this is set to `true`.\nIt is recommended to set this to `true` when using international version of dashscope.\n", + "default": true + } + } + }, + "max_tokens": { + "type": "integer", + "description": "Defines the max_tokens, if using chat or completion models." + }, + "output_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in the output of the AI." + }, + "temperature": { + "type": "number", + "maximum": 5, + "minimum": 0, + "description": "Defines the matching temperature, if using chat or completion models." + }, + "top_p": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Defines the top-p probability mass, if supported." + }, + "top_k": { + "type": "integer", + "maximum": 500, + "minimum": 0, + "description": "Defines the top-k most likely tokens, if supported." + } + }, + "description": "Key/value settings for the model" + }, + "provider": { + "type": "string", + "enum": [ + "anthropic", + "azure", + "bedrock", + "cerebras", + "cohere", + "dashscope", + "databricks", + "deepseek", + "gemini", + "huggingface", + "kimi", + "llama2", + "mistral", + "ollama", + "openai", + "vercel", + "vllm", + "xai" + ], + "description": "AI provider request format - Kong translates requests to and from the specified backend compatible formats." + }, + "name": { + "type": "string", + "description": "Model name to execute." + } + }, + "required": [ + "provider" + ] + }, + "logging": { + "type": "object", + "properties": { + "log_statistics": { + "type": "boolean", + "description": "If enabled and supported by the driver, will add model usage and token metrics into the Kong log plugin(s) output.", + "default": false + }, + "log_payloads": { + "type": "boolean", + "description": "If enabled, will log the request and response body into the Kong log plugin(s) output.Furthermore if Opentelemetry instrumentation is enabled the traces will contain this data as well.", + "default": false + } + } + }, + "weight": { + "type": "integer", + "maximum": 65535, + "minimum": 1, + "description": "The weight this target gets within the upstream loadbalancer (1-65535). Only used by ai-proxy-advanced.", + "default": 100 + }, + "description": { + "type": "string", + "description": "The semantic description of the target, required if using semantic load balancing. Specially, setting this to 'CATCHALL' will indicate such target to be used when no other targets match the semantic threshold. Only used by ai-proxy-advanced." + }, + "metadata": { + "type": "object", + "additionalProperties": true, + "description": "For internal use only. ", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "route_type": { + "type": "string", + "enum": [ + "audio/v1/audio/speech", + "audio/v1/audio/transcriptions", + "audio/v1/audio/translations", + "image/v1/images/edits", + "image/v1/images/generations", + "llm/v1/assistants", + "llm/v1/batches", + "llm/v1/chat", + "llm/v1/completions", + "llm/v1/embeddings", + "llm/v1/files", + "llm/v1/responses", + "realtime/v1/realtime", + "video/v1/videos/generations" + ], + "description": "The model's operation implementation, for this provider. " + }, + "auth": { + "type": "object", + "properties": { + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + } + } + } + }, + "required": [ + "model", + "route_type" + ] + } + }, + "required": [ + "llm" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "model", + "paths": [ + "config.llm" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiMcpOauth2.json b/app/_schemas/ai-gateway/policies/AiMcpOauth2.json new file mode 100644 index 00000000000..63a5cc4e5ed --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiMcpOauth2.json @@ -0,0 +1,502 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "minLength": 1, + "description": "Consumer fields used for mapping: - `id`: try to find the matching Consumer by `id` - `username`: try to find the matching Consumer by `username` - `custom_id`: try to find the matching Consumer by `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "metadata_discovery_endpoint": { + "type": "string", + "description": "Custom OAuth 2.0 authorization server metadata discovery URL. If provided, the plugin will use this URL directly instead of trying standard well-known discovery paths. The custom endpoint URL should end with either '/.well-known/openid-configuration' or '/.well-known/oauth-authorization-server'." + }, + "metadata_cache_ttl": { + "type": "integer", + "description": "The cache TTL in seconds for discovered authorization server metadata.", + "default": 3600 + }, + "client_auth": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The client authentication method." + }, + "tls_client_auth_cert": { + "type": "string", + "description": "PEM-encoded client certificate for mTLS." + }, + "tls_client_auth_key": { + "type": "string", + "description": "PEM-encoded private key for mTLS." + }, + "args": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Additional arguments to send in the POST body." + }, + "metadata_endpoint": { + "type": "string", + "description": "The path for OAuth 2.0 Protected Resource Metadata. Default to $resource/.well-known/oauth-protected-resource. For example, if the configured resource is https://api.example.com/mcp, the metadata endpoint is /mcp/.well-known/oauth-protected-resource." + }, + "insecure_relaxed_audience_validation": { + "type": "boolean", + "description": "If enabled, the plugin will not validate the audience of the access token. Disable it if the authorization server does not correctly set the audience claim according to RFC 8707 and MCP specification.", + "default": false + }, + "metadata_discovery_retry": { + "type": "integer", + "description": "The number of retry attempts for metadata discovery requests per URL.", + "default": 3 + }, + "token_exchange": { + "type": "object", + "properties": { + "request": { + "type": "object", + "properties": { + "actor_token": { + "type": "string", + "description": "Static actor token value (when source is config)." + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "Audiences used in the token exchange request." + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "Scopes used in the token exchange request." + }, + "subject_token_type": { + "type": "string", + "description": "The type of token to be exchanged.", + "default": "urn:ietf:params:oauth:token-type:access_token" + }, + "actor_token_source": { + "type": "string", + "enum": [ + "config", + "header", + "none" + ], + "description": "Where to obtain actor token.", + "default": "none" + }, + "actor_token_header": { + "type": "string", + "description": "Header name containing actor token (when source is header)." + }, + "actor_token_type": { + "type": "string", + "description": "The token type identifier of actor token.", + "default": "urn:ietf:params:oauth:token-type:access_token" + }, + "resource": { + "type": "string", + "description": "The absolute URI of target MCP service where token will be used." + }, + "requested_token_type": { + "type": "string", + "description": "The desired output token type.", + "default": "urn:ietf:params:oauth:token-type:access_token" + } + } + }, + "cache": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether to cache exchanged token", + "default": true + }, + "ttl": { + "type": "integer", + "description": "The default cache TTL to store exchanged token. If the exchange endpoint does not provide 'expires_in' data when token is exchanged this TTL value will be used to cache it.", + "default": 3600 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether Token Exchange should be enabled", + "default": false + }, + "token_endpoint": { + "type": "string", + "description": "The token exchange endopint." + }, + "client_id": { + "type": "string", + "description": "The client ID for authentication.", + "x-referenceable": true + }, + "client_secret": { + "type": "string", + "description": "The client secret for authentication.", + "x-encrypted": true, + "x-referenceable": true + }, + "client_auth": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_post", + "inherit", + "none" + ], + "description": "The type of authentication method to use with the exchange endpoint. Use 'inherit' to use the same client_id, and secret as in introspection_endpoint.", + "default": "client_secret_basic" + } + }, + "required": [ + "token_endpoint" + ], + "description": "Configuration details about token exchange that should happen before reaching upstream MCP server" + }, + "client_alg": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS384", + "RS512" + ], + "description": "The client JWT signing algorithm." + }, + "scopes_supported": { + "type": "array", + "items": { + "type": "string", + "description": "Recommended scopes that are used in authorization requests to request access to this protected resource." + }, + "minLength": 1 + }, + "claim_to_header": { + "type": "array", + "items": { + "type": "object", + "properties": { + "claim": { + "type": "string", + "description": "The claim name to be used in the access token." + }, + "header": { + "type": "string", + "description": "The HTTP header name to be used for forwarding the claim value to the upstream." + } + }, + "required": [ + "claim", + "header" + ] + }, + "minLength": 1, + "description": "Map top-level token claims to upstream headers. Mutually exclusive with upstream_headers." + }, + "passthrough_credentials": { + "type": "boolean", + "description": "Keep the credentials used for authentication in the request. If multiple credentials are sent with the same request, the plugin will keep those that were used for successful authentication.", + "default": false + }, + "consumer_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer mapping fails.", + "default": false + }, + "consumer_groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The claim used for consumer groups mapping. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "client_id": { + "type": "string", + "description": "The client ID for authentication.", + "x-referenceable": true + }, + "client_jwk": { + "type": "string", + "description": "The client JWK for private_key_jwt authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "tls_client_auth_ssl_verify": { + "type": "boolean", + "description": "Verify server certificate in mTLS.", + "default": true + }, + "resource": { + "type": "string", + "description": "The resource identifier." + }, + "keepalive": { + "type": "boolean", + "description": "Enable HTTP keepalive for requests.", + "default": true + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests.", + "default": 1.1 + }, + "timeout": { + "type": "number", + "description": "Network I/O timeout in milliseconds.", + "default": 10000 + }, + "upstream_headers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The name of the header." + }, + "path": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The path of the header value." + } + }, + "required": [ + "header", + "path" + ] + }, + "description": "Map token claims to upstream headers using path-based access. Each entry specifies a header name and a path (array of strings) to traverse the token claims. Mutually exclusive with claim_to_header." + }, + "consumer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The claim used for consumer mapping. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "jwt_claims_leeway": { + "type": "integer", + "description": "The leeway in seconds for JWT claims validation (exp, nbf). This allows tokens that are slightly expired or not yet valid due to clock skew.", + "default": 0 + }, + "introspection_endpoint": { + "type": "string", + "description": "The Token Introspection Endpoint. If not provided, the plugin will attempt to use JWKS to verify the token. If the token is opaque, this field must be provided." + }, + "introspection_format": { + "type": "string", + "enum": [ + "base64", + "base64url", + "string" + ], + "description": "Controls introspection response format." + }, + "authorization_servers": { + "type": "array", + "items": { + "type": "string", + "description": "The authorization server identifier." + }, + "minLength": 1 + }, + "jwks_cache_ttl": { + "type": "integer", + "description": "The cache TTL in seconds for JWKS.", + "default": 3600 + }, + "cache_introspection": { + "type": "boolean", + "description": "If enabled, the plugin will cache the introspection response for the access token. This can improve performance by reducing the number of introspection requests to the authorization server.", + "default": true + }, + "proxy_config": { + "type": "object", + "properties": { + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "mtls_introspection_endpoint": { + "type": "string", + "description": "The mTLS alias for the introspection endpoint." + }, + "client_secret": { + "type": "string", + "description": "The client secret for authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Verify the SSL certificate.", + "default": true + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "consumer_groups_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer groups mapping fails.", + "default": false + }, + "credential_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim used to derive virtual credentials (e.g. to be consumed by the rate-limiting plugin), in case the consumer mapping is not used. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "sub" + ] + }, + "jwks_endpoint": { + "type": "string", + "description": "The JWKS endpoint URL for fetching the authorization server's public keys. If not provided, the plugin will attempt to discover it from the authorization server metadata." + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Additional headers for the introspection request." + } + }, + "required": [ + "authorization_servers", + "resource" + ], + "description": "The configuration for MCP authorization in OAuth2. If this is enabled, make sure the configured metadata_endpoint is also covered by the same route so the authorization can be applied correctly." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiMcpProxy.json b/app/_schemas/ai-gateway/policies/AiMcpProxy.json new file mode 100644 index 00000000000..64ab69c8bae --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiMcpProxy.json @@ -0,0 +1,691 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "conversion-listener", + "conversion-only", + "listener", + "passthrough-listener", + "upstream-server" + ], + "description": "The mode of the MCP proxy. Possible values are: 'passthrough-listener', 'conversion-listener', 'conversion-only', 'listener', 'upstream-server'." + }, + "acl_attribute_type": { + "type": "string", + "enum": [ + "consumer", + "oauth_access_token" + ], + "description": "The type of attributes that ACL is evaluated with. Should only be configured on listener modes, not conversion-only.", + "default": "consumer" + }, + "default_acl": { + "type": "array", + "items": { + "type": "object", + "properties": { + "scope": { + "type": "string", + "description": "Scope for this default ACL entry (for example: 'tools'). Defaults to 'tools'.", + "default": "tools" + }, + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Subjects (e.g. Consumer name, Consumer Groups, or Claim values depending on configuration) explicitly allowed to access this scope." + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Subjects (e.g. Consumer name, Consumer Groups, or Claim values depending on configuration) explicitly denied from this scope. `deny` takes precedence over `allow`." + } + }, + "description": "Default ACL entry for the given scope. `deny` has higher precedence than `allow`." + }, + "description": "Optional list of default ACL rules keyed by scope (for example: tools)." + }, + "tools_cache_ttl_seconds": { + "type": "integer", + "description": "The time-to-live (TTL) for the upstream tools cache in seconds. Set to 0 to refresh on every client call." + }, + "include_consumer_groups": { + "type": "boolean", + "description": "If enabled (true), allows Consumer Group names to be used in default and per-primitive ACL. Should only be configured on listener modes, not conversion-only.", + "default": false + }, + "consumer_identifier": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ], + "description": "Which subject type entries in ACL lists refer to for per-consumer matching. Should only be configured on listener modes, not conversion-only.", + "default": "username" + }, + "access_token_claim_field": { + "type": "string", + "minLength": 1, + "description": "The claim in the OAuth2 access token to use as the subject for ACL evaluation when 'acl_attribute_type' is set to 'oauth_access_token'. Nested claim can be fetched by using a jq filter starts with dot, e.g., \".user.email\": https://jqlang.org/manual/#object-identifier-index." + }, + "tools": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "The host of the exported API, which must match the route's hosts. It should be the route's host. By default, Kong will extract the host from API configuration. If the configured host is wildcard, this field is required." + }, + "method": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "PATCH", + "POST", + "PUT" + ], + "description": "The method of the exported API, which must be one of the route's method. By default, Kong will extract the method from API configuration. If the configured method is not exactly matched, this field is required." + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "x-speakeasy-type-override": "any" + }, + "description": "The API parameters specification defined in OpenAPI JSON format. For example, '[{\"name\": \"city\", \"in\": \"query\", \"description\": \"Name of the city to get the weather for\", \"required\": true, \"schema\": {\"type\": \"string\"}}]'.See https://swagger.io/docs/specification/v3_0/describing-parameters/ for more details.", + "nullable": true + }, + "input_schema": { + "type": "object", + "additionalProperties": true, + "description": "The entire inputSchema section for the tool. This will override the upstream server's inputSchema on the same tool name, if present.", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "output_schema": { + "type": "object", + "additionalProperties": true, + "description": "The entire outputSchema section for the tool. This will override the upstream server's outputSchema on the same tool name, if present.", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "annotations": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Human-readable title for the tool" + }, + "read_only_hint": { + "type": "boolean", + "description": "If true, the tool does not modify its environment" + }, + "destructive_hint": { + "type": "boolean", + "description": "If true, the tool may perform destructive updates" + }, + "idempotent_hint": { + "type": "boolean", + "description": "If true, repeated calls with same args have no additional effect" + }, + "open_world_hint": { + "type": "boolean", + "description": "If true, tool interacts with external entities" + } + } + }, + "acl": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Subjects (e.g. Consumer name, Consumer Groups, or Claim values depending on configuration) explicitly allowed to use this primitive." + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Subjects (e.g. Consumer name, Consumer Groups, or Claim values depending on configuration) explicitly denied from using this primitive. `deny` takes precedence over `allow`." + } + }, + "description": "Optional per-primitive ACL. `deny` has higher precedence than `allow`." + }, + "name": { + "type": "string", + "description": "Tool identifier. In passthrough-listener mode, used to match remote MCP Server tools for ACL enforcement. In other modes, it is also used as the tool name (overrides tools.annotations.title if present)." + }, + "description": { + "type": "string", + "description": "The description of the MCP tool. This is used to provide information about the tool's functionality and usage." + }, + "responses": { + "type": "object", + "additionalProperties": true, + "description": "The API responses specification defined in OpenAPI JSON format. This specification will be used to validate the upstream response and map it back to the structuredOutput. For example, '{\"200\":{\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"result\":{\"type\":\"string\"}}}}}}}'.See https://swagger.io/docs/specification/v3_0/describing-responses/ for more details.Only one non-error (status code \u003c 400) response is supported. Note that `$ref` is not supported.", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "path": { + "type": "string", + "description": "The path of the exported API, which must match the route's paths. Path not starting with '/' are treated as relative path and the route path will be added as the prefix. If the upstream path is different from the route one, to match the route's path, use relative path and strip_path to strip the added prefix. Relative path is unsupported when the route path is regex. By default, Kong will extract the path from API configuration." + }, + "query": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "The query arguments of the exported API. If the generated query arguments are not exactly matched, this field is required." + }, + "scheme": { + "type": "string", + "enum": [ + "http", + "https" + ], + "description": "The scheme of the exported API, which must be one of the route's scheme. By default, Kong will extract the scheme from API configuration. If the configured scheme is not expected, this field can be used to override it." + }, + "request_body": { + "type": "object", + "additionalProperties": true, + "description": "The API requestBody specification defined in OpenAPI JSON format. For example, '{\"content\":{\"application/x-www-form-urlencoded\":{\"schema\":{\"type\":\"object\",\"properties\":{\"color\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}}}'.See https://swagger.io/docs/specification/v3_0/describing-request-body/describing-request-body/ for more details. Note that `$ref` is not supported so we need to inline the schema.", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "The headers of the exported API. By default, Kong will extract the headers from API configuration. If the configured headers are not exactly matched, this field is required." + } + }, + "required": [ + "description" + ] + } + }, + "server": { + "type": "object", + "properties": { + "tools_list_auth": { + "type": "object", + "properties": { + "scope": { + "type": "string", + "description": "The scopes for the OAuth 2.0 client-credentials.", + "x-referenceable": true + }, + "access_token_header": { + "type": "string", + "description": "Specify a header name used to send the fetched access token to the upstream MCP server. The value should include the header name and the token prefix if needed. Defaults to 'Authorization'." + }, + "id_token_header": { + "type": "string", + "description": "Specify a header name used to send the fetched ID token to the upstream MCP server. The value should include the header name and the token prefix if needed. Leave this empty to not send the ID token during tools list." + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint URL for fetching the OAuth 2.0 access token using client-credentials.", + "x-referenceable": true + }, + "client_id": { + "type": "string", + "description": "The client ID for the OAuth 2.0 client-credentials.", + "x-referenceable": true, + "x-encrypted": true + }, + "client_secret": { + "type": "string", + "description": "The client secret for the OAuth 2.0 client-credentials.", + "x-encrypted": true, + "x-referenceable": true + } + }, + "description": "Provide OAuth 2.0 client-credentials that can be used for fetching the tools list from an upstream MCP server. This is only applicable when mode is 'upstream-server'. The credentials will be stored in Kong and sent to the upstream MCP server when fetching the tools list." + }, + "tag": { + "type": "string", + "description": "The tag of the MCP server. This is used to filter the exported MCP tools. The field should contain exactly one tag. " + }, + "timeout": { + "type": "number", + "description": "The timeout for calling the tools in milliseconds.", + "default": 10000 + }, + "forward_client_headers": { + "type": "boolean", + "description": "Whether to forward the client request headers to the upstream server when calling the tools.", + "default": true + }, + "session": { + "type": "object", + "properties": { + "session_ttl": { + "type": "number", + "description": "The time-to-live (TTL) for each session in seconds.", + "default": 86400 + }, + "strategy": { + "type": "string", + "enum": [ + "client", + "redis" + ], + "description": "The strategy for the session. If the value is 'client', the session is encrypted into MCP session id assigned to the client. If the value is not 'client', the session is stored in the configured database." + }, + "client": { + "type": "object", + "properties": { + "secrets": { + "type": "array", + "items": { + "type": "string", + "minLength": 8, + "x-referenceable": true, + "x-encrypted": true + }, + "minLength": 1, + "description": "The secrets that are used in session encryption. Required when the strategy is 'client'. The first secret is used for encryption, while all secrets are used for decryption to support key rotation." + } + }, + "description": "The configuration for client-side session storage." + }, + "redis": { + "type": "object", + "properties": { + "cloud_authentication": { + "type": "object", + "properties": { + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + } + } + }, + "managed": { + "type": "boolean", + "description": "If enabled, Kong will maintain managed sessions with the MCP server.", + "default": true + } + }, + "description": "Enable managed session when Kong responds as MCP server in listener or conversion-listener modes. This doesn't affect the passthrough-listener mode as the state in that mode is maintained by the upstream MCP servers." + }, + "preserve_upstream_tool_names": { + "type": "boolean", + "description": "If enabled, the original upstream tool names are preserved as-is when Kong acts as an MCP server. If disabled (false), the service name will be prepended to the MCP tool names to avoid name collisions when multiple services are used.", + "default": false + } + } + }, + "logging": { + "type": "object", + "properties": { + "log_payloads": { + "type": "boolean", + "description": "If enabled, will log the request and response body into the Kong log plugin(s) output.", + "default": false + }, + "log_audits": { + "type": "boolean", + "description": "If true, emit audit logs for ACL evaluations.", + "default": false + }, + "log_statistics": { + "type": "boolean", + "description": "If enabled, will add mcp metrics into the Kong log plugin(s) output.", + "default": false + } + } + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "proxy_config": { + "type": "object", + "properties": { + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + } + } + } + }, + "required": [ + "mode" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiModelSelector.json b/app/_schemas/ai-gateway/policies/AiModelSelector.json new file mode 100644 index 00000000000..2eefa8bc6c5 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiModelSelector.json @@ -0,0 +1,101 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "body_path": { + "type": "string", + "description": "The name of the field where the model is extracted from the request body when source is 'body'. Only supports extract from the top-level", + "default": "model" + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "source": { + "type": "string", + "enum": [ + "body", + "header" + ], + "description": "Where the plugin reads the request model from.", + "default": "body" + }, + "header_name": { + "type": "string", + "description": "Header to read when source is 'header'." + } + } + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiPromptCompressor.json b/app/_schemas/ai-gateway/policies/AiPromptCompressor.json new file mode 100644 index 00000000000..5eb3006e41b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiPromptCompressor.json @@ -0,0 +1,193 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "log_text_data": { + "type": "boolean", + "description": "Log the text data", + "default": false + }, + "message_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "assistant", + "system", + "user" + ] + }, + "default": [ + "user" + ] + }, + "proxy_config": { + "type": "object", + "properties": { + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "compression_ranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "min_tokens": { + "type": "integer" + }, + "max_tokens": { + "type": "integer" + }, + "value": { + "type": "number" + } + }, + "required": [ + "max_tokens", + "min_tokens", + "value" + ] + }, + "description": "What value to be used to compress with. The 'value' is interpreted as rate or target_token depending on compressor_type." + }, + "compressor_url": { + "type": "string", + "description": "The url of the compressor", + "default": "http://localhost:8080" + }, + "compressor_type": { + "type": "string", + "enum": [ + "rate", + "target_token" + ], + "description": "What compression type to use to compress with", + "default": "rate" + }, + "timeout": { + "type": "number", + "description": "Connection timeout with the compressor", + "default": 10000 + }, + "keepalive_timeout": { + "type": "number", + "description": "The keepalive timeout for the established http connnection", + "default": 60000 + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs", + "default": true + } + }, + "required": [ + "compression_ranges" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiPromptDecorator.json b/app/_schemas/ai-gateway/policies/AiPromptDecorator.json new file mode 100644 index 00000000000..16e3e675521 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiPromptDecorator.json @@ -0,0 +1,145 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "prompts": { + "type": "object", + "properties": { + "prepend": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "assistant", + "system", + "user" + ], + "default": "system" + }, + "content": { + "type": "string", + "maxLength": 100000, + "minLength": 1 + } + }, + "required": [ + "content" + ] + }, + "maxLength": 15, + "description": "Insert chat messages at the beginning of the chat message array. This array preserves exact order when adding messages." + }, + "append": { + "type": "array", + "items": { + "type": "object", + "properties": { + "content": { + "type": "string", + "maxLength": 100000, + "minLength": 1 + }, + "role": { + "type": "string", + "enum": [ + "assistant", + "system", + "user" + ], + "default": "system" + } + }, + "required": [ + "content" + ] + }, + "maxLength": 15, + "description": "Insert chat messages at the end of the chat message array. This array preserves exact order when adding messages." + } + } + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "llm_format": { + "type": "string", + "enum": [ + "anthropic", + "bedrock", + "cohere", + "gemini", + "huggingface", + "openai" + ], + "description": "LLM input and output format and schema to use", + "default": "openai" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiPromptGuard.json b/app/_schemas/ai-gateway/policies/AiPromptGuard.json new file mode 100644 index 00000000000..24fe853b0ab --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiPromptGuard.json @@ -0,0 +1,129 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "allow_patterns": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 10, + "description": "Array of valid regex patterns, or valid questions from the 'user' role in chat." + }, + "deny_patterns": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 10, + "description": "Array of invalid regex patterns, or invalid questions from the 'user' role in chat." + }, + "allow_all_conversation_history": { + "type": "boolean", + "description": "If true, will ignore all previous chat prompts from the conversation history.", + "default": false + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "match_all_roles": { + "type": "boolean", + "description": "If true, will match all roles in addition to 'user' role in conversation history.", + "default": false + }, + "llm_format": { + "type": "string", + "enum": [ + "anthropic", + "bedrock", + "cohere", + "gemini", + "huggingface", + "openai" + ], + "description": "LLM input and output format and schema to use", + "default": "openai" + }, + "genai_category": { + "type": "string", + "enum": [ + "audio/speech", + "audio/transcription", + "image/generation", + "realtime/generation", + "text/embeddings", + "text/generation" + ], + "description": "Generative AI category of the request", + "default": "text/generation" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiPromptTemplate.json b/app/_schemas/ai-gateway/policies/AiPromptTemplate.json new file mode 100644 index 00000000000..04e91e1ebd7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiPromptTemplate.json @@ -0,0 +1,110 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "templates": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique name for the template, can be called with `{template://NAME}`" + }, + "template": { + "type": "string", + "description": "Template string for this request, supports mustache-style `{{placeholders}}`" + } + }, + "required": [ + "name", + "template" + ] + }, + "description": "Array of templates available to the request context." + }, + "allow_untemplated_requests": { + "type": "boolean", + "description": "Set true to allow requests that don't call or match any template.", + "default": true + }, + "log_original_request": { + "type": "boolean", + "description": "Set true to add the original request to the Kong log plugin(s) output.", + "default": false + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + } + }, + "required": [ + "templates" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiProxyAdvanced.json b/app/_schemas/ai-gateway/policies/AiProxyAdvanced.json new file mode 100644 index 00000000000..390e63bec77 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiProxyAdvanced.json @@ -0,0 +1,1429 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "llm_format": { + "type": "string", + "enum": [ + "anthropic", + "bedrock", + "cohere", + "gemini", + "huggingface", + "openai" + ], + "description": "LLM input and output format and schema to use", + "default": "openai" + }, + "genai_category": { + "type": "string", + "enum": [ + "audio/speech", + "audio/transcription", + "image/generation", + "realtime/generation", + "text/embeddings", + "text/generation" + ], + "description": "Generative AI category of the request", + "default": "text/generation" + }, + "balancer": { + "type": "object", + "properties": { + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "default": 60000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "default": 60000 + }, + "failover_criteria": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "error", + "http_403", + "http_404", + "http_429", + "http_500", + "http_502", + "http_503", + "http_504", + "invalid_header", + "non_idempotent", + "timeout" + ] + }, + "description": "Specifies in which cases an upstream response should be failover to the next target. Each option in the array is equivalent to the function of http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream", + "default": [ + "error", + "timeout" + ] + }, + "max_fails": { + "type": "integer", + "maximum": 32767, + "minimum": 0, + "description": "Number of unsuccessful attempts to communicate with a target that should occur in the duration defined by `fail_timeout` before the target is considered unavailable. The zero value disables the circuit breaker. What is considered an unsuccessful attempt is defined by `failover_criteria`. Note the cases of `error`, `timeout` and `invalid_header` are always considered unsuccessful attempts, while the cases of `http_403` and `http_404` are never considered unsuccessful attempts.", + "default": 0 + }, + "algorithm": { + "type": "string", + "enum": [ + "consistent-hashing", + "least-connections", + "lowest-latency", + "lowest-usage", + "priority", + "round-robin", + "semantic" + ], + "description": "Which load balancing algorithm to use.", + "default": "round-robin" + }, + "tokens_count_strategy": { + "type": "string", + "enum": [ + "completion-tokens", + "cost", + "llm-accuracy", + "prompt-tokens", + "total-tokens" + ], + "description": "What tokens to use for usage calculation. Available values are: `total_tokens` `prompt_tokens`, `completion_tokens` and `cost`.", + "default": "total-tokens" + }, + "write_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "default": 60000 + }, + "fail_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The period of time (in milliseconds) the target will be considered unavailable after the number of unsuccessful attempts reaches `max_fails`.", + "default": 10000 + }, + "latency_strategy": { + "type": "string", + "enum": [ + "e2e", + "tpot" + ], + "description": "What metrics to use for latency. Available values are: `tpot` (time-per-output-token) and `e2e`.", + "default": "tpot" + }, + "hash_on_header": { + "type": "string", + "description": "The header to use for consistent-hashing.", + "default": "X-Kong-LLM-Request-ID" + }, + "slots": { + "type": "integer", + "maximum": 65536, + "minimum": 10, + "description": "The number of slots in the load balancer algorithm.", + "default": 10000 + }, + "retries": { + "type": "integer", + "maximum": 32767, + "minimum": 0, + "description": "The number of retries to execute upon failure to proxy.", + "default": 5 + } + } + }, + "vectordb": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "pgvector", + "redis" + ], + "description": "which vector database driver to use" + }, + "dimensions": { + "type": "integer", + "description": "the desired dimensionality for the vectors" + }, + "threshold": { + "type": "number", + "description": "the default similarity threshold for accepting semantic search results (float). Higher threshold means more results are considered similar." + }, + "distance_metric": { + "type": "string", + "enum": [ + "cosine", + "euclidean" + ], + "description": "the distance metric to use for vector searches" + }, + "redis": { + "type": "object", + "properties": { + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + } + } + }, + "pgvector": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "the password of the pgvector database", + "x-referenceable": true, + "x-encrypted": true + }, + "timeout": { + "type": "number", + "description": "the timeout of the pgvector database", + "default": 5000 + }, + "ssl_version": { + "type": "string", + "enum": [ + "any", + "tlsv1_2", + "tlsv1_3" + ], + "description": "the ssl version to use for the pgvector database", + "default": "tlsv1_2" + }, + "user": { + "type": "string", + "description": "the user of the pgvector database", + "default": "postgres", + "x-referenceable": true + }, + "database": { + "type": "string", + "description": "the database of the pgvector database", + "default": "kong-pgvector" + }, + "ssl": { + "type": "boolean", + "description": "whether to use ssl for the pgvector database", + "default": false + }, + "ssl_required": { + "type": "boolean", + "description": "whether ssl is required for the pgvector database", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "whether to verify ssl for the pgvector database", + "default": true + }, + "ssl_cert": { + "type": "string", + "description": "the path of ssl cert to use for the pgvector database" + }, + "ssl_cert_key": { + "type": "string", + "description": "the path of ssl cert key to use for the pgvector database" + }, + "host": { + "type": "string", + "description": "the host of the pgvector database", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "description": "the port of the pgvector database", + "default": 5432 + } + } + } + }, + "required": [ + "dimensions", + "distance_metric", + "strategy" + ] + }, + "acls": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "object", + "properties": { + "match": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "authenticated_groups", + "consumer", + "consumer_group", + "header", + "ip", + "model", + "path", + "provider" + ], + "description": "The attribute to match against." + }, + "key": { + "type": "string", + "description": "Helper key used by some types: consumer (id|username), consumer_group (id|name), header (header name)." + }, + "values": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "Allowed values for the selected type." + } + }, + "required": [ + "type", + "values" + ], + "description": "Single match condition (e.g. user or model value)." + }, + "minLength": 1, + "description": "All conditions must match for the rule to apply (logical AND)." + } + }, + "required": [ + "match" + ], + "description": "ACL rule composed of one or more match conditions." + }, + "minLength": 1, + "description": "Requests matching any allow rule are permitted unless also matched by a deny rule." + }, + "deny": { + "type": "array", + "items": { + "type": "object", + "properties": { + "match": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "authenticated_groups", + "consumer", + "consumer_group", + "header", + "ip", + "model", + "path", + "provider" + ], + "description": "The attribute to match against." + }, + "key": { + "type": "string", + "description": "Helper key used by some types: consumer (id|username), consumer_group (id|name), header (header name)." + }, + "values": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "Allowed values for the selected type." + } + }, + "required": [ + "type", + "values" + ], + "description": "Single match condition (e.g. user or model value)." + }, + "minLength": 1, + "description": "All conditions must match for the rule to apply (logical AND)." + } + }, + "required": [ + "match" + ], + "description": "ACL rule composed of one or more match conditions." + }, + "minLength": 1, + "description": "Requests matching any deny rule are blocked. Deny rules take precedence over allow rules." + } + }, + "description": "Optional ACL rules. Deny rules take precedence over allow rules." + }, + "embeddings": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-encrypted": true, + "x-referenceable": true + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + } + } + }, + "model": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "azure", + "bedrock", + "databricks", + "gemini", + "huggingface", + "mistral", + "ollama", + "openai", + "vercel" + ], + "description": "AI provider format to use for embeddings API" + }, + "name": { + "type": "string", + "description": "Model name to execute." + }, + "options": { + "type": "object", + "properties": { + "upstream_url": { + "type": "string", + "description": "upstream url for the embeddings" + }, + "azure": { + "type": "object", + "properties": { + "api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + }, + "instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + } + } + }, + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + } + } + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + } + }, + "description": "Key/value settings for the model" + } + }, + "required": [ + "name", + "provider" + ] + } + }, + "required": [ + "model" + ] + }, + "proxy_config": { + "type": "object", + "properties": { + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "response_streaming": { + "type": "string", + "enum": [ + "allow", + "always", + "deny" + ], + "description": "Whether to 'optionally allow', 'deny', or 'always' (force) the streaming of answers via server sent events.", + "default": "allow" + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "model_name_header": { + "type": "boolean", + "description": "Display the model name selected in the X-Kong-LLM-Model response header", + "default": true + }, + "targets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "The semantic description of the target, required if using semantic load balancing. Specially, setting this to 'CATCHALL' will indicate such target to be used when no other targets match the semantic threshold. Only used by ai-proxy-advanced." + }, + "metadata": { + "type": "object", + "additionalProperties": true, + "description": "For internal use only. ", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "route_type": { + "type": "string", + "enum": [ + "audio/v1/audio/speech", + "audio/v1/audio/transcriptions", + "audio/v1/audio/translations", + "image/v1/images/edits", + "image/v1/images/generations", + "llm/v1/assistants", + "llm/v1/batches", + "llm/v1/chat", + "llm/v1/completions", + "llm/v1/embeddings", + "llm/v1/files", + "llm/v1/responses", + "realtime/v1/realtime", + "video/v1/videos/generations" + ], + "description": "The model's operation implementation, for this provider. " + }, + "auth": { + "type": "object", + "properties": { + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-encrypted": true, + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + } + } + }, + "model": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "anthropic", + "azure", + "bedrock", + "cerebras", + "cohere", + "dashscope", + "databricks", + "deepseek", + "gemini", + "huggingface", + "kimi", + "llama2", + "mistral", + "ollama", + "openai", + "vercel", + "vllm", + "xai" + ], + "description": "AI provider request format - Kong translates requests to and from the specified backend compatible formats." + }, + "name": { + "type": "string", + "description": "Model name to execute." + }, + "model_alias": { + "type": "string", + "description": "The model name parameter from the request that this model should map to." + }, + "options": { + "type": "object", + "properties": { + "anthropic_version": { + "type": "string", + "description": "Defines the schema/API version, if using Anthropic provider." + }, + "azure_deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + }, + "upstream_url": { + "type": "string", + "description": "Manually specify or override the full URL to the AI operation endpoints, when calling (self-)hosted models, or for running via a private endpoint. Variable substitution is supported. Warning: if variable substitution is used, please verify that the client is from a trusted source to prevent injection." + }, + "bedrock": { + "type": "object", + "properties": { + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + }, + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + } + } + }, + "cohere": { + "type": "object", + "properties": { + "api_version": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "description": "Cohere API version for chat route type: v1 (legacy, /v1/chat) or v2 (default, /v2/chat, supports tools).", + "default": "v2" + }, + "embedding_input_type": { + "type": "string", + "enum": [ + "classification", + "clustering", + "image", + "search_document", + "search_query" + ], + "description": "The purpose of the input text to calculate embedding vectors.", + "default": "classification" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "dashscope": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Dashscope endpoints are available, and the international endpoint will be used when this is set to `true`.\nIt is recommended to set this to `true` when using international version of dashscope.\n", + "default": true + } + } + }, + "output_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in the output of the AI." + }, + "temperature": { + "type": "number", + "maximum": 5, + "minimum": 0, + "description": "Defines the matching temperature, if using chat or completion models." + }, + "top_k": { + "type": "integer", + "maximum": 500, + "minimum": 0, + "description": "Defines the top-k most likely tokens, if supported." + }, + "mistral_format": { + "type": "string", + "enum": [ + "ollama", + "openai" + ], + "description": "If using mistral provider, select the upstream message format." + }, + "embeddings_dimensions": { + "type": "integer", + "description": "If using embeddings models, set the number of dimensions to generate." + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "top_p": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Defines the top-p probability mass, if supported." + }, + "llama2_format": { + "type": "string", + "enum": [ + "ollama", + "openai", + "raw" + ], + "description": "If using llama2 provider, select the upstream message format." + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "kimi": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Kimi/Moonshot AI endpoints are available: `api.moonshot.cn` (mainland China) and\n`api.moonshot.ai` (international, default). Set this to `false` to use the mainland China endpoint.\n", + "default": true + } + } + }, + "max_tokens": { + "type": "integer", + "description": "Defines the max_tokens, if using chat or completion models." + }, + "input_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in your prompt." + }, + "azure_instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "azure_api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "gemini": { + "type": "object", + "properties": { + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + }, + "endpoint_id": { + "type": "string", + "description": "If running Gemini on Vertex Model Garden, specify the endpoint ID." + }, + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + } + } + } + }, + "description": "Key/value settings for the model" + } + }, + "required": [ + "provider" + ] + }, + "logging": { + "type": "object", + "properties": { + "log_payloads": { + "type": "boolean", + "description": "If enabled, will log the request and response body into the Kong log plugin(s) output.Furthermore if Opentelemetry instrumentation is enabled the traces will contain this data as well.", + "default": false + }, + "log_statistics": { + "type": "boolean", + "description": "If enabled and supported by the driver, will add model usage and token metrics into the Kong log plugin(s) output.", + "default": false + } + } + }, + "weight": { + "type": "integer", + "maximum": 65535, + "minimum": 1, + "description": "The weight this target gets within the upstream loadbalancer (1-65535). Only used by ai-proxy-advanced.", + "default": 100 + } + }, + "required": [ + "model", + "route_type" + ] + } + } + }, + "required": [ + "targets" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "embeddings", + "paths": [ + "config.embeddings" + ] + }, + { + "name": "model", + "paths": [ + "config.targets[]" + ] + }, + { + "name": "vectordb", + "paths": [ + "config.vectordb" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiRagInjector.json b/app/_schemas/ai-gateway/policies/AiRagInjector.json new file mode 100644 index 00000000000..7b53b04c1c6 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiRagInjector.json @@ -0,0 +1,828 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "proxy_config": { + "type": "object", + "properties": { + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + } + } + }, + "max_filter_clauses": { + "type": "integer", + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of filter clauses allowed", + "default": 100 + }, + "stop_on_filter_error": { + "type": "boolean", + "description": "Default behavior when filter parsing fails (can be overridden per-request)", + "default": false + }, + "stop_on_failure": { + "type": "boolean", + "description": "Halt the LLM request process in case of a vectordb or embeddings service failure", + "default": false + }, + "inject_as_role": { + "type": "string", + "enum": [ + "assistant", + "system", + "user" + ], + "default": "user" + }, + "inject_template": { + "type": "string", + "default": "\u003cCONTEXT\u003e\n\u003cPROMPT\u003e" + }, + "global_acl_config": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Consumer identifiers allowed access (groups, IDs, usernames, or custom IDs based on consumer_identifier setting)", + "default": [] + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Consumer identifiers denied access (groups, IDs, usernames, or custom IDs based on consumer_identifier setting)", + "default": [] + } + }, + "description": "Global ACL configuration for all RAG operations" + }, + "collection_acl_config": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Consumer identifiers allowed access to this collection", + "default": [] + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Consumer identifiers denied access to this collection", + "default": [] + } + } + }, + "description": "Per-collection ACL overrides" + }, + "filter_mode": { + "type": "string", + "enum": [ + "compatible", + "strict" + ], + "description": "Defines how the plugin behaves when a filter is invalid. Set to `compatible` to ignore invalid filters, or `strict` to raise an error. This can be overridden per request.", + "default": "compatible" + }, + "consumer_identifier": { + "type": "string", + "enum": [ + "consumer_group", + "consumer_id", + "custom_id", + "username" + ], + "description": "The type of consumer identifier used for ACL checks", + "default": "consumer_group" + }, + "fetch_chunks_count": { + "type": "number", + "description": "The maximum number of chunks to fetch from vectordb", + "default": 5 + }, + "vectordb_namespace": { + "type": "string", + "description": "The namespace of the vectordb to use for embeddings lookup", + "default": "kong_rag_injector" + }, + "embeddings": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + } + } + }, + "model": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "azure", + "bedrock", + "databricks", + "gemini", + "huggingface", + "mistral", + "ollama", + "openai", + "vercel" + ], + "description": "AI provider format to use for embeddings API" + }, + "name": { + "type": "string", + "description": "Model name to execute." + }, + "options": { + "type": "object", + "properties": { + "upstream_url": { + "type": "string", + "description": "upstream url for the embeddings" + }, + "azure": { + "type": "object", + "properties": { + "instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + } + } + }, + "gemini": { + "type": "object", + "properties": { + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + }, + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + } + } + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + } + }, + "description": "Key/value settings for the model" + } + }, + "required": [ + "name", + "provider" + ] + } + }, + "required": [ + "model" + ] + }, + "vectordb": { + "type": "object", + "properties": { + "threshold": { + "type": "number", + "description": "the default similarity threshold for accepting semantic search results (float). Higher threshold means more results are considered similar." + }, + "distance_metric": { + "type": "string", + "enum": [ + "cosine", + "euclidean" + ], + "description": "the distance metric to use for vector searches" + }, + "redis": { + "type": "object", + "properties": { + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "pgvector": { + "type": "object", + "properties": { + "ssl_cert_key": { + "type": "string", + "description": "the path of ssl cert key to use for the pgvector database" + }, + "port": { + "type": "integer", + "description": "the port of the pgvector database", + "default": 5432 + }, + "user": { + "type": "string", + "description": "the user of the pgvector database", + "default": "postgres", + "x-referenceable": true + }, + "database": { + "type": "string", + "description": "the database of the pgvector database", + "default": "kong-pgvector" + }, + "timeout": { + "type": "number", + "description": "the timeout of the pgvector database", + "default": 5000 + }, + "ssl_required": { + "type": "boolean", + "description": "whether ssl is required for the pgvector database", + "default": false + }, + "host": { + "type": "string", + "description": "the host of the pgvector database", + "default": "127.0.0.1" + }, + "password": { + "type": "string", + "description": "the password of the pgvector database", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl": { + "type": "boolean", + "description": "whether to use ssl for the pgvector database", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "whether to verify ssl for the pgvector database", + "default": true + }, + "ssl_version": { + "type": "string", + "enum": [ + "any", + "tlsv1_2", + "tlsv1_3" + ], + "description": "the ssl version to use for the pgvector database", + "default": "tlsv1_2" + }, + "ssl_cert": { + "type": "string", + "description": "the path of ssl cert to use for the pgvector database" + } + } + }, + "strategy": { + "type": "string", + "enum": [ + "pgvector", + "redis" + ], + "description": "which vector database driver to use" + }, + "dimensions": { + "type": "integer", + "description": "the desired dimensionality for the vectors" + } + }, + "required": [ + "dimensions", + "distance_metric", + "strategy" + ] + } + }, + "required": [ + "embeddings", + "vectordb" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "embeddings", + "paths": [ + "config.embeddings" + ] + }, + { + "name": "vectordb", + "paths": [ + "config.vectordb" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiRateLimitingAdvanced.json b/app/_schemas/ai-gateway/policies/AiRateLimitingAdvanced.json new file mode 100644 index 00000000000..4480ff31bf0 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiRateLimitingAdvanced.json @@ -0,0 +1,559 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is isolated in each namespace. NOTE: For the plugin instances sharing the same namespace, all the configurations that are required for synchronizing counters, e.g. `strategy`, `redis`, `sync_rate`, `dictionary_name`, need to be the same." + }, + "policies": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "UUID reference to a reusable ai_rate_limiting_policies DAO entity. Mutually exclusive with inline limits." + }, + "match": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "consumer", + "consumer_group", + "header", + "ip", + "model", + "path", + "provider" + ], + "description": "The attribute to match against." + }, + "values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Values to match. If omitted, matches any value of this type." + }, + "key": { + "type": "string", + "description": "Sub-key for consumer (id|username|custom_id), consumer_group (id|name), or header (header name)." + }, + "partition_by": { + "type": "boolean", + "description": "If true, the matched value contributes to the composite rate limit counter key.", + "default": false + } + }, + "required": [ + "type" + ] + }, + "description": "Array of match conditions (AND logic). If omitted, this policy acts as a fallback for unmatched requests." + }, + "limits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "week_start_day": { + "type": "string", + "enum": [ + "friday", + "monday", + "saturday", + "sunday", + "thursday", + "tuesday", + "wednesday" + ], + "description": "Day the week starts for calendar weekly windows." + }, + "month_day": { + "type": "integer", + "maximum": 31, + "minimum": 1, + "description": "Day of month the calendar monthly window starts (1-31)." + }, + "tokens_count_strategy": { + "type": "string", + "enum": [ + "completion_tokens", + "cost", + "prompt_tokens", + "total_tokens" + ], + "description": "What to count for this limit. Supported strategies: total_tokens, prompt_tokens, completion_tokens, cost.", + "default": "total_tokens" + }, + "limit": { + "type": "number", + "description": "The rate limit threshold for this window." + }, + "window_size": { + "type": "integer", + "description": "The window size in seconds for fixed or sliding windows." + }, + "period": { + "type": "string", + "enum": [ + "month", + "week" + ], + "description": "The calendar period for calendar windows." + } + }, + "required": [ + "limit" + ] + }, + "minLength": 1, + "description": "Rate limits to enforce when this policy matches." + }, + "window_type": { + "type": "string", + "enum": [ + "calendar", + "fixed", + "sliding" + ], + "description": "The time window type for this policy.", + "default": "sliding" + }, + "timezone": { + "type": "string", + "description": "IANA timezone used for calendar window boundaries." + } + } + }, + "minLength": 1, + "description": "Policy-based rate limiting. Each policy defines match conditions and limits." + }, + "header_name": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "error_message": { + "type": "string", + "description": "Set a custom error message to return when the rate limit is exceeded.", + "default": "AI token rate limit exceeded for provider(s): " + }, + "tokens_count_strategy": { + "type": "string", + "enum": [ + "completion_tokens", + "cost", + "prompt_tokens", + "total_tokens" + ], + "description": "What tokens to use for cost calculation. Available values are: `total_tokens` `prompt_tokens`, `completion_tokens` or `cost`.", + "default": "total_tokens" + }, + "path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes)." + }, + "disable_penalty": { + "type": "boolean", + "description": "If set to `true`, this doesn't count denied requests (status = `429`). If set to `false`, all requests, including denied ones, are counted. This parameter only affects the `sliding` window_type and the request prompt provider.", + "default": false + }, + "error_hide_providers": { + "type": "boolean", + "description": "Optionally hide informative response that would otherwise provide information about the provider in the error message.", + "default": false + }, + "sync_rate": { + "type": "number", + "description": "How often to sync counter data to the central data store. A value of 0 results in synchronous behavior; a value of -1 ignores sync behavior entirely and only stores counters in node memory. A value greater than 0 will sync the counters in the specified number of seconds. The minimum allowed interval is 0.02 seconds (20ms)." + }, + "strategy": { + "type": "string", + "enum": [ + "cluster", + "local", + "redis" + ], + "description": "The rate-limiting strategy to use for retrieving and incrementing the limits. Available values are: `local`, `redis` and `cluster`.", + "default": "local" + }, + "dictionary_name": { + "type": "string", + "description": "The shared dictionary where counters are stored. When the plugin is configured to synchronize counter data externally (that is `config.strategy` is `cluster` or `redis` and `config.sync_rate` isn't `-1`), this dictionary serves as a buffer to populate counters in the data store on each synchronization cycle. The dictionary must be defined in the nginx configuration using `lua_shared_dict` directive (e.g., `lua_shared_dict kong_rate_limiting_counters 12m`).", + "default": "kong_rate_limiting_counters" + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers that would otherwise provide information about the current status of limits and counters.", + "default": false + }, + "request_prompt_count_function": { + "type": "string", + "description": "If defined, it use custom function to count requests for the request prompt provider" + }, + "custom_cost_count_function": { + "type": "string", + "description": "If defined, it uses custom function to generate cost for the inference request" + }, + "error_code": { + "type": "number", + "description": "Set a custom error code to return when the rate limit is exceeded.", + "default": 429 + }, + "retry_after_jitter_max": { + "type": "number", + "description": "The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` header of denied requests (status = `429`) in order to prevent all the clients from coming back at the same time. The lower bound of the jitter is `0`; in this case, the `Retry-After` header is equal to the `RateLimit-Reset` header.", + "default": 0 + }, + "redis": { + "type": "object", + "properties": { + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-encrypted": true, + "x-referenceable": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + } + } + }, + "decrease_by_fractions_in_redis": { + "type": "boolean", + "description": "By default, Kong decreates the AI rate limiting counters by whole number in Redis. This setting allows to decrease the counters by float number.", + "default": false + }, + "identifier": { + "type": "string", + "enum": [ + "consumer", + "consumer-group", + "credential", + "header", + "ip", + "path", + "service" + ], + "description": "The type of identifier used to generate the rate limit key. Defines the scope used to increment the rate limiting counters. Can be `ip`, `credential`, `consumer`, `service`, `header`, `path` or `consumer-group`. Note if `identifier` is `consumer-group`, the plugin must be applied on a consumer group entity. Because a consumer may belong to multiple consumer groups, the plugin needs to know explicitly which consumer group to limit the rate.", + "default": "consumer" + }, + "window_type": { + "type": "string", + "enum": [ + "fixed", + "sliding" + ], + "description": "Sets the time window type to either `sliding` (default) or `fixed`. Sliding windows apply the rate limiting logic while taking into account previous hit rates (from the window that immediately precedes the current) using a dynamic weight. Fixed windows consist of buckets that are statically assigned to a definitive time range, each request is mapped to only one fixed window based on its timestamp and will affect only that window's counters.", + "default": "sliding" + } + }, + "required": [ + "policies" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiRequestTransformer.json b/app/_schemas/ai-gateway/policies/AiRequestTransformer.json new file mode 100644 index 00000000000..737e4ae0a40 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiRequestTransformer.json @@ -0,0 +1,553 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "llm": { + "type": "object", + "properties": { + "logging": { + "type": "object", + "properties": { + "log_statistics": { + "type": "boolean", + "description": "If enabled and supported by the driver, will add model usage and token metrics into the Kong log plugin(s) output.", + "default": false + }, + "log_payloads": { + "type": "boolean", + "description": "If enabled, will log the request and response body into the Kong log plugin(s) output.Furthermore if Opentelemetry instrumentation is enabled the traces will contain this data as well.", + "default": false + } + } + }, + "weight": { + "type": "integer", + "maximum": 65535, + "minimum": 1, + "description": "The weight this target gets within the upstream loadbalancer (1-65535). Only used by ai-proxy-advanced.", + "default": 100 + }, + "description": { + "type": "string", + "description": "The semantic description of the target, required if using semantic load balancing. Specially, setting this to 'CATCHALL' will indicate such target to be used when no other targets match the semantic threshold. Only used by ai-proxy-advanced." + }, + "metadata": { + "type": "object", + "additionalProperties": true, + "description": "For internal use only. ", + "nullable": true, + "x-speakeasy-type-override": "any" + }, + "route_type": { + "type": "string", + "enum": [ + "audio/v1/audio/speech", + "audio/v1/audio/transcriptions", + "audio/v1/audio/translations", + "image/v1/images/edits", + "image/v1/images/generations", + "llm/v1/assistants", + "llm/v1/batches", + "llm/v1/chat", + "llm/v1/completions", + "llm/v1/embeddings", + "llm/v1/files", + "llm/v1/responses", + "realtime/v1/realtime", + "video/v1/videos/generations" + ], + "description": "The model's operation implementation, for this provider. " + }, + "auth": { + "type": "object", + "properties": { + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + } + } + }, + "model": { + "type": "object", + "properties": { + "options": { + "type": "object", + "properties": { + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "kimi": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Kimi/Moonshot AI endpoints are available: `api.moonshot.cn` (mainland China) and\n`api.moonshot.ai` (international, default). Set this to `false` to use the mainland China endpoint.\n", + "default": true + } + } + }, + "input_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in your prompt." + }, + "output_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in the output of the AI." + }, + "anthropic_version": { + "type": "string", + "description": "Defines the schema/API version, if using Anthropic provider." + }, + "embeddings_dimensions": { + "type": "integer", + "description": "If using embeddings models, set the number of dimensions to generate." + }, + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + }, + "endpoint_id": { + "type": "string", + "description": "If running Gemini on Vertex Model Garden, specify the endpoint ID." + } + } + }, + "temperature": { + "type": "number", + "maximum": 5, + "minimum": 0, + "description": "Defines the matching temperature, if using chat or completion models." + }, + "top_k": { + "type": "integer", + "maximum": 500, + "minimum": 0, + "description": "Defines the top-k most likely tokens, if supported." + }, + "llama2_format": { + "type": "string", + "enum": [ + "ollama", + "openai", + "raw" + ], + "description": "If using llama2 provider, select the upstream message format." + }, + "cohere": { + "type": "object", + "properties": { + "api_version": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "description": "Cohere API version for chat route type: v1 (legacy, /v1/chat) or v2 (default, /v2/chat, supports tools).", + "default": "v2" + }, + "embedding_input_type": { + "type": "string", + "enum": [ + "classification", + "clustering", + "image", + "search_document", + "search_query" + ], + "description": "The purpose of the input text to calculate embedding vectors.", + "default": "classification" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "dashscope": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Dashscope endpoints are available, and the international endpoint will be used when this is set to `true`.\nIt is recommended to set this to `true` when using international version of dashscope.\n", + "default": true + } + } + }, + "max_tokens": { + "type": "integer", + "description": "Defines the max_tokens, if using chat or completion models." + }, + "azure_instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "azure_deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + }, + "mistral_format": { + "type": "string", + "enum": [ + "ollama", + "openai" + ], + "description": "If using mistral provider, select the upstream message format." + }, + "top_p": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Defines the top-p probability mass, if supported." + }, + "azure_api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "upstream_url": { + "type": "string", + "description": "Manually specify or override the full URL to the AI operation endpoints, when calling (self-)hosted models, or for running via a private endpoint. Variable substitution is supported. Warning: if variable substitution is used, please verify that the client is from a trusted source to prevent injection." + }, + "bedrock": { + "type": "object", + "properties": { + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + }, + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + } + } + } + }, + "description": "Key/value settings for the model" + }, + "provider": { + "type": "string", + "enum": [ + "anthropic", + "azure", + "bedrock", + "cerebras", + "cohere", + "dashscope", + "databricks", + "deepseek", + "gemini", + "huggingface", + "kimi", + "llama2", + "mistral", + "ollama", + "openai", + "vercel", + "vllm", + "xai" + ], + "description": "AI provider request format - Kong translates requests to and from the specified backend compatible formats." + }, + "name": { + "type": "string", + "description": "Model name to execute." + }, + "model_alias": { + "type": "string", + "description": "The model name parameter from the request that this model should map to." + } + }, + "required": [ + "provider" + ] + } + }, + "required": [ + "model", + "route_type" + ] + }, + "prompt": { + "type": "string", + "description": "Use this prompt to tune the LLM system/assistant message for the incoming proxy request (from the client), and what you are expecting in return." + }, + "transformation_extract_pattern": { + "type": "string", + "description": "Defines the regular expression that must match to indicate a successful AI transformation at the request phase. The first match will be set as the outgoing body. If the AI service's response doesn't match this pattern, it is marked as a failure." + }, + "http_timeout": { + "type": "integer", + "description": "Timeout in milliseconds for the AI upstream service.", + "default": 60000 + }, + "https_verify": { + "type": "boolean", + "description": "Verify the TLS certificate of the AI upstream service.", + "default": true + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + }, + "proxy_config": { + "type": "object", + "properties": { + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + } + } + } + }, + "required": [ + "llm", + "prompt" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "model", + "paths": [ + "config.llm" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiResponseTransformer.json b/app/_schemas/ai-gateway/policies/AiResponseTransformer.json new file mode 100644 index 00000000000..138e5df8524 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiResponseTransformer.json @@ -0,0 +1,568 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "proxy_config": { + "type": "object", + "properties": { + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "llm": { + "type": "object", + "properties": { + "route_type": { + "type": "string", + "enum": [ + "audio/v1/audio/speech", + "audio/v1/audio/transcriptions", + "audio/v1/audio/translations", + "image/v1/images/edits", + "image/v1/images/generations", + "llm/v1/assistants", + "llm/v1/batches", + "llm/v1/chat", + "llm/v1/completions", + "llm/v1/embeddings", + "llm/v1/files", + "llm/v1/responses", + "realtime/v1/realtime", + "video/v1/videos/generations" + ], + "description": "The model's operation implementation, for this provider. " + }, + "auth": { + "type": "object", + "properties": { + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + } + } + }, + "model": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "anthropic", + "azure", + "bedrock", + "cerebras", + "cohere", + "dashscope", + "databricks", + "deepseek", + "gemini", + "huggingface", + "kimi", + "llama2", + "mistral", + "ollama", + "openai", + "vercel", + "vllm", + "xai" + ], + "description": "AI provider request format - Kong translates requests to and from the specified backend compatible formats." + }, + "name": { + "type": "string", + "description": "Model name to execute." + }, + "model_alias": { + "type": "string", + "description": "The model name parameter from the request that this model should map to." + }, + "options": { + "type": "object", + "properties": { + "temperature": { + "type": "number", + "maximum": 5, + "minimum": 0, + "description": "Defines the matching temperature, if using chat or completion models." + }, + "max_tokens": { + "type": "integer", + "description": "Defines the max_tokens, if using chat or completion models." + }, + "llama2_format": { + "type": "string", + "enum": [ + "ollama", + "openai", + "raw" + ], + "description": "If using llama2 provider, select the upstream message format." + }, + "embeddings_dimensions": { + "type": "integer", + "description": "If using embeddings models, set the number of dimensions to generate." + }, + "top_p": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Defines the top-p probability mass, if supported." + }, + "top_k": { + "type": "integer", + "maximum": 500, + "minimum": 0, + "description": "Defines the top-k most likely tokens, if supported." + }, + "anthropic_version": { + "type": "string", + "description": "Defines the schema/API version, if using Anthropic provider." + }, + "upstream_url": { + "type": "string", + "description": "Manually specify or override the full URL to the AI operation endpoints, when calling (self-)hosted models, or for running via a private endpoint. Variable substitution is supported. Warning: if variable substitution is used, please verify that the client is from a trusted source to prevent injection." + }, + "huggingface": { + "type": "object", + "properties": { + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + }, + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + } + } + }, + "cohere": { + "type": "object", + "properties": { + "api_version": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "description": "Cohere API version for chat route type: v1 (legacy, /v1/chat) or v2 (default, /v2/chat, supports tools).", + "default": "v2" + }, + "embedding_input_type": { + "type": "string", + "enum": [ + "classification", + "clustering", + "image", + "search_document", + "search_query" + ], + "description": "The purpose of the input text to calculate embedding vectors.", + "default": "classification" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "dashscope": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Dashscope endpoints are available, and the international endpoint will be used when this is set to `true`.\nIt is recommended to set this to `true` when using international version of dashscope.\n", + "default": true + } + } + }, + "kimi": { + "type": "object", + "properties": { + "international": { + "type": "boolean", + "description": "Two Kimi/Moonshot AI endpoints are available: `api.moonshot.cn` (mainland China) and\n`api.moonshot.ai` (international, default). Set this to `false` to use the mainland China endpoint.\n", + "default": true + } + } + }, + "input_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in your prompt." + }, + "azure_instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "azure_api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "azure_deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + }, + "mistral_format": { + "type": "string", + "enum": [ + "ollama", + "openai" + ], + "description": "If using mistral provider, select the upstream message format." + }, + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + }, + "endpoint_id": { + "type": "string", + "description": "If running Gemini on Vertex Model Garden, specify the endpoint ID." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "output_cost": { + "type": "number", + "description": "Defines the cost per 1M tokens in the output of the AI." + } + }, + "description": "Key/value settings for the model" + } + }, + "required": [ + "provider" + ] + }, + "logging": { + "type": "object", + "properties": { + "log_payloads": { + "type": "boolean", + "description": "If enabled, will log the request and response body into the Kong log plugin(s) output.Furthermore if Opentelemetry instrumentation is enabled the traces will contain this data as well.", + "default": false + }, + "log_statistics": { + "type": "boolean", + "description": "If enabled and supported by the driver, will add model usage and token metrics into the Kong log plugin(s) output.", + "default": false + } + } + }, + "weight": { + "type": "integer", + "maximum": 65535, + "minimum": 1, + "description": "The weight this target gets within the upstream loadbalancer (1-65535). Only used by ai-proxy-advanced.", + "default": 100 + }, + "description": { + "type": "string", + "description": "The semantic description of the target, required if using semantic load balancing. Specially, setting this to 'CATCHALL' will indicate such target to be used when no other targets match the semantic threshold. Only used by ai-proxy-advanced." + }, + "metadata": { + "type": "object", + "additionalProperties": true, + "description": "For internal use only. ", + "nullable": true, + "x-speakeasy-type-override": "any" + } + }, + "required": [ + "model", + "route_type" + ] + }, + "prompt": { + "type": "string", + "description": "Use this prompt to tune the LLM system/assistant message for the returning proxy response (from the upstream), adn what response format you are expecting." + }, + "transformation_extract_pattern": { + "type": "string", + "description": "Defines the regular expression that must match to indicate a successful AI transformation at the response phase. The first match will be set as the returning body. If the AI service's response doesn't match this pattern, a failure is returned to the client." + }, + "parse_llm_response_json_instructions": { + "type": "boolean", + "description": "Set true to read specific response format from the LLM, and accordingly set the status code / body / headers that proxy back to the client. You need to engineer your LLM prompt to return the correct format, see plugin docs 'Overview' page for usage instructions.", + "default": false + }, + "http_timeout": { + "type": "integer", + "description": "Timeout in milliseconds for the AI upstream service.", + "default": 60000 + }, + "https_verify": { + "type": "boolean", + "description": "Verify the TLS certificate of the AI upstream service.", + "default": true + }, + "max_request_body_size": { + "type": "integer", + "description": "max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8388608 + } + }, + "required": [ + "llm", + "prompt" + ] + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "model", + "paths": [ + "config.llm" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiSanitizer.json b/app/_schemas/ai-gateway/policies/AiSanitizer.json new file mode 100644 index 00000000000..06b517fd4a4 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiSanitizer.json @@ -0,0 +1,243 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "keepalive_timeout": { + "type": "number", + "description": "The keepalive timeout for the established http connnection", + "default": 60000 + }, + "sanitization_mode": { + "type": "string", + "enum": [ + "BOTH", + "INPUT", + "OUTPUT" + ], + "description": "The sanitization mode to use for the request", + "default": "INPUT" + }, + "anonymize": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "all", + "all_and_credentials", + "bank", + "credentials", + "creditcard", + "crypto", + "custom", + "date", + "domain", + "driverlicense", + "email", + "general", + "ip", + "medical", + "nationalid", + "nrp", + "passport", + "phone", + "ssn", + "url" + ] + }, + "description": "List of types to be anonymized", + "default": [ + "all_and_credentials" + ] + }, + "block_if_detected": { + "type": "boolean", + "description": "Whether to block requests containing PII data", + "default": false + }, + "skip_logging_sanitized_items": { + "type": "boolean", + "description": "Whether to log sanitized items in the Kong log plugins. Turn it on if you want to hide sensitive data from logs.", + "default": false + }, + "port": { + "type": "number", + "description": "The port of the sanitizer", + "default": 8080 + }, + "stop_on_error": { + "type": "boolean", + "description": "Stop processing if an error occurs.", + "default": true + }, + "recover_redacted": { + "type": "boolean", + "description": "Whether to recover redacted data. This doesn't apply to the redacted output.", + "default": true + }, + "redact_type": { + "type": "string", + "enum": [ + "placeholder", + "synthetic" + ], + "description": "What value to be used to redacted to", + "default": "placeholder" + }, + "proxy_config": { + "type": "object", + "properties": { + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + } + } + }, + "timeout": { + "type": "number", + "description": "Connection timeout with the sanitizer service.", + "default": 10000 + }, + "allow_all_conversation_history": { + "type": "boolean", + "description": "If false, will ignore all previous chat messages from the conversation history.", + "default": true + }, + "host": { + "type": "string", + "description": "The host of the sanitizer", + "default": "localhost" + }, + "scheme": { + "type": "string", + "description": "The protocol can be http and https", + "default": "http" + }, + "custom_patterns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "score": { + "type": "number", + "maximum": 1, + "minimum": 0, + "default": 0.5 + } + }, + "required": [ + "name", + "regex" + ] + }, + "minLength": 1, + "description": "List of custom patterns to be used for anonymization" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiSemanticCache.json b/app/_schemas/ai-gateway/policies/AiSemanticCache.json new file mode 100644 index 00000000000..279e49d13e9 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiSemanticCache.json @@ -0,0 +1,776 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "message_countback": { + "type": "number", + "maximum": 1000, + "minimum": 1, + "description": "Number of messages in the chat history to Vectorize/Cache", + "default": 1 + }, + "ignore_assistant_prompts": { + "type": "boolean", + "description": "Ignore and discard any assistant prompts when Vectorizing the request", + "default": false + }, + "cache_control": { + "type": "boolean", + "description": "When enabled, respect the Cache-Control behaviors defined in RFC7234.", + "default": false + }, + "exact_caching": { + "type": "boolean", + "description": "When enabled, a first check for exact query will be done. It will impact DB size", + "default": false + }, + "llm_format": { + "type": "string", + "enum": [ + "anthropic", + "bedrock", + "cohere", + "gemini", + "huggingface", + "openai" + ], + "description": "LLM input and output format and schema to use", + "default": "openai" + }, + "proxy_config": { + "type": "object", + "properties": { + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + } + } + }, + "ignore_system_prompts": { + "type": "boolean", + "description": "Ignore and discard any system prompts when Vectorizing the request", + "default": false + }, + "ignore_tool_prompts": { + "type": "boolean", + "description": "Ignore and discard any tool prompts when Vectorizing the request", + "default": false + }, + "stop_on_failure": { + "type": "boolean", + "description": "Halt the LLM request process in case of a caching system failure", + "default": false + }, + "cache_ttl": { + "type": "integer", + "description": "TTL in seconds of cache entities. Must be a value greater than 0.", + "default": 300 + }, + "embeddings": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "model": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Model name to execute." + }, + "options": { + "type": "object", + "properties": { + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + } + } + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "upstream_url": { + "type": "string", + "description": "upstream url for the embeddings" + }, + "azure": { + "type": "object", + "properties": { + "instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + }, + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + } + } + } + }, + "description": "Key/value settings for the model" + }, + "provider": { + "type": "string", + "enum": [ + "azure", + "bedrock", + "databricks", + "gemini", + "huggingface", + "mistral", + "ollama", + "openai", + "vercel" + ], + "description": "AI provider format to use for embeddings API" + } + }, + "required": [ + "name", + "provider" + ] + } + }, + "required": [ + "model" + ] + }, + "vectordb": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "pgvector", + "redis" + ], + "description": "which vector database driver to use" + }, + "dimensions": { + "type": "integer", + "description": "the desired dimensionality for the vectors" + }, + "threshold": { + "type": "number", + "description": "the default similarity threshold for accepting semantic search results (float). Higher threshold means more results are considered similar." + }, + "distance_metric": { + "type": "string", + "enum": [ + "cosine", + "euclidean" + ], + "description": "the distance metric to use for vector searches" + }, + "redis": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-encrypted": true, + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + } + } + }, + "pgvector": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "the host of the pgvector database", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "description": "the port of the pgvector database", + "default": 5432 + }, + "user": { + "type": "string", + "description": "the user of the pgvector database", + "default": "postgres", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "the password of the pgvector database", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "string", + "description": "the database of the pgvector database", + "default": "kong-pgvector" + }, + "timeout": { + "type": "number", + "description": "the timeout of the pgvector database", + "default": 5000 + }, + "ssl": { + "type": "boolean", + "description": "whether to use ssl for the pgvector database", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "whether to verify ssl for the pgvector database", + "default": true + }, + "ssl_required": { + "type": "boolean", + "description": "whether ssl is required for the pgvector database", + "default": false + }, + "ssl_version": { + "type": "string", + "enum": [ + "any", + "tlsv1_2", + "tlsv1_3" + ], + "description": "the ssl version to use for the pgvector database", + "default": "tlsv1_2" + }, + "ssl_cert": { + "type": "string", + "description": "the path of ssl cert to use for the pgvector database" + }, + "ssl_cert_key": { + "type": "string", + "description": "the path of ssl cert key to use for the pgvector database" + } + } + } + }, + "required": [ + "dimensions", + "distance_metric", + "strategy" + ] + } + }, + "required": [ + "embeddings", + "vectordb" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "embeddings", + "paths": [ + "config.embeddings" + ] + }, + { + "name": "vectordb", + "paths": [ + "config.vectordb" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiSemanticPromptGuard.json b/app/_schemas/ai-gateway/policies/AiSemanticPromptGuard.json new file mode 100644 index 00000000000..561150fe01b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiSemanticPromptGuard.json @@ -0,0 +1,779 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "vectordb": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "pgvector", + "redis" + ], + "description": "which vector database driver to use" + }, + "dimensions": { + "type": "integer", + "description": "the desired dimensionality for the vectors" + }, + "threshold": { + "type": "number", + "description": "the default similarity threshold for accepting semantic search results (float). Higher threshold means more results are considered similar." + }, + "distance_metric": { + "type": "string", + "enum": [ + "cosine", + "euclidean" + ], + "description": "the distance metric to use for vector searches" + }, + "redis": { + "type": "object", + "properties": { + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + } + } + }, + "pgvector": { + "type": "object", + "properties": { + "ssl_cert": { + "type": "string", + "description": "the path of ssl cert to use for the pgvector database" + }, + "host": { + "type": "string", + "description": "the host of the pgvector database", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "description": "the port of the pgvector database", + "default": 5432 + }, + "user": { + "type": "string", + "description": "the user of the pgvector database", + "default": "postgres", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "the password of the pgvector database", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "string", + "description": "the database of the pgvector database", + "default": "kong-pgvector" + }, + "ssl": { + "type": "boolean", + "description": "whether to use ssl for the pgvector database", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "whether to verify ssl for the pgvector database", + "default": true + }, + "ssl_cert_key": { + "type": "string", + "description": "the path of ssl cert key to use for the pgvector database" + }, + "timeout": { + "type": "number", + "description": "the timeout of the pgvector database", + "default": 5000 + }, + "ssl_required": { + "type": "boolean", + "description": "whether ssl is required for the pgvector database", + "default": false + }, + "ssl_version": { + "type": "string", + "enum": [ + "any", + "tlsv1_2", + "tlsv1_3" + ], + "description": "the ssl version to use for the pgvector database", + "default": "tlsv1_2" + } + } + } + }, + "required": [ + "dimensions", + "distance_metric", + "strategy" + ] + }, + "proxy_config": { + "type": "object", + "properties": { + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + } + } + }, + "search": { + "type": "object", + "properties": { + "threshold": { + "type": "number", + "description": "Threshold for the similarity score to be considered a match.", + "default": 0.5 + } + } + }, + "rules": { + "type": "object", + "properties": { + "match_all_conversation_history": { + "type": "boolean", + "description": "If false, will ignore all previous chat prompts from the conversation history.", + "default": false + }, + "allow_prompts": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 100, + "description": "List of prompts to allow." + }, + "deny_prompts": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 100, + "description": "List of prompts to deny." + }, + "match_all_roles": { + "type": "boolean", + "description": "If true, will match all roles in addition to 'user' role in conversation history.", + "default": false + } + } + }, + "genai_category": { + "type": "string", + "enum": [ + "audio/speech", + "audio/transcription", + "image/generation", + "realtime/generation", + "text/embeddings", + "text/generation" + ], + "description": "Generative AI category of the request", + "default": "text/generation" + }, + "embeddings": { + "type": "object", + "properties": { + "model": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Model name to execute." + }, + "options": { + "type": "object", + "properties": { + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + } + } + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + }, + "upstream_url": { + "type": "string", + "description": "upstream url for the embeddings" + }, + "azure": { + "type": "object", + "properties": { + "instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + } + } + } + }, + "description": "Key/value settings for the model" + }, + "provider": { + "type": "string", + "enum": [ + "azure", + "bedrock", + "databricks", + "gemini", + "huggingface", + "mistral", + "ollama", + "openai", + "vercel" + ], + "description": "AI provider format to use for embeddings API" + } + }, + "required": [ + "name", + "provider" + ] + }, + "auth": { + "type": "object", + "properties": { + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + } + } + } + }, + "required": [ + "model" + ] + } + }, + "required": [ + "embeddings", + "vectordb" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "embeddings", + "paths": [ + "config.embeddings" + ] + }, + { + "name": "vectordb", + "paths": [ + "config.vectordb" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AiSemanticResponseGuard.json b/app/_schemas/ai-gateway/policies/AiSemanticResponseGuard.json new file mode 100644 index 00000000000..979493bac82 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AiSemanticResponseGuard.json @@ -0,0 +1,787 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "vectordb": { + "type": "object", + "properties": { + "distance_metric": { + "type": "string", + "enum": [ + "cosine", + "euclidean" + ], + "description": "the distance metric to use for vector searches" + }, + "redis": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + } + } + }, + "pgvector": { + "type": "object", + "properties": { + "user": { + "type": "string", + "description": "the user of the pgvector database", + "default": "postgres", + "x-referenceable": true + }, + "database": { + "type": "string", + "description": "the database of the pgvector database", + "default": "kong-pgvector" + }, + "timeout": { + "type": "number", + "description": "the timeout of the pgvector database", + "default": 5000 + }, + "ssl": { + "type": "boolean", + "description": "whether to use ssl for the pgvector database", + "default": false + }, + "ssl_required": { + "type": "boolean", + "description": "whether ssl is required for the pgvector database", + "default": false + }, + "ssl_version": { + "type": "string", + "enum": [ + "any", + "tlsv1_2", + "tlsv1_3" + ], + "description": "the ssl version to use for the pgvector database", + "default": "tlsv1_2" + }, + "host": { + "type": "string", + "description": "the host of the pgvector database", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "description": "the port of the pgvector database", + "default": 5432 + }, + "password": { + "type": "string", + "description": "the password of the pgvector database", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl_verify": { + "type": "boolean", + "description": "whether to verify ssl for the pgvector database", + "default": true + }, + "ssl_cert": { + "type": "string", + "description": "the path of ssl cert to use for the pgvector database" + }, + "ssl_cert_key": { + "type": "string", + "description": "the path of ssl cert key to use for the pgvector database" + } + } + }, + "strategy": { + "type": "string", + "enum": [ + "pgvector", + "redis" + ], + "description": "which vector database driver to use" + }, + "dimensions": { + "type": "integer", + "description": "the desired dimensionality for the vectors" + }, + "threshold": { + "type": "number", + "description": "the default similarity threshold for accepting semantic search results (float). Higher threshold means more results are considered similar." + } + }, + "required": [ + "dimensions", + "distance_metric", + "strategy" + ] + }, + "proxy_config": { + "type": "object", + "properties": { + "no_proxy": { + "type": "string", + "description": "Comma-separated list of hosts that should not be proxied." + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "search": { + "type": "object", + "properties": { + "threshold": { + "type": "number", + "description": "Threshold for the similarity score to be considered a match.", + "default": 0.5 + } + } + }, + "rules": { + "type": "object", + "properties": { + "allow_responses": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 100, + "description": "List of responses to allow." + }, + "deny_responses": { + "type": "array", + "items": { + "type": "string", + "maxLength": 500, + "minLength": 1 + }, + "maxLength": 100, + "description": "List of responses to deny." + }, + "max_response_body_size": { + "type": "integer", + "description": "Max allowed body size allowed to be introspected. 0 means unlimited, but the size of this body will still be limited by Nginx's client_max_body_size.", + "default": 8192 + } + } + }, + "llm_format": { + "type": "string", + "enum": [ + "anthropic", + "bedrock", + "cohere", + "gemini", + "huggingface", + "openai" + ], + "description": "LLM input and output format and schema to use", + "default": "openai" + }, + "genai_category": { + "type": "string", + "enum": [ + "audio/speech", + "audio/transcription", + "image/generation", + "realtime/generation", + "text/embeddings", + "text/generation" + ], + "description": "Generative AI category of the request", + "default": "text/generation" + }, + "embeddings": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "param_value": { + "type": "string", + "description": "Specify the full parameter value for 'param_name'.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_use_service_account": { + "type": "boolean", + "description": "Use service account auth for GCP-based providers and models.", + "default": false + }, + "aws_access_key_id": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_ACCESS_KEY_ID environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_metadata_url": { + "type": "string", + "description": "Custom metadata URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google metadata endpoint.", + "x-referenceable": true + }, + "param_name": { + "type": "string", + "description": "If AI model requires authentication via query parameter, specify its name here.", + "x-referenceable": true + }, + "azure_client_secret": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the tenant ID.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "Set this field to the full JSON of the GCP service account to authenticate, if required. If null (and gcp_use_service_account is true), Kong will attempt to read from environment variable `GCP_SERVICE_ACCOUNT`.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_oauth_token_url": { + "type": "string", + "description": "Custom OAuth token URL for GCP authentication. Useful for restricted network environments or custom GCP endpoints. If null, Kong will use the default Google OAuth token endpoint.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "Set this if you are using an AWS provider (Bedrock) and you are authenticating using static IAM User credentials. Setting this will override the AWS_SECRET_ACCESS_KEY environment variable for this plugin instance.", + "x-referenceable": true, + "x-encrypted": true + }, + "header_name": { + "type": "string", + "description": "If AI model requires authentication via Authorization or API key header, specify its name here.", + "x-referenceable": true + }, + "header_value": { + "type": "string", + "description": "Specify the full auth header value for 'header_name', for example 'Bearer key' or just 'key'.", + "x-referenceable": true, + "x-encrypted": true + }, + "param_location": { + "type": "string", + "enum": [ + "body", + "query" + ], + "description": "Specify whether the 'param_name' and 'param_value' options go in a query string, or the POST form/JSON body." + }, + "azure_use_managed_identity": { + "type": "boolean", + "description": "Set true to use the Azure Cloud Managed Identity (or user-assigned identity) to authenticate with Azure-provider models.", + "default": false + }, + "azure_client_id": { + "type": "string", + "description": "If azure_use_managed_identity is set to true, and you need to use a different user-assigned identity for this LLM instance, set the client ID.", + "x-referenceable": true + }, + "allow_override": { + "type": "boolean", + "description": "If enabled, the authorization header or parameter can be overridden in the request by the value configured in the plugin.", + "default": false + } + } + }, + "model": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Model name to execute." + }, + "options": { + "type": "object", + "properties": { + "upstream_url": { + "type": "string", + "description": "upstream url for the embeddings" + }, + "azure": { + "type": "object", + "properties": { + "instance": { + "type": "string", + "description": "Instance name for Azure OpenAI hosted models." + }, + "api_version": { + "type": "string", + "description": "'api-version' for Azure OpenAI instances.", + "default": "2023-05-15" + }, + "deployment_id": { + "type": "string", + "description": "Deployment ID for Azure OpenAI instances." + } + } + }, + "bedrock": { + "type": "object", + "properties": { + "aws_region": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can override the `AWS_REGION` environment variable by setting this option." + }, + "aws_assume_role_arn": { + "type": "string", + "description": "If using AWS providers (Bedrock) you can assume a different role after authentication with the current IAM context is successful." + }, + "aws_role_session_name": { + "type": "string", + "description": "If using AWS providers (Bedrock), set the identifier of the assumed role session." + }, + "embeddings_normalize": { + "type": "boolean", + "description": "If using AWS providers (Bedrock), set to true to normalize the embeddings.", + "default": false + }, + "performance_config_latency": { + "type": "string", + "description": "Force the client's performance configuration 'latency' for all requests. Leave empty to let the consumer select the performance configuration." + }, + "video_output_s3_uri": { + "type": "string", + "description": "S3 URI (s3://bucket/prefix) where Bedrock will store generated video files. Required for video generation." + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "If using AWS providers (Bedrock), override the STS endpoint URL when assuming a different role." + }, + "batch_bucket_prefix": { + "type": "string", + "description": "S3 URI prefix (s3://bucket/prefix/) where Bedrock will get input files from and store results to for native batch API." + }, + "batch_role_arn": { + "type": "string", + "description": "AWS role arn used for calling batch API. Try to get the value from request if ommited." + } + } + }, + "gemini": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string", + "description": "If running Gemini on Vertex, specify the regional API endpoint (hostname only)." + }, + "project_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the project ID." + }, + "location_id": { + "type": "string", + "description": "If running Gemini on Vertex, specify the location ID." + } + } + }, + "huggingface": { + "type": "object", + "properties": { + "use_cache": { + "type": "boolean", + "description": "Use the cache layer on the inference API" + }, + "wait_for_model": { + "type": "boolean", + "description": "Wait for the model if it is not ready" + } + } + }, + "databricks": { + "type": "object", + "properties": { + "workspace_instance_id": { + "type": "string", + "description": "Workspace Instance ID ('dbc-xxx-yyy') for Databricks model serving." + } + } + } + }, + "description": "Key/value settings for the model" + }, + "provider": { + "type": "string", + "enum": [ + "azure", + "bedrock", + "databricks", + "gemini", + "huggingface", + "mistral", + "ollama", + "openai", + "vercel" + ], + "description": "AI provider format to use for embeddings API" + } + }, + "required": [ + "name", + "provider" + ] + } + }, + "required": [ + "model" + ] + } + }, + "required": [ + "embeddings", + "vectordb" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "embeddings", + "paths": [ + "config.embeddings" + ] + }, + { + "name": "vectordb", + "paths": [ + "config.vectordb" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AppDynamics.json b/app/_schemas/ai-gateway/policies/AppDynamics.json new file mode 100644 index 00000000000..ca0b73d0e7b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AppDynamics.json @@ -0,0 +1,57 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "additionalProperties": true + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AwsLambda.json b/app/_schemas/ai-gateway/policies/AwsLambda.json new file mode 100644 index 00000000000..0b890808e6e --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AwsLambda.json @@ -0,0 +1,223 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "awsgateway_compatible_payload_version": { + "type": "string", + "enum": [ + "1.0", + "2.0" + ], + "description": "An optional value that defines which version will be used to generate the AWS API Gateway compatible payload. The default will be `1.0`.", + "default": "1.0" + }, + "skip_large_bodies": { + "type": "boolean", + "description": "An optional value that defines whether Kong should send large bodies that are buffered to disk", + "default": true + }, + "aws_sts_endpoint_url": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "log_type": { + "type": "string", + "enum": [ + "None", + "Tail" + ], + "description": "The LogType to use when invoking the function. By default, None and Tail are supported.", + "default": "Tail" + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "disable_https": { + "type": "boolean", + "default": false + }, + "awsgateway_compatible": { + "type": "boolean", + "description": "An optional value that defines whether the plugin should wrap requests into the Amazon API gateway.", + "default": false + }, + "aws_region": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 443 + }, + "forward_request_uri": { + "type": "boolean", + "description": "An optional value that defines whether the original HTTP request URI is sent in the request_uri field of the JSON-encoded request.", + "default": false + }, + "forward_request_body": { + "type": "boolean", + "description": "An optional value that defines whether the request body is sent in the request_body field of the JSON-encoded request. If the body arguments can be parsed, they are sent in the separate request_body_args field of the request. ", + "default": false + }, + "proxy_url": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "base64_encode_body": { + "type": "boolean", + "description": "An optional value that Base64-encodes the request body.", + "default": true + }, + "function_name": { + "type": "string", + "description": "The AWS Lambda function to invoke. Both function name and function ARN (including partial) are supported." + }, + "unhandled_status": { + "type": "integer", + "maximum": 999, + "minimum": 100, + "description": "The response status code to use (instead of the default 200, 202, or 204) in the case of an Unhandled Function Error." + }, + "aws_imds_protocol_version": { + "type": "string", + "enum": [ + "v1", + "v2" + ], + "description": "Identifier to select the IMDS protocol version to use: `v1` or `v2`.", + "default": "v1" + }, + "aws_role_session_name": { + "type": "string", + "description": "The identifier of the assumed role session.", + "default": "kong" + }, + "forward_request_headers": { + "type": "boolean", + "description": "An optional value that defines whether the original HTTP request headers are sent as a map in the request_headers field of the JSON-encoded request.", + "default": false + }, + "keepalive": { + "type": "number", + "description": "An optional value in milliseconds that defines how long an idle connection lives before being closed.", + "default": 60000 + }, + "qualifier": { + "type": "string", + "description": "The qualifier to use when invoking the function." + }, + "invocation_type": { + "type": "string", + "enum": [ + "DryRun", + "Event", + "RequestResponse" + ], + "description": "The InvocationType to use when invoking the function. Available types are RequestResponse, Event, DryRun.", + "default": "RequestResponse" + }, + "forward_request_method": { + "type": "boolean", + "description": "An optional value that defines whether the original HTTP request method verb is sent in the request_method field of the JSON-encoded request.", + "default": false + }, + "empty_arrays_mode": { + "type": "string", + "enum": [ + "correct", + "legacy" + ], + "description": "An optional value that defines whether Kong should send empty arrays (returned by Lambda function) as `[]` arrays or `{}` objects in JSON responses. The value `legacy` means Kong will send empty arrays as `{}` objects in response", + "default": "legacy" + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when invoking the function.", + "default": 60000 + }, + "is_proxy_integration": { + "type": "boolean", + "description": "An optional value that defines whether the response format to receive from the Lambda to this format.", + "default": false + }, + "aws_key": { + "type": "string", + "description": "The AWS key credential to be used when invoking the function.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret": { + "type": "string", + "description": "The AWS secret credential to be used when invoking the function. ", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The target AWS IAM role ARN used to invoke the Lambda function.", + "x-encrypted": true, + "x-referenceable": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Set to `true` to verify the TLS certificate when connecting to AWS services.", + "default": true + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/AzureFunctions.json b/app/_schemas/ai-gateway/policies/AzureFunctions.json new file mode 100644 index 00000000000..22be2d00a23 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/AzureFunctions.json @@ -0,0 +1,122 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "clientid": { + "type": "string", + "description": "The `clientid` to access the Azure resources. If provided, it is injected as the `x-functions-clientid` header.", + "x-referenceable": true, + "x-encrypted": true + }, + "hostdomain": { + "type": "string", + "description": "The domain where the function resides.", + "default": "azurewebsites.net" + }, + "routeprefix": { + "type": "string", + "description": "Route prefix to use.", + "default": "api" + }, + "functionname": { + "type": "string", + "description": "Name of the Azure function to invoke." + }, + "timeout": { + "type": "number", + "description": "Timeout in milliseconds before closing a connection to the Azure Functions server.", + "default": 600000 + }, + "keepalive": { + "type": "number", + "description": "Time in milliseconds during which an idle connection to the Azure Functions server lives before being closed.", + "default": 60000 + }, + "https": { + "type": "boolean", + "description": "Use of HTTPS to connect with the Azure Functions server.", + "default": true + }, + "https_verify": { + "type": "boolean", + "description": "Set to `true` to authenticate the Azure Functions server.", + "default": true + }, + "apikey": { + "type": "string", + "description": "The apikey to access the Azure resources. If provided, it is injected as the `x-functions-key` header.", + "x-referenceable": true, + "x-encrypted": true + }, + "appname": { + "type": "string", + "description": "The Azure app name." + } + }, + "required": [ + "appname", + "functionname" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/BasicAuth.json b/app/_schemas/ai-gateway/policies/BasicAuth.json new file mode 100644 index 00000000000..68c252cb53f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/BasicAuth.json @@ -0,0 +1,236 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "anonymous": { + "type": "string", + "description": "An optional string (Consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request will fail with an authentication failure `4xx`. Please note that this value must refer to the Consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the `Authorization` header) before proxying it.", + "default": true + }, + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value.", + "default": "service" + }, + "brute_force_protection": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "cluster", + "memory", + "off", + "redis" + ], + "description": "The brute force protection strategy to use for retrieving and incrementing the limits. Available values are: `cluster`, `redis`, `memory`, and `off`.", + "default": "off" + }, + "redis": { + "type": "object", + "properties": { + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + } + }, + "description": "Redis configuration" + } + } + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "x-supported-partials": [ + { + "name": "redis-ce", + "paths": [ + "config.brute_force_protection.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/BotDetection.json b/app/_schemas/ai-gateway/policies/BotDetection.json new file mode 100644 index 00000000000..72892349540 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/BotDetection.json @@ -0,0 +1,64 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of regular expressions that should be allowed. The regular expressions will be checked against the `User-Agent` header.", + "default": [] + }, + "deny": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of regular expressions that should be denied. The regular expressions will be checked against the `User-Agent` header.", + "default": [] + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Canary.json b/app/_schemas/ai-gateway/policies/Canary.json new file mode 100644 index 00000000000..969762851eb --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Canary.json @@ -0,0 +1,117 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "duration": { + "type": "number", + "description": "The duration of the canary release in seconds.", + "default": 3600 + }, + "upstream_fallback": { + "type": "boolean", + "description": "Specifies whether to fallback to the upstream server if the canary release fails.", + "default": false + }, + "groups": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The groups allowed to access the canary release." + }, + "start": { + "type": "number", + "description": "Future time in seconds since epoch, when the canary release will start. Ignored when `percentage` is set, or when using `allow` or `deny` in `hash`." + }, + "steps": { + "type": "number", + "minimum": 1, + "description": "The number of steps for the canary release.", + "default": 1000 + }, + "percentage": { + "type": "number", + "maximum": 100, + "minimum": 0, + "description": "The percentage of traffic to be routed to the canary release." + }, + "upstream_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "upstream_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "upstream_uri": { + "type": "string", + "minLength": 1, + "description": "The URI of the upstream server to be used for the canary release." + }, + "canary_by_header_name": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "hash": { + "type": "string", + "enum": [ + "allow", + "consumer", + "deny", + "header", + "ip", + "none" + ], + "description": "Hash algorithm to be used for canary release.\n\n* `consumer`: The hash will be based on the consumer.\n* `ip`: The hash will be based on the client IP address.\n* `none`: No hash will be applied.\n* `allow`: Allows the specified groups to access the canary release.\n* `deny`: Denies the specified groups from accessing the canary release.\n* `header`: The hash will be based on the specified header value.", + "default": "consumer" + }, + "hash_header": { + "type": "string", + "description": "A string representing an HTTP header name." + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Confluent.json b/app/_schemas/ai-gateway/policies/Confluent.json new file mode 100644 index 00000000000..ab5cd5a4013 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Confluent.json @@ -0,0 +1,469 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "producer_async_buffering_limits_messages_in_memory": { + "type": "integer", + "description": "Maximum number of messages that can be buffered in memory in asynchronous mode.", + "default": 50000 + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "oauth2": { + "type": "object", + "properties": { + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + } + } + }, + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "username": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + } + } + }, + "value_schema": { + "type": "object", + "properties": { + "subject_name": { + "type": "string", + "description": "The name of the subject" + }, + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + } + } + }, + "key_schema": { + "type": "object", + "properties": { + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + }, + "subject_name": { + "type": "string", + "description": "The name of the subject" + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + } + } + } + }, + "description": "The plugin-global schema registry configuration. This can be overwritten by the topic configuration." + }, + "cluster_api_secret": { + "type": "string", + "description": "Password/ApiSecret for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "forward_headers": { + "type": "boolean", + "description": "Include the request headers in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "producer_request_acks": { + "type": "integer", + "enum": [ + -1, + 0, + 1 + ], + "description": "The number of acknowledgments the producer requires the leader to have received before considering a request complete. Allowed values: 0 for no acknowledgments; 1 for only the leader; and -1 for the full ISR (In-Sync Replica set).", + "default": 1 + }, + "producer_request_limits_bytes_per_request": { + "type": "integer", + "description": "Maximum size of a Produce request in bytes.", + "default": 1048576 + }, + "producer_request_timeout": { + "type": "integer", + "description": "Time to wait for a Produce response in milliseconds.", + "default": 2000 + }, + "producer_request_limits_messages_per_request": { + "type": "integer", + "description": "Maximum number of messages to include into a single producer request.", + "default": 200 + }, + "confluent_cloud_api_key": { + "type": "string", + "description": "Apikey for authentication with Confluent Cloud. This allows for management tasks such as creating topics, ACLs, etc.", + "x-encrypted": true, + "x-referenceable": true + }, + "producer_request_retries_max_attempts": { + "type": "integer", + "description": "Maximum number of retry attempts per single Produce request.", + "default": 10 + }, + "allowed_topics": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of allowed topic names to which messages can be sent. The default topic configured in the `topic` field is always allowed, regardless of its inclusion in `allowed_topics`." + }, + "timeout": { + "type": "integer", + "description": "Socket timeout in milliseconds.", + "default": 10000 + }, + "cluster_name": { + "type": "string", + "description": "An identifier for the Kafka cluster. By default, this field generates a random string. You can also set your own custom cluster identifier. If more than one Kafka plugin is configured without a `cluster_name` (that is, if the default autogenerated value is removed), these plugins will use the same producer, and by extension, the same cluster. Logs will be sent to the leader of the cluster." + }, + "producer_request_retries_backoff_timeout": { + "type": "integer", + "description": "Backoff interval between retry attempts in milliseconds.", + "default": 100 + }, + "topics_query_arg": { + "type": "string", + "description": "The request query parameter name that contains the topics to publish to" + }, + "key_query_arg": { + "type": "string", + "description": "The request query parameter name that contains the Kafka message key. If specified, messages with the same key will be sent to the same Kafka partition, ensuring consistent ordering." + }, + "keepalive": { + "type": "integer", + "description": "Keepalive timeout in milliseconds.", + "default": 60000 + }, + "keepalive_enabled": { + "type": "boolean", + "default": false + }, + "cluster_api_key": { + "type": "string", + "description": "Username/Apikey for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "security": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Enables verification of the certificate presented by the server.", + "default": true + } + } + }, + "producer_async_flush_timeout": { + "type": "integer", + "description": "Maximum time interval in milliseconds between buffer flushes in asynchronous mode.", + "default": 1000 + }, + "producer_async": { + "type": "boolean", + "description": "Flag to enable asynchronous mode.", + "default": true + }, + "confluent_cloud_api_secret": { + "type": "string", + "description": "The corresponding secret for the Confluent Cloud API key.", + "x-referenceable": true, + "x-encrypted": true + }, + "forward_method": { + "type": "boolean", + "description": "Include the request method in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "forward_uri": { + "type": "boolean", + "description": "Include the request URI and URI arguments (as in, query arguments) in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "forward_body": { + "type": "boolean", + "description": "Include the request body in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": true + }, + "message_by_lua_functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates the message being sent to the Kafka topic." + }, + "bootstrap_servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + }, + "required": [ + "host", + "port" + ] + }, + "description": "Set of bootstrap brokers in a `{host: host, port: port}` list format." + }, + "topic": { + "type": "string", + "description": "The default Kafka topic to publish to if the query parameter defined in the `topics_query_arg` does not exist in the request" + } + }, + "required": [ + "cluster_api_key", + "cluster_api_secret", + "topic" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ConfluentConsume.json b/app/_schemas/ai-gateway/policies/ConfluentConsume.json new file mode 100644 index 00000000000..28541c3456f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ConfluentConsume.json @@ -0,0 +1,630 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "cluster_api_key": { + "type": "string", + "description": "Username/Apikey for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "confluent_cloud_api_secret": { + "type": "string", + "description": "The corresponding secret for the Confluent Cloud API key.", + "x-referenceable": true, + "x-encrypted": true + }, + "security": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Enables verification of the certificate presented by the server.", + "default": true + } + } + }, + "message_by_lua_functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates the message being sent to the client." + }, + "bootstrap_servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + } + }, + "required": [ + "host", + "port" + ] + }, + "description": "Set of bootstrap brokers in a `{host: host, port: port}` list format." + }, + "keepalive_enabled": { + "type": "boolean", + "default": false + }, + "cluster_api_secret": { + "type": "string", + "description": "Password/ApiSecret for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + }, + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "oauth2_client": { + "type": "object", + "properties": { + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + } + } + }, + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "username": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + } + }, + "required": [ + "token_endpoint" + ] + } + } + } + } + } + }, + "description": "The plugin-global schema registry configuration." + }, + "mode": { + "type": "string", + "enum": [ + "http-get", + "server-sent-events", + "websocket" + ], + "description": "The mode of operation for the plugin.", + "default": "http-get" + }, + "message_deserializer": { + "type": "string", + "enum": [ + "json", + "noop" + ], + "description": "The deserializer to use for the consumed messages.", + "default": "noop" + }, + "enforce_latest_offset_reset": { + "type": "boolean", + "description": "When true, 'latest' offset reset behaves correctly (starts from end). When false (default), maintains backwards compatibility where 'latest' acts like 'earliest'.", + "default": false + }, + "commit_strategy": { + "type": "string", + "enum": [ + "auto", + "off" + ], + "description": "The strategy to use for committing offsets.", + "default": "auto" + }, + "timeout": { + "type": "integer", + "description": "Socket timeout in milliseconds.", + "default": 10000 + }, + "keepalive": { + "type": "integer", + "description": "Keepalive timeout in milliseconds.", + "default": 60000 + }, + "topics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + }, + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "username": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + }, + "password": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-encrypted": true, + "x-referenceable": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + } + } + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + } + } + } + }, + "description": "The plugin-global schema registry configuration." + }, + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minLength": 1, + "description": "The Kafka topics and their configuration you want to consume from." + }, + "auto_offset_reset": { + "type": "string", + "enum": [ + "earliest", + "latest" + ], + "description": "The offset to start from when there is no initial offset in the consumer group.", + "default": "earliest" + }, + "confluent_cloud_api_key": { + "type": "string", + "description": "Apikey for authentication with Confluent Cloud. This allows for management tasks such as creating topics, ACLs, etc.", + "x-encrypted": true, + "x-referenceable": true + }, + "cluster_name": { + "type": "string", + "description": "An identifier for the Kafka cluster. By default, this field generates a random string. You can also set your own custom cluster identifier. If more than one Kafka plugin is configured without a `cluster_name` (that is, if the default autogenerated value is removed), these plugins will use the same producer, and by extension, the same cluster. Logs will be sent to the leader of the cluster." + }, + "enable_dlq": { + "type": "boolean", + "description": "Enables Dead Letter Queue. When enabled, if the message doesn't conform to the schema (from Schema Registry) or there's an error in the `message_by_lua_functions`, it will be forwarded to `dlq_topic` that can be processed later." + }, + "dlq_topic": { + "type": "string", + "description": "The topic to use for the Dead Letter Queue." + } + }, + "required": [ + "cluster_api_key", + "cluster_api_secret", + "topics" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/CorrelationId.json b/app/_schemas/ai-gateway/policies/CorrelationId.json new file mode 100644 index 00000000000..2072bb5e479 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/CorrelationId.json @@ -0,0 +1,78 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "header_name": { + "type": "string", + "description": "The HTTP header name to use for the correlation ID.", + "default": "Kong-Request-ID" + }, + "generator": { + "type": "string", + "enum": [ + "tracker", + "uuid", + "uuid#counter" + ], + "description": "The generator to use for the correlation ID. Accepted values are `uuid`, `uuid#counter`, and `tracker`. See [Generators](#generators).", + "default": "uuid#counter" + }, + "echo_downstream": { + "type": "boolean", + "description": "Whether to echo the header back to downstream (the client).", + "default": false + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Cors.json b/app/_schemas/ai-gateway/policies/Cors.json new file mode 100644 index 00000000000..f67b5b5f82c --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Cors.json @@ -0,0 +1,123 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "origins": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed domains for the `Access-Control-Allow-Origin` header. If you want to allow all origins, add `*` as a single value to this configuration field. The accepted values can either be flat strings or PCRE regexes. NOTE: If you don't specify any allowed domains, all origins are allowed." + }, + "methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ] + }, + "description": "'Value for the `Access-Control-Allow-Methods` header. Available options include `GET`, `HEAD`, `PUT`, `PATCH`, `POST`, `DELETE`, `OPTIONS`, `TRACE`, `CONNECT`. By default, all options are allowed.'", + "default": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ] + }, + "allow_origin_absent": { + "type": "boolean", + "description": "A boolean value that skip cors response headers when origin header of request is empty", + "default": true + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Value for the `Access-Control-Allow-Headers` header." + }, + "exposed_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Value for the `Access-Control-Expose-Headers` header. If not specified, no custom headers are exposed." + }, + "max_age": { + "type": "number", + "description": "Indicates how long the results of the preflight request can be cached, in `seconds`." + }, + "credentials": { + "type": "boolean", + "description": "Flag to determine whether the `Access-Control-Allow-Credentials` header should be sent with `true` as the value.", + "default": false + }, + "private_network": { + "type": "boolean", + "description": "Flag to determine whether the `Access-Control-Allow-Private-Network` header should be sent with `true` as the value.", + "default": false + }, + "preflight_continue": { + "type": "boolean", + "description": "A boolean value that instructs the plugin to proxy the `OPTIONS` preflight request to the Upstream service.", + "default": false + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Datadog.json b/app/_schemas/ai-gateway/policies/Datadog.json new file mode 100644 index 00000000000..1e88c4b6241 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Datadog.json @@ -0,0 +1,232 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 8125 + }, + "route_name_tag": { + "type": "string", + "description": "String to be attached as tag of the route name or ID." + }, + "retry_count": { + "type": "integer", + "description": "Number of times to retry when sending data to the upstream server." + }, + "metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": [ + "kong_latency", + "latency", + "request_count", + "request_size", + "response_size", + "upstream_latency" + ], + "description": "Datadog metric’s name" + }, + "stat_type": { + "type": "string", + "enum": [ + "counter", + "distribution", + "gauge", + "histogram", + "meter", + "set", + "timer" + ], + "description": "Determines what sort of event the metric represents" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of tags" + }, + "sample_rate": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Sampling rate" + }, + "consumer_identifier": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ], + "description": "Authenticated user detail" + } + }, + "required": [ + "name", + "stat_type" + ] + }, + "description": "List of metrics to be logged." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "localhost", + "x-referenceable": true + }, + "prefix": { + "type": "string", + "description": "String to be attached as a prefix to a metric's name.", + "default": "kong" + }, + "service_name_tag": { + "type": "string", + "description": "String to be attached as the name of the service.", + "default": "name" + }, + "status_tag": { + "type": "string", + "description": "String to be attached as the tag of the HTTP status.", + "default": "status" + }, + "consumer_tag": { + "type": "string", + "description": "String to be attached as tag of the consumer.", + "default": "consumer" + }, + "queue_size": { + "type": "integer", + "description": "Maximum number of log entries to be sent on each message to the upstream server." + }, + "flush_timeout": { + "type": "number", + "description": "Optional time in seconds. If `queue_size` \u003e 1, this is the max idle time before sending a log with less than `queue_size` records." + }, + "queue": { + "type": "object", + "properties": { + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + }, + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + }, + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + } + } + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Datakit.json b/app/_schemas/ai-gateway/policies/Datakit.json new file mode 100644 index 00000000000..adc19897170 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Datakit.json @@ -0,0 +1,1327 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "nodes": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "branch" + ], + "x-terraform-transform-const": true + }, + "else": { + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`." + }, + "maxLength": 64, + "minLength": 1, + "description": "nodes to execute if the input condition is `false`" + }, + "then": { + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`." + }, + "maxLength": 64, + "minLength": 1, + "description": "nodes to execute if the input condition is `true`" + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "branch node input" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "branch node output" + }, + "outputs": { + "type": "object", + "properties": { + "else": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "node output" + }, + "then": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "node output" + } + }, + "description": "branch node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + } + }, + "title": "branch", + "description": "Execute different nodes based on some input condition" + }, + { + "type": "object", + "properties": { + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "cache node input" + }, + "inputs": { + "type": "object", + "properties": { + "data": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The data to be cached." + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The cache key." + }, + "ttl": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The TTL in seconds." + } + }, + "description": "cache node inputs" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "cache node output" + }, + "outputs": { + "type": "object", + "properties": { + "data": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The data that was cached." + }, + "hit": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Signals a cache hit." + }, + "miss": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Signals a cache miss." + }, + "stored": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Signals whether data was stored in cache." + } + }, + "description": "cache node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "cache" + ], + "x-terraform-transform-const": true + }, + "bypass_on_error": { + "type": "boolean" + }, + "ttl": { + "type": "integer" + } + }, + "title": "cache", + "description": "Fetch cached data" + }, + { + "type": "object", + "properties": { + "ssl_server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS." + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the TLS certificate when making HTTPS requests.", + "default": true + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2." + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "call node input" + }, + "inputs": { + "type": "object", + "properties": { + "proxy_auth_password": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication." + }, + "proxy_auth_username": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication." + }, + "query": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP request query" + }, + "url": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP request URL" + }, + "body": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP request body" + }, + "headers": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP request headers" + }, + "http_proxy": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The HTTP proxy URL. This proxy server will be used for HTTP requests." + }, + "https_proxy": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The HTTPS proxy URL. This proxy server will be used for HTTPS requests." + } + }, + "description": "call node inputs" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "call node output" + }, + "method": { + "type": "string", + "maxLength": 32, + "minLength": 1, + "description": "A string representing an HTTP method, such as GET, POST, PUT, or DELETE. The string must contain only uppercase letters.", + "default": "GET" + }, + "url": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "outputs": { + "type": "object", + "properties": { + "body": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP response body" + }, + "headers": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP response headers" + }, + "raw_body": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The raw, non-decoded HTTP response body" + }, + "status": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP response status code" + } + }, + "description": "call node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "call" + ], + "x-terraform-transform-const": true + } + }, + "title": "call", + "description": "Make an external HTTP request" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "exit" + ], + "x-terraform-transform-const": true + }, + "status": { + "type": "integer", + "maximum": 599, + "minimum": 200, + "description": "HTTP status code", + "default": 200 + }, + "warn_headers_sent": { + "type": "boolean" + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "exit node input" + }, + "inputs": { + "type": "object", + "properties": { + "headers": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP response headers" + }, + "body": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "HTTP response body" + } + }, + "description": "exit node inputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + } + }, + "title": "exit", + "description": "Terminate the request and send a response to the client" + }, + { + "type": "object", + "properties": { + "jq": { + "type": "string", + "maxLength": 10240, + "minLength": 1, + "description": "The jq filter text. Refer to https://jqlang.org/manual/ for full documentation." + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "filter input(s)" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "description": "filter input(s)" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "filter output(s)" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "jq" + ], + "x-terraform-transform-const": true + } + }, + "title": "jq", + "required": [ + "jq" + ], + "description": "Process data using `jq` syntax" + }, + { + "type": "object", + "properties": { + "attributes_block_name": { + "type": "string", + "maxLength": 32, + "minLength": 1 + }, + "attributes_name_prefix": { + "type": "string", + "maxLength": 32, + "minLength": 1 + }, + "text_block_name": { + "type": "string", + "maxLength": 32, + "minLength": 1, + "description": "The name of the block to treat as XML text content.", + "default": "#text" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "description": "JSON string or table" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "XML document converted from JSON" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "json_to_xml" + ], + "x-terraform-transform-const": true + }, + "root_element_name": { + "type": "string", + "maxLength": 64, + "minLength": 1 + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JSON string or table" + } + }, + "title": "json_to_xml", + "description": "transform JSON or lua table to XML" + }, + { + "type": "object", + "properties": { + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JWT token (with or without Bearer prefix)" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "jwt_decode node output" + }, + "outputs": { + "type": "object", + "properties": { + "header": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Decoded JWT header (alg, kid, typ)" + }, + "payload": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Decoded JWT payload (claims)" + }, + "signature": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Raw signature (base64url encoded)" + } + }, + "description": "jwt_decode node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "jwt_decode" + ], + "x-terraform-transform-const": true + } + }, + "title": "jwt_decode", + "description": "Decode JWT without signature verification" + }, + { + "type": "object", + "properties": { + "kid": { + "type": "string", + "description": "Key ID for header" + }, + "static_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Static claims always included", + "default": {} + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "jwt_sign node input" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "jwt_sign node output" + }, + "outputs": { + "type": "object", + "properties": { + "claims": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Complete claims used" + }, + "header": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JWT header" + }, + "token": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Signed JWT" + } + }, + "description": "jwt_sign node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "jwt_sign" + ], + "x-terraform-transform-const": true + }, + "algorithm": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS384", + "RS512" + ], + "description": "Signing algorithm" + }, + "expires_in": { + "type": "integer", + "description": "Seconds until token expires (for exp claim)", + "default": 300 + }, + "not_before": { + "type": "integer", + "description": "Seconds until token becomes valid (for nbf claim)", + "default": 0 + }, + "typ": { + "type": "string", + "description": "Token type for header", + "default": "JWT" + }, + "inputs": { + "type": "object", + "properties": { + "claims": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Dynamic claims to include" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Signing key (PEM, JWK JSON string, or HMAC secret)" + } + }, + "description": "jwt_sign node inputs" + } + }, + "title": "jwt_sign", + "required": [ + "algorithm" + ], + "description": "Create and sign a JWT" + }, + { + "type": "object", + "properties": { + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "jwt_verify node input" + }, + "inputs": { + "type": "object", + "properties": { + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Verification key: JWKS, JWK, PEM string, or HMAC secret" + }, + "token": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JWT token (with or without Bearer prefix)" + } + }, + "description": "jwt_verify node inputs" + }, + "allowed_algorithms": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS384", + "RS512" + ] + }, + "description": "Allowed signing algorithms (empty = any supported)", + "default": [] + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "jwt_verify node output" + }, + "outputs": { + "type": "object", + "properties": { + "claims": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JWT payload claims" + }, + "header": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "JWT header" + } + }, + "description": "jwt_verify node outputs" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "jwt_verify" + ], + "x-terraform-transform-const": true + }, + "audiences": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed audiences (empty = any)", + "default": [] + }, + "issuers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed issuers (empty = any)", + "default": [] + }, + "leeway": { + "type": "integer", + "description": "Allowed clock skew in seconds for exp/nbf validation", + "default": 0 + }, + "required_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Claims that must be present", + "default": [] + }, + "validate_exp": { + "type": "boolean", + "description": "Validate expiration claim", + "default": true + }, + "validate_nbf": { + "type": "boolean", + "description": "Validate not-before claim", + "default": true + } + }, + "title": "jwt_verify", + "description": "Verify JWT signature and validate claims" + }, + { + "type": "object", + "properties": { + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Property input source. When connected, this node operates in SET mode and writes input data to the property. Otherwise, the node operates in GET mode and reads the property." + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "Property output. This can be connected regardless of whether the node is operating in GET mode or SET mode." + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "property" + ], + "x-terraform-transform-const": true + }, + "content_type": { + "type": "string", + "enum": [ + "application/json", + "application/octet-stream", + "text/plain" + ], + "description": "The expected mime type of the property value. When set to `application/json`, SET operations will JSON-encode input data before writing it, and GET operations will JSON-decode output data after reading it. Otherwise, this setting has no effect." + }, + "property": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The property name to get/set" + } + }, + "title": "property", + "required": [ + "property" + ], + "description": "Get or set a property" + }, + { + "type": "object", + "properties": { + "values": { + "type": "object", + "additionalProperties": true, + "description": "An object with string keys and freeform values", + "x-speakeasy-type-override": "any" + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "The entire `.values` map" + }, + "outputs": { + "type": "object", + "additionalProperties": { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "description": "Individual items from `.values`, referenced by key" + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "type": { + "type": "string", + "enum": [ + "static" + ], + "x-terraform-transform-const": true + } + }, + "title": "static", + "required": [ + "values" + ], + "description": "Produce reusable outputs from statically-configured values" + }, + { + "type": "object", + "properties": { + "recognize_type": { + "type": "boolean", + "default": true + }, + "text_as_property": { + "type": "boolean", + "default": false + }, + "input": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "XML document string" + }, + "type": { + "type": "string", + "enum": [ + "xml_to_json" + ], + "x-terraform-transform-const": true + }, + "attributes_block_name": { + "type": "string", + "maxLength": 32, + "minLength": 1 + }, + "text_block_name": { + "type": "string", + "maxLength": 32, + "minLength": 1, + "default": "#text" + }, + "xpath": { + "type": "string", + "maxLength": 256, + "minLength": 1 + }, + "output": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "a map object converted from XML document. If connected to `request.body` or `response.body`, the output will be a JSON object." + }, + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "description": "A label that uniquely identifies the node within the plugin configuration so that it can be used for input/output connections. Must be valid `snake_case` or `kebab-case`.", + "x-lua-required": true + }, + "attributes_name_prefix": { + "type": "string", + "maxLength": 32, + "minLength": 1 + } + }, + "title": "xml_to_json", + "description": "convert XML to JSON" + } + ] + }, + "maxLength": 64, + "minLength": 1 + }, + "resources": { + "type": "object", + "properties": { + "vault": { + "type": "object", + "maxLength": 64, + "minLength": 1, + "additionalProperties": { + "type": "string", + "maxLength": 4095, + "minLength": 1, + "x-lua-required": true, + "x-referenceable": true + } + }, + "cache": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "memory", + "redis" + ], + "description": "The backing data store in which to hold cache entities. Accepted values are: `memory` and `redis`." + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template.", + "default": "kong_db_cache" + } + } + }, + "redis": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-encrypted": true, + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + } + } + } + } + } + } + }, + "debug": { + "type": "boolean", + "default": false + } + }, + "required": [ + "nodes" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.resources.cache.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Degraphql.json b/app/_schemas/ai-gateway/policies/Degraphql.json new file mode 100644 index 00000000000..b57f8c8d5d7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Degraphql.json @@ -0,0 +1,53 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "graphql_server_path": { + "type": "string", + "description": "The GraphQL endpoint serve path", + "default": "/graphql" + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ExitTransformer.json b/app/_schemas/ai-gateway/policies/ExitTransformer.json new file mode 100644 index 00000000000..8fbe42516d1 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ExitTransformer.json @@ -0,0 +1,80 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "functions": { + "type": "array", + "items": { + "type": "string" + } + }, + "handle_unknown": { + "type": "boolean", + "description": "Determines whether to handle unknown status codes by transforming their responses.", + "default": false + }, + "handle_unexpected": { + "type": "boolean", + "description": "Determines whether to handle unexpected errors by transforming their responses.", + "default": false + } + }, + "required": [ + "functions" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/FileLog.json b/app/_schemas/ai-gateway/policies/FileLog.json new file mode 100644 index 00000000000..c2bc9ada8e5 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/FileLog.json @@ -0,0 +1,87 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "The file path of the output log file. The plugin creates the log file if it doesn't exist yet." + }, + "reopen": { + "type": "boolean", + "description": "Determines whether the log file is closed and reopened on every request.", + "default": false + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + } + }, + "required": [ + "path" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ForwardProxy.json b/app/_schemas/ai-gateway/policies/ForwardProxy.json new file mode 100644 index 00000000000..9901fe90901 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ForwardProxy.json @@ -0,0 +1,112 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "proxy_scheme": { + "type": "string", + "enum": [ + "http" + ], + "description": "The proxy scheme to use when connecting. Only `http` is supported.", + "default": "http" + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected\nby basic authentication.", + "x-referenceable": true + }, + "https_verify": { + "type": "boolean", + "description": "Whether the server certificate will be verified according to the CA certificates specified in lua_ssl_trusted_certificate.", + "default": true + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected\nby basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "x_headers": { + "type": "string", + "enum": [ + "append", + "delete", + "transparent" + ], + "description": "Determines how to handle headers when forwarding the request.", + "default": "append" + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + } + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/GraphqlProxyCacheAdvanced.json b/app/_schemas/ai-gateway/policies/GraphqlProxyCacheAdvanced.json new file mode 100644 index 00000000000..ad1e5d7d6a7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/GraphqlProxyCacheAdvanced.json @@ -0,0 +1,343 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "bypass_on_err": { + "type": "boolean", + "description": "Unhandled errors while trying to retrieve a cache entry (such as redis down) are resolved with `Bypass`, with the request going upstream.", + "default": false + }, + "vary_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration." + }, + "strategy": { + "type": "string", + "enum": [ + "memory", + "redis" + ], + "description": "The backing data store in which to hold cached entities. Accepted value is `memory`.", + "default": "memory" + }, + "cache_ttl": { + "type": "integer", + "description": "TTL in seconds of cache entities. Must be a value greater than 0.", + "default": 300 + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. This dictionary currently must be defined manually in the Kong Nginx template.", + "default": "kong_db_cache" + } + } + }, + "redis": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-encrypted": true, + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + } + } + } + } + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/GraphqlRateLimitingAdvanced.json b/app/_schemas/ai-gateway/policies/GraphqlRateLimitingAdvanced.json new file mode 100644 index 00000000000..17596e5c1b7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/GraphqlRateLimitingAdvanced.json @@ -0,0 +1,399 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "The rate limiting namespace to use for this plugin instance. This namespace is used to share rate limiting counters across different instances. If it is not provided, a random UUID is generated. NOTE: For the plugin instances sharing the same namespace, all the configurations that are required for synchronizing counters, e.g. `strategy`, `redis`, `sync_rate`, `window_size`, `dictionary_name`, need to be the same." + }, + "strategy": { + "type": "string", + "enum": [ + "cluster", + "redis" + ], + "description": "The rate-limiting strategy to use for retrieving and incrementing the limits.", + "default": "cluster" + }, + "dictionary_name": { + "type": "string", + "description": "The shared dictionary where counters will be stored until the next sync cycle.", + "default": "kong_rate_limiting_counters" + }, + "cost_strategy": { + "type": "string", + "enum": [ + "default", + "node_quantifier" + ], + "description": "Strategy to use to evaluate query costs. Either `default` or `node_quantifier`.", + "default": "default" + }, + "identifier": { + "type": "string", + "enum": [ + "consumer", + "credential", + "ip" + ], + "description": "How to define the rate limit key. Can be `ip`, `credential`, `consumer`.", + "default": "consumer" + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers. Available options: `true` or `false`.", + "default": false + }, + "score_factor": { + "type": "number", + "description": "A scoring factor to multiply (or divide) the cost. The `score_factor` must always be greater than 0.", + "default": 1 + }, + "max_cost": { + "type": "number", + "description": "A defined maximum cost per query. 0 means unlimited.", + "default": 0 + }, + "redis": { + "type": "object", + "properties": { + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-encrypted": true, + "x-referenceable": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "cloud_authentication": { + "type": "object", + "properties": { + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + } + } + }, + "pass_all_downstream_headers": { + "type": "boolean", + "description": "pass all downstream headers to the upstream graphql server in introspection request", + "default": false + }, + "window_size": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more window sizes to apply a limit to (defined in seconds)." + }, + "window_type": { + "type": "string", + "enum": [ + "fixed", + "sliding" + ], + "description": "Sets the time window to either `sliding` or `fixed`.", + "default": "sliding" + }, + "limit": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more requests-per-window limits to apply." + }, + "sync_rate": { + "type": "number", + "description": "How often to sync counter data to the central data store. A value of 0 results in synchronous behavior; a value of -1 ignores sync behavior entirely and only stores counters in node memory. A value greater than 0 syncs the counters in that many number of seconds." + } + }, + "required": [ + "limit", + "sync_rate", + "window_size" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/GrpcGateway.json b/app/_schemas/ai-gateway/policies/GrpcGateway.json new file mode 100644 index 00000000000..0f8c36bb4ff --- /dev/null +++ b/app/_schemas/ai-gateway/policies/GrpcGateway.json @@ -0,0 +1,69 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "proto": { + "type": "string", + "description": "Describes the gRPC types and methods." + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/GrpcWeb.json b/app/_schemas/ai-gateway/policies/GrpcWeb.json new file mode 100644 index 00000000000..7da97a00fcf --- /dev/null +++ b/app/_schemas/ai-gateway/policies/GrpcWeb.json @@ -0,0 +1,78 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "allow_origin_header": { + "type": "string", + "description": "The value of the `Access-Control-Allow-Origin` header in the response to the gRPC-Web client.", + "default": "*" + }, + "proto": { + "type": "string", + "description": "If present, describes the gRPC types and methods. Required to support payload transcoding. When absent, the web client must use application/grpw-web+proto content." + }, + "pass_stripped_path": { + "type": "boolean", + "description": "If set to `true` causes the plugin to pass the stripped request path to the upstream gRPC service." + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/HeaderCertAuth.json b/app/_schemas/ai-gateway/policies/HeaderCertAuth.json new file mode 100644 index 00000000000..0ca7713c35d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/HeaderCertAuth.json @@ -0,0 +1,182 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "cache_ttl": { + "type": "number", + "description": "Cache expiry time in seconds.", + "default": 60 + }, + "skip_consumer_lookup": { + "type": "boolean", + "description": "Skip consumer lookup once certificate is trusted against the configured CA list.", + "default": false + }, + "authenticated_group_by": { + "type": "string", + "enum": [ + "CN", + "DN" + ], + "description": "Certificate property to use as the authenticated group. Valid values are `CN` (Common Name) or `DN` (Distinguished Name). Once `skip_consumer_lookup` is applied, any client with a valid certificate can access the Service/API. To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create allowed or denied groups of users.", + "default": "CN" + }, + "ssl_verify": { + "type": "boolean", + "description": "This option enables verification of the certificate presented by the server of the OCSP responder's URL and by the server of the CRL Distribution Point.", + "default": true + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "certificate_header_name": { + "type": "string", + "description": "Name of the header that contains the certificate, received from the WAF or other L7 downstream proxy." + }, + "certificate_header_format": { + "type": "string", + "enum": [ + "base64_encoded", + "url_encoded" + ], + "description": "Format of the certificate header. Supported formats: `base64_encoded`, `url_encoded`." + }, + "default_consumer": { + "type": "string", + "description": "The UUID or username of the consumer to use when a trusted client certificate is presented but no consumer matches. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "allow_partial_chain": { + "type": "boolean", + "description": "Allow certificate verification with only an intermediate certificate. When this is enabled, you don't need to upload the full chain to Kong Certificates.", + "default": false + }, + "http_timeout": { + "type": "number", + "description": "HTTP timeout threshold in milliseconds when communicating with the OCSP server or downloading CRL.", + "default": 30000 + }, + "cert_cache_ttl": { + "type": "number", + "description": "The length of time in milliseconds between refreshes of the revocation check status cache.", + "default": 60000 + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "secure_source": { + "type": "boolean", + "description": "Whether to secure the source of the request. If set to `true`, the plugin will only allow requests from trusted IPs (configured by the `trusted_ips` config option).", + "default": true + }, + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "username" + ] + }, + "description": "Whether to match the subject name of the client-supplied certificate against consumer's `username` and/or `custom_id` attribute. If set to `[]` (the empty array), then auto-matching is disabled.", + "default": [ + "custom_id", + "username" + ] + }, + "ca_certificates": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of CA Certificates strings to use as Certificate Authorities (CA) when validating a client certificate. At least one is required but you can specify as many as needed. The value of this array is comprised of primary keys (`id`)." + }, + "revocation_check_mode": { + "type": "string", + "enum": [ + "IGNORE_CA_ERROR", + "SKIP", + "STRICT" + ], + "description": "Controls client certificate revocation check behavior. If set to `SKIP`, no revocation check is performed. If set to `IGNORE_CA_ERROR`, the plugin respects the revocation status when either OCSP or CRL URL is set, and doesn't fail on network issues. If set to `STRICT`, the plugin only treats the certificate as valid when it's able to verify the revocation status.", + "default": "IGNORE_CA_ERROR" + } + }, + "required": [ + "ca_certificates", + "certificate_header_format", + "certificate_header_name" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/HmacAuth.json b/app/_schemas/ai-gateway/policies/HmacAuth.json new file mode 100644 index 00000000000..f919fb6a199 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/HmacAuth.json @@ -0,0 +1,113 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "anonymous": { + "type": "string", + "description": "An optional string (Consumer UUID or username) value to use as an “anonymous” consumer if authentication fails." + }, + "validate_request_body": { + "type": "boolean", + "description": "A boolean value telling the plugin to enable body validation.", + "default": false + }, + "enforce_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of headers that the client should at least use for HTTP signature creation.", + "default": [] + }, + "algorithms": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "hmac-sha1", + "hmac-sha224", + "hmac-sha256", + "hmac-sha384", + "hmac-sha512" + ] + }, + "description": "A list of HMAC digest algorithms that the user wants to support. Allowed values are `hmac-sha224`, `hmac-sha256`, `hmac-sha384`, `hmac-sha512`, and `hmac-sha1` (disabled by default, and not available in FIPS mode)", + "default": [ + "hmac-sha224", + "hmac-sha256", + "hmac-sha384", + "hmac-sha512" + ] + }, + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service.", + "default": true + }, + "clock_skew": { + "type": "number", + "description": "Clock skew in seconds to prevent replay attacks.", + "default": 300 + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/HttpLog.json b/app/_schemas/ai-gateway/policies/HttpLog.json new file mode 100644 index 00000000000..f36e4cee18b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/HttpLog.json @@ -0,0 +1,195 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "http_endpoint": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl_verify": { + "type": "boolean", + "description": "When using TLS, this option enables verification of the certificate presented by the server.", + "default": true + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when sending data to the upstream server.", + "default": 10000 + }, + "keepalive": { + "type": "number", + "description": "An optional value in milliseconds that defines how long an idle connection will live before being closed.", + "default": 60000 + }, + "retry_count": { + "type": "integer", + "description": "Number of times to retry when sending data to the upstream server." + }, + "flush_timeout": { + "type": "number", + "description": "Optional time in seconds. If `queue_size` \u003e 1, this is the max idle time before sending a log with less than `queue_size` records." + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "An optional table of headers included in the HTTP message to the upstream server. Values are indexed by header name, and each header name accepts a single string." + }, + "queue": { + "type": "object", + "properties": { + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + }, + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + }, + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + }, + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + } + } + }, + "method": { + "type": "string", + "enum": [ + "PATCH", + "POST", + "PUT" + ], + "description": "An optional method used to send data to the HTTP server. Supported values are `POST` (default), `PUT`, and `PATCH`.", + "default": "POST" + }, + "content_type": { + "type": "string", + "enum": [ + "application/json", + "application/json; charset=utf-8" + ], + "description": "Indicates the type of data sent. The only available option is `application/json`.", + "default": "application/json" + }, + "queue_size": { + "type": "integer", + "description": "Maximum number of log entries to be sent on each message to the upstream server." + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + } + }, + "required": [ + "http_endpoint" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/InjectionProtection.json b/app/_schemas/ai-gateway/policies/InjectionProtection.json new file mode 100644 index 00000000000..5daa3c628e4 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/InjectionProtection.json @@ -0,0 +1,126 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "custom_injections": { + "type": "array", + "items": { + "type": "object", + "properties": { + "regex": { + "type": "string", + "description": "The regex to match against." + }, + "name": { + "type": "string", + "description": "A unique name for this injection." + } + }, + "required": [ + "name", + "regex" + ] + }, + "description": "Custom regexes to check for." + }, + "enforcement_mode": { + "type": "string", + "enum": [ + "block", + "log_only" + ], + "description": "Enforcement mode of the security policy.", + "default": "block" + }, + "error_status_code": { + "type": "integer", + "maximum": 499, + "minimum": 400, + "description": "The response status code when validation fails.", + "default": 400 + }, + "error_message": { + "type": "string", + "description": "The response message when validation fails", + "default": "Bad Request" + }, + "injection_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "java_exception", + "js", + "sql", + "sql_low_sensitivity", + "ssi", + "xpath_abbreviated", + "xpath_extended" + ] + }, + "description": "The type of injections to check for.", + "default": [ + "sql" + ] + }, + "locations": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "headers", + "path", + "path_and_query", + "query" + ] + }, + "description": "The locations to check for injection.", + "default": [ + "path_and_query" + ] + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/IpRestriction.json b/app/_schemas/ai-gateway/policies/IpRestriction.json new file mode 100644 index 00000000000..fa31797c569 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/IpRestriction.json @@ -0,0 +1,101 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls" + ] + }, + "config": { + "type": "object", + "properties": { + "allow": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an IP address or CIDR block, such as 192.168.1.1 or 192.168.0.0/16." + }, + "description": "List of IPs or CIDR ranges to allow. One of `config.allow` or `config.deny` must be specified." + }, + "deny": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an IP address or CIDR block, such as 192.168.1.1 or 192.168.0.0/16." + }, + "description": "List of IPs or CIDR ranges to deny. One of `config.allow` or `config.deny` must be specified." + }, + "status": { + "type": "number", + "description": "The HTTP status of the requests that will be rejected by the plugin." + }, + "message": { + "type": "string", + "description": "The message to send as a response body to rejected requests." + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Jq.json b/app/_schemas/ai-gateway/policies/Jq.json new file mode 100644 index 00000000000..c0e8afa9e19 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Jq.json @@ -0,0 +1,145 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "response_jq_program_options": { + "type": "object", + "properties": { + "join_output": { + "type": "boolean", + "default": false + }, + "ascii_output": { + "type": "boolean", + "default": false + }, + "sort_keys": { + "type": "boolean", + "default": false + }, + "compact_output": { + "type": "boolean", + "default": true + }, + "raw_output": { + "type": "boolean", + "default": false + } + }, + "default": {} + }, + "response_if_media_type": { + "type": "array", + "items": { + "type": "string" + }, + "default": [ + "application/json" + ] + }, + "response_if_status_code": { + "type": "array", + "items": { + "type": "integer", + "maximum": 599, + "minimum": 100 + }, + "default": [ + 200 + ] + }, + "request_jq_program": { + "type": "string" + }, + "request_jq_program_options": { + "type": "object", + "properties": { + "sort_keys": { + "type": "boolean", + "default": false + }, + "compact_output": { + "type": "boolean", + "default": true + }, + "raw_output": { + "type": "boolean", + "default": false + }, + "join_output": { + "type": "boolean", + "default": false + }, + "ascii_output": { + "type": "boolean", + "default": false + } + }, + "default": {} + }, + "request_if_media_type": { + "type": "array", + "items": { + "type": "string" + }, + "default": [ + "application/json" + ] + }, + "response_jq_program": { + "type": "string" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/JsonThreatProtection.json b/app/_schemas/ai-gateway/policies/JsonThreatProtection.json new file mode 100644 index 00000000000..4c252c70670 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/JsonThreatProtection.json @@ -0,0 +1,121 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "max_string_value_length": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max string value length. -1 means unlimited.", + "default": -1 + }, + "error_status_code": { + "type": "integer", + "maximum": 499, + "minimum": 400, + "description": "The response status code when validation fails.", + "default": 400 + }, + "max_object_entry_count": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max number of entries in an object. -1 means unlimited.", + "default": -1 + }, + "allow_duplicate_object_entry_name": { + "type": "boolean", + "description": "Allow or disallow duplicate object entry name.", + "default": true + }, + "allow_non_json_requests": { + "type": "boolean", + "description": "Allow non-json requests to bypass the rules", + "default": false + }, + "enforcement_mode": { + "type": "string", + "enum": [ + "block", + "log_only" + ], + "description": "Enforcement mode of the security policy.", + "default": "block" + }, + "error_message": { + "type": "string", + "description": "The response message when validation fails", + "default": "Bad Request" + }, + "max_body_size": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max size of the request body. -1 means unlimited.", + "default": 8192 + }, + "max_container_depth": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max nested depth of objects and arrays. -1 means unlimited.", + "default": -1 + }, + "max_object_entry_name_length": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max string length of object name. -1 means unlimited.", + "default": -1 + }, + "max_array_element_count": { + "type": "integer", + "maximum": 2147483648, + "minimum": -1, + "description": "Max number of elements in an array. -1 means unlimited.", + "default": -1 + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/JweDecrypt.json b/app/_schemas/ai-gateway/policies/JweDecrypt.json new file mode 100644 index 00000000000..a9dab768eb2 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/JweDecrypt.json @@ -0,0 +1,86 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "lookup_header_name": { + "type": "string", + "description": "The name of the header to look for the JWE token.", + "default": "Authorization" + }, + "forward_header_name": { + "type": "string", + "description": "The name of the header that is used to set the decrypted value.", + "default": "Authorization" + }, + "key_sets": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Denote the name or names of all Key Sets that should be inspected when trying to find a suitable key to decrypt the JWE token." + }, + "strict": { + "type": "boolean", + "description": "Defines how the plugin behaves in cases where no token was found in the request. When using `strict` mode, the request requires a token to be present and subsequently raise an error if none could be found.", + "default": true + } + }, + "required": [ + "key_sets" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Jwt.json b/app/_schemas/ai-gateway/policies/Jwt.json new file mode 100644 index 00000000000..c98060a0f2f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Jwt.json @@ -0,0 +1,127 @@ +{ + "properties": { + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "cookie_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of cookie names that Kong will inspect to retrieve JWTs.", + "default": [] + }, + "key_claim_name": { + "type": "string", + "description": "The name of the claim in which the key identifying the secret must be passed. The plugin will attempt to read this claim from the JWT payload and the header, in that order.", + "default": "iss" + }, + "claims_to_verify": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "exp", + "nbf" + ] + }, + "description": "A list of registered claims (according to RFC 7519) that Kong can verify as well. Accepted values: one of exp or nbf." + }, + "run_on_preflight": { + "type": "boolean", + "description": "A boolean value that indicates whether the plugin should run (and try to authenticate) on OPTIONS preflight requests. If set to false, then OPTIONS requests will always be allowed.", + "default": true + }, + "maximum_expiration": { + "type": "number", + "maximum": 31536000, + "minimum": 0, + "description": "A value between 0 and 31536000 (365 days) limiting the lifetime of the JWT to maximum_expiration seconds in the future.", + "default": 0 + }, + "uri_param_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of querystring parameters that Kong will inspect to retrieve JWTs.", + "default": [ + "jwt" + ] + }, + "secret_is_base64": { + "type": "boolean", + "description": "If true, the plugin assumes the credential’s secret to be base64 encoded. You will need to create a base64-encoded secret for your Consumer, and sign your JWT with the original secret.", + "default": false + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails." + }, + "header_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of HTTP header names that Kong will inspect to retrieve JWTs.", + "default": [ + "authorization" + ] + }, + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/JwtSigner.json b/app/_schemas/ai-gateway/policies/JwtSigner.json new file mode 100644 index 00000000000..38923ac4d03 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/JwtSigner.json @@ -0,0 +1,1130 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "verify_access_token_audience": { + "type": "boolean", + "description": "Quickly turn off and on the access token required audiences verification, specified with `config.access_token_audiences_required`.", + "default": true + }, + "channel_token_consumer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "When you set a value for this parameter, the plugin tries to map an arbitrary claim specified with this configuration parameter. Kong consumers have an `id`, a `username`, and a `custom_id`. If this parameter is enabled but the mapping fails, such as when there's a non-existent Kong consumer, the plugin responds with `403 Forbidden`." + }, + "channel_token_introspection_subject_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token to verify against values of `config.channel_token_introspection_subjects_allowed`.", + "default": [ + "sub" + ] + }, + "channel_token_optional_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the optional claims of the channel token. These claims are only validated when they are present. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "channel_token_introspection_consumer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "When you set a value for this parameter, the plugin tries to map an arbitrary claim specified with this configuration parameter (such as `sub` or `username`) in channel token introspection results to Kong consumer entity" + }, + "remove_channel_token_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "remove claims. It should be an array, and each element is a claim key string.", + "default": [] + }, + "access_token_jwks_uri": { + "type": "string", + "description": "Specify the URI where the plugin can fetch the public keys (JWKS) to verify the signature of the access token." + }, + "access_token_introspection_body_args": { + "type": "string", + "description": "This parameter allows you to pass URL encoded request body arguments. For example: `resource=` or `a=1\u0026b=\u0026c`." + }, + "access_token_introspection_subject_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token introspection to verify against values of `config.access_token_introspection_subjects_allowed`.", + "default": [ + "sub" + ] + }, + "channel_token_issuer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token to verify against values of `config.channel_token_issuers_allowed`.", + "default": [ + "iss" + ] + }, + "verify_channel_token_introspection_scopes": { + "type": "boolean", + "description": "Quickly turn on/off the channel token introspection scopes verification specified with `config.channel_token_introspection_scopes_required`.", + "default": true + }, + "trust_channel_token_introspection": { + "type": "boolean", + "description": "Providing an opaque channel token for plugin introspection, and verifying expiry and scopes on introspection results may make further payload checks unnecessary before the plugin signs a new token. This also applies when using a JWT token with introspection JSON as per config.channel_token_introspection_jwt_claim. Use this parameter to manage additional payload checks before signing a new token. With true (default), payload's expiry or scopes aren't checked.", + "default": true + }, + "access_token_introspection_authorization": { + "type": "string", + "description": "If the introspection endpoint requires client authentication (client being the JWT Signer plugin), you can specify the `Authorization` header's value with this configuration parameter." + }, + "trust_access_token_introspection": { + "type": "boolean", + "description": "Use this parameter to enable and disable further checks on a payload before the new token is signed. If you set this to `true`, the expiry or scopes are not checked on a payload.", + "default": true + }, + "channel_token_leeway": { + "type": "number", + "description": "Adjusts clock skew between the token issuer and Kong. The value will be used to time-related claim verification. For example, it will be added to token's `exp` claim before checking token expiry against Kong servers current time in seconds. You can disable channel token `expiry` verification altogether with `config.verify_channel_token_expiry`.", + "default": 0 + }, + "access_token_keyset_rotate_period": { + "type": "number", + "description": "Specify the period (in seconds) to auto-rotate the jwks for `access_token_keyset`. The default value 0 means no auto-rotation.", + "default": 0 + }, + "access_token_signing": { + "type": "boolean", + "description": "Quickly turn access token signing or re-signing off and on as needed. If turned off, the plugin will not send the signed or resigned token to the upstream.", + "default": true + }, + "channel_token_keyset_rotate_period": { + "type": "number", + "description": "Specify the period (in seconds) to auto-rotate the jwks for `channel_token_keyset`. The default value 0 means no auto-rotation.", + "default": 0 + }, + "channel_token_introspection_audiences_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences allowed to be present in the channel token introspection claim specified by `config.channel_token_introspection_audience_claim`." + }, + "access_token_notbefore_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the notbefore claim in an access token to verify if the default `nbf` is not used.", + "default": [ + "nbf" + ] + }, + "enable_instrumentation": { + "type": "boolean", + "description": "Writes log entries with some added information using `ngx.CRIT` (CRITICAL) level.", + "default": false + }, + "access_token_jwks_uri_rotate_period": { + "type": "number", + "description": "Specify the period (in seconds) to auto-rotate the jwks for `access_token_jwks_uri`. The default value 0 means no auto-rotation.", + "default": 0 + }, + "access_token_introspection_issuers_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The issuers allowed to be present in the access token introspection claim specified by `config.access_token_introspection_issuer_claim`." + }, + "set_access_token_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Set customized claims. If a claim is already present, it will be overwritten. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + }, + "remove_access_token_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "remove claims. It should be an array, and each element is a claim key string.", + "default": [] + }, + "verify_access_token_issuer": { + "type": "boolean", + "description": "Quickly turn off and on the access token allowed issuers verification, specified with `config.access_token_issuers_allowed`.", + "default": true + }, + "channel_token_introspection_authorization": { + "type": "string", + "description": "When using `opaque` channel tokens, and you want to turn on channel token introspection, you need to specify the OAuth 2.0 introspection endpoint URI with this configuration parameter. Otherwise the plugin will not try introspection, and instead returns `401 Unauthorized` when using opaque channel tokens." + }, + "verify_access_token_introspection_expiry": { + "type": "boolean", + "description": "Quickly turn access token introspection expiry verification off and on as needed.", + "default": true + }, + "channel_token_introspection_subjects_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The subjects allowed to be present in the channel token introspection claim specified by `config.channel_token_introspection_subject_claim`." + }, + "channel_token_introspection_consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "When the plugin tries to do channel token introspection results to Kong consumer mapping, it tries to find a matching Kong consumer from properties defined using this configuration parameter. The parameter can take an array of values. Valid values are `id`, `username` and `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "verify_channel_token_issuer": { + "type": "boolean", + "description": "Quickly turn off and on the channel token allowed issuers verification, specified with `config.channel_token_issuers_allowed`.", + "default": true + }, + "verify_channel_token_introspection_notbefore": { + "type": "boolean", + "description": "Quickly turn off and on the channel token introspection notbefore verification.", + "default": false + }, + "access_token_keyset_client_certificate": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "The client certificate that will be used to authenticate Kong if `access_token_keyset` is an https uri that requires mTLS Auth.", + "x-foreign": true + }, + "access_token_expiry_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the expiry claim in an access token to verify if the default `exp` is not used.", + "default": [ + "exp" + ] + }, + "access_token_introspection_issuer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token introspection to verify against values of `config.access_token_introspection_issuers_allowed`.", + "default": [ + "iss" + ] + }, + "access_token_introspection_audiences_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences allowed to be present in the access token introspection claim specified by `config.access_token_introspection_audience_claim`." + }, + "add_access_token_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Add customized claims if they are not present yet. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + }, + "verify_access_token_expiry": { + "type": "boolean", + "description": "Quickly turn access token expiry verification off and on as needed.", + "default": true + }, + "channel_token_notbefore_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the notbefore claim in a channel token to verify if the default `nbf` is not used.", + "default": [ + "nbf" + ] + }, + "channel_token_introspection_body_args": { + "type": "string", + "description": "If you need to pass additional body arguments to introspection endpoint when the plugin introspects the opaque channel token, you can use this config parameter to specify them. You should URL encode the value. For example: `resource=` or `a=1\u0026b=\u0026c`." + }, + "access_token_scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the required values (or scopes) that are checked by a claim specified by `config.access_token_scopes_claim`." + }, + "access_token_optional": { + "type": "boolean", + "description": "If an access token is not provided or no `config.access_token_request_header` is specified, the plugin cannot verify the access token. In that case, the plugin normally responds with `401 Unauthorized` (client didn't send a token) or `500 Unexpected` (a configuration error). Use this parameter to allow the request to proceed even when there is no token to check. If the token is provided, then this parameter has no effect", + "default": false + }, + "verify_access_token_introspection_issuer": { + "type": "boolean", + "description": "Quickly turn off and on the access token introspection allowed issuers verification, specified with `config.access_token_introspection_issuers_allowed`.", + "default": true + }, + "channel_token_keyset": { + "type": "string", + "description": "The name of the keyset containing signing keys.", + "default": "kong" + }, + "channel_token_signing_algorithm": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS512" + ], + "description": "When this plugin sets the upstream header as specified with `config.channel_token_upstream_header`, it also re-signs the original channel token using private keys of this plugin. Specify the algorithm that is used to sign the token.", + "default": "RS256" + }, + "channel_token_endpoints_ssl_verify": { + "type": "boolean", + "description": "Whether to verify the TLS certificate if any of `channel_token_introspection_endpoint`, `channel_token_jwks_uri`, or `channel_token_keyset` is an HTTPS URI.", + "default": true + }, + "access_token_keyset": { + "type": "string", + "description": "The name of the keyset containing signing keys.", + "default": "kong" + }, + "access_token_introspection_required_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the required claims that must be present in the access token introspection result. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "channel_token_jwks_uri_client_password": { + "type": "string", + "description": "The client password that will be used to authenticate Kong if `channel_token_jwks_uri` is a uri that requires Basic Auth. Should be configured together with `channel_token_jwks_uri_client_username`", + "x-referenceable": true, + "x-encrypted": true + }, + "channel_token_audiences_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences allowed to be present in the channel token claim specified by `config.channel_token_audience_claim`." + }, + "access_token_request_header": { + "type": "string", + "description": "This parameter tells the name of the header where to look for the access token.", + "default": "Authorization" + }, + "verify_access_token_scopes": { + "type": "boolean", + "description": "Quickly turn off and on the access token required scopes verification, specified with `config.access_token_scopes_required`.", + "default": true + }, + "channel_token_keyset_client_username": { + "type": "string", + "description": "The client username that will be used to authenticate Kong if `channel_token_keyset` is a uri that requires Basic Auth. Should be configured together with `channel_token_keyset_client_password`", + "x-referenceable": true + }, + "channel_token_subjects_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The subjects allowed to be present in the channel token claim specified by `config.channel_token_subject_claim`." + }, + "channel_token_upstream_header": { + "type": "string", + "description": "This plugin removes the `config.channel_token_request_header` from the request after reading its value." + }, + "channel_token_introspection_scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Use this parameter to specify the claim/property in channel token introspection results (`JSON`) to be verified against values of `config.channel_token_introspection_scopes_required`. This supports nested claims.", + "default": [ + "scope" + ] + }, + "add_channel_token_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Add customized claims if they are not present yet. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + }, + "access_token_introspection_notbefore_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the notbefore claim in an access token introspection to verify if the default `nbf` is not used.", + "default": [ + "nbf" + ] + }, + "verify_access_token_introspection_audience": { + "type": "boolean", + "description": "Quickly turn off and on the access token introspection required audiences verification, specified with `config.access_token_introspection_audiences_required`.", + "default": true + }, + "channel_token_scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token to verify against values of `config.channel_token_scopes_required`. This supports nested claims.", + "default": [ + "scope" + ] + }, + "channel_token_introspection_hint": { + "type": "string", + "description": "If you need to give `hint` parameter when introspecting a channel token, you can use this parameter to specify the value of such parameter. By default, a `hint` isn't sent with channel token introspection." + }, + "channel_token_introspection_optional_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the optional claims of the channel token introspection. These claims are only validated when they are present. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "access_token_introspection_consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "When the plugin tries to do access token introspection results to Kong consumer mapping, it tries to find a matching Kong consumer from properties defined using this configuration parameter. The parameter can take an array of values.", + "default": [ + "custom_id", + "username" + ] + }, + "channel_token_keyset_client_certificate": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "The client certificate that will be used to authenticate Kong if `channel_token_keyset` is an https uri that requires mTLS Auth.", + "x-foreign": true + }, + "channel_token_introspection_scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Use this parameter to specify the required values (or scopes) that are checked by an introspection claim/property specified by `config.channel_token_introspection_scopes_claim`." + }, + "verify_channel_token_scopes": { + "type": "boolean", + "description": "Quickly turn on/off the channel token required scopes verification specified with `config.channel_token_scopes_required`.", + "default": true + }, + "enable_channel_token_introspection": { + "type": "boolean", + "description": "If you don't want to support opaque channel tokens, disable introspection by changing this configuration parameter to `false`.", + "default": true + }, + "access_token_issuer": { + "type": "string", + "description": "The `iss` claim of a signed or re-signed access token is set to this value. Original `iss` claim of the incoming token (possibly introspected) is stored in `original_iss` claim of the newly signed access token.", + "default": "kong" + }, + "access_token_jwks_uri_client_certificate": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "The client certificate that will be used to authenticate Kong if `access_token_jwks_uri` is an https uri that requires mTLS Auth.", + "x-foreign": true + }, + "verify_access_token_introspection_scopes": { + "type": "boolean", + "description": "Quickly turn off and on the access token introspection scopes verification, specified with `config.access_token_introspection_scopes_required`.", + "default": true + }, + "channel_token_scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the required values (or scopes) that are checked by a claim specified by `config.channel_token_scopes_claim`." + }, + "channel_token_introspection_leeway": { + "type": "number", + "description": "You can use this parameter to adjust clock skew between the token issuer introspection results and Kong. The value will be used to time-related claim verification. For example, it will be added to introspection results (`JSON`) `exp` claim/property before checking token expiry against Kong servers current time (in seconds). You can disable channel token introspection `expiry` verification altogether with `config.verify_channel_token_introspection_expiry`.", + "default": 0 + }, + "realm": { + "type": "string", + "description": "When authentication or authorization fails, or there is an unexpected error, the plugin sends a `WWW-Authenticate` header with the `realm` attribute value." + }, + "access_token_jwks_uri_client_password": { + "type": "string", + "description": "The client password that will be used to authenticate Kong if `access_token_jwks_uri` is a uri that requires Basic Auth. Should be configured together with `access_token_jwks_uri_client_username`", + "x-referenceable": true, + "x-encrypted": true + }, + "access_token_subject_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token to verify against values of `config.access_token_subjects_allowed`.", + "default": [ + "sub" + ] + }, + "access_token_introspection_scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the required values (or scopes) that are checked by an introspection claim/property specified by `config.access_token_introspection_scopes_claim`." + }, + "cache_access_token_introspection": { + "type": "boolean", + "description": "Whether to cache access token introspection results.", + "default": true + }, + "access_token_introspection_jwt_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If your introspection endpoint returns an access token in one of the keys (or claims) within the introspection results (`JSON`). If the key cannot be found, the plugin responds with `401 Unauthorized`. Also if the key is found but cannot be decoded as JWT, it also responds with `401 Unauthorized`." + }, + "access_token_endpoints_ssl_verify": { + "type": "boolean", + "description": "Whether to verify the TLS certificate if any of `access_token_introspection_endpoint`, `access_token_jwks_uri`, or `access_token_keyset` is an HTTPS URI.", + "default": true + }, + "channel_token_keyset_client_password": { + "type": "string", + "description": "The client password that will be used to authenticate Kong if `channel_token_keyset` is a uri that requires Basic Auth. Should be configured together with `channel_token_keyset_client_username`", + "x-referenceable": true, + "x-encrypted": true + }, + "verify_channel_token_signature": { + "type": "boolean", + "description": "Quickly turn on/off the channel token signature verification.", + "default": true + }, + "verify_channel_token_subject": { + "type": "boolean", + "description": "Quickly turn off and on the channel token required subjects verification, specified with `config.channel_token_subjects_required`.", + "default": true + }, + "cache_channel_token_introspection": { + "type": "boolean", + "description": "Whether to cache channel token introspection results.", + "default": true + }, + "access_token_issuer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token to verify against values of `config.access_token_issuers_allowed`.", + "default": [ + "iss" + ] + }, + "set_channel_token_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Set customized claims. If a claim is already present, it will be overwritten. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + }, + "enable_hs_signatures": { + "type": "boolean", + "description": "Tokens signed with HMAC algorithms such as `HS256`, `HS384`, or `HS512` are not accepted by default. If you need to accept such tokens for verification, enable this setting.", + "default": false + }, + "access_token_optional_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the optional claims of the access token. These claims are only validated when they are present. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "access_token_subjects_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The subjects allowed to be present in the access token claim specified by `config.access_token_subject_claim`." + }, + "access_token_introspection_leeway": { + "type": "number", + "description": "Adjusts clock skew between the token issuer introspection results and Kong. The value will be used to time-related claim verification. For example, it will be added to introspection results (`JSON`) `exp` claim/property before checking token expiry against Kong servers current time in seconds. You can disable access token introspection `expiry` verification altogether with `config.verify_access_token_introspection_expiry`.", + "default": 0 + }, + "enable_access_token_introspection": { + "type": "boolean", + "description": "If you don't want to support opaque access tokens, change this configuration parameter to `false` to disable introspection.", + "default": true + }, + "access_token_introspection_audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token introspection to verify against values of `config.access_token_introspection_audiences_allowed`.", + "default": [ + "aud" + ] + }, + "channel_token_signing": { + "type": "boolean", + "description": "Quickly turn channel token signing or re-signing off and on as needed. If turned off, the plugin will not send the signed or resigned token to the upstream.", + "default": true + }, + "channel_token_upstream_leeway": { + "type": "number", + "description": "If you want to add or perhaps subtract (using negative value) expiry time of the original channel token, you can specify a value that is added to the original channel token's `exp` claim.", + "default": 0 + }, + "verify_channel_token_introspection_audience": { + "type": "boolean", + "description": "Quickly turn off and on the channel token introspection required audiences verification, specified with `config.channel_token_introspection_audiences_required`.", + "default": true + }, + "access_token_upstream_leeway": { + "type": "number", + "description": "If you want to add or subtract (using a negative value) expiry time (in seconds) of the original access token, you can specify a value that is added to the original access token's `exp` claim.", + "default": 0 + }, + "access_token_introspection_scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim/property in access token introspection results (`JSON`) to be verified against values of `config.access_token_introspection_scopes_required`. This supports nested claims. For example, with Keycloak you could use `[ \"realm_access\", \"roles\" ]`, which can be given as `realm_access,roles` (form post). If the claim is not found in access token introspection results, and you have specified `config.access_token_introspection_scopes_required`, the plugin responds with `403 Forbidden`.", + "default": [ + "scope" + ] + }, + "access_token_introspection_consumer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "When you set a value for this parameter, the plugin tries to map an arbitrary claim specified with this configuration parameter (such as `sub` or `username`) in access token introspection results to the Kong consumer entity." + }, + "verify_access_token_subject": { + "type": "boolean", + "description": "Quickly turn off and on the access token required subjects verification, specified with `config.access_token_subjects_required`.", + "default": true + }, + "channel_token_jwks_uri_rotate_period": { + "type": "number", + "description": "Specify the period (in seconds) to auto-rotate the jwks for `channel_token_jwks_uri`. The default value 0 means no auto-rotation.", + "default": 0 + }, + "channel_token_required_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the required claims that must be present in the channel token. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "channel_token_expiry_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the expiry claim in a channel token to verify if the default `exp` is not used.", + "default": [ + "exp" + ] + }, + "channel_token_introspection_expiry_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the expiry claim in a channel token to verify if the default `exp` is not used.", + "default": [ + "exp" + ] + }, + "access_token_required_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the required claims that must be present in the access token. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "access_token_introspection_endpoint": { + "type": "string", + "description": "When you use `opaque` access tokens and you want to turn on access token introspection, you need to specify the OAuth 2.0 introspection endpoint URI with this configuration parameter." + }, + "verify_access_token_notbefore": { + "type": "boolean", + "description": "Quickly turn off and on the access token notbefore verification.", + "default": false + }, + "channel_token_introspection_timeout": { + "type": "number", + "description": "Timeout in milliseconds for an introspection request. The plugin tries to introspect twice if the first request fails for some reason. If both requests timeout, then the plugin runs two times the `config.access_token_introspection_timeout` on channel token introspection." + }, + "original_channel_token_upstream_header": { + "type": "string", + "description": "The HTTP header name used to store the original channel token." + }, + "verify_channel_token_audience": { + "type": "boolean", + "description": "Quickly turn off and on the channel token required audiences verification, specified with `config.channel_token_audiences_required`.", + "default": true + }, + "verify_channel_token_notbefore": { + "type": "boolean", + "description": "Quickly turn off and on the channel token notbefore verification.", + "default": false + }, + "add_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Add customized claims to both tokens if they are not present yet. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + }, + "original_access_token_upstream_header": { + "type": "string", + "description": "The HTTP header name used to store the original access token." + }, + "access_token_introspection_timeout": { + "type": "number", + "description": "Timeout in milliseconds for an introspection request. The plugin tries to introspect twice if the first request fails for some reason. If both requests timeout, then the plugin runs two times the `config.access_token_introspection_timeout` on access token introspection." + }, + "channel_token_introspection_issuer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token introspection to verify against values of `config.channel_token_introspection_issuers_allowed`.", + "default": [ + "iss" + ] + }, + "channel_token_optional": { + "type": "boolean", + "description": "If a channel token is not provided or no `config.channel_token_request_header` is specified, the plugin cannot verify the channel token. In that case, the plugin normally responds with `401 Unauthorized` (client didn't send a token) or `500 Unexpected` (a configuration error). Enable this parameter to allow the request to proceed even when there is no channel token to check. If the channel token is provided, then this parameter has no effect", + "default": false + }, + "access_token_consumer_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "When you set a value for this parameter, the plugin tries to map an arbitrary claim specified with this configuration parameter (for example, `sub` or `username`) in an access token to Kong consumer entity." + }, + "channel_token_jwks_uri_client_certificate": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "The client certificate that will be used to authenticate Kong if `channel_token_jwks_uri` is an https uri that requires mTLS Auth.", + "x-foreign": true + }, + "channel_token_request_header": { + "type": "string", + "description": "This parameter tells the name of the header where to look for the channel token. If you don't want to do anything with the channel token, then you can set this to `null` or `\"\"` (empty string)." + }, + "access_token_keyset_client_password": { + "type": "string", + "description": "The client password that will be used to authenticate Kong if `access_token_keyset` is a uri that requires Basic Auth. Should be configured together with `access_token_keyset_client_username`", + "x-referenceable": true, + "x-encrypted": true + }, + "access_token_signing_algorithm": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS512" + ], + "description": "When this plugin sets the upstream header as specified with `config.access_token_upstream_header`, re-signs the original access token using the private keys of the JWT Signer plugin. Specify the algorithm that is used to sign the token. The `config.access_token_issuer` specifies which `keyset` is used to sign the new token issued by Kong using the specified signing algorithm.", + "default": "RS256" + }, + "verify_channel_token_expiry": { + "type": "boolean", + "default": true + }, + "access_token_issuers_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The issuers allowed to be present in the access token claim specified by `config.access_token_issuer_claim`." + }, + "channel_token_consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "When the plugin tries to do channel token to Kong consumer mapping, it tries to find a matching Kong consumer from properties defined using this configuration parameter. The parameter can take an array of valid values: `id`, `username`, and `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "channel_token_introspection_jwt_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If your introspection endpoint returns a channel token in one of the keys (or claims) in the introspection results (`JSON`), the plugin can use that value instead of the introspection results when doing expiry verification and signing of the new token issued by Kong." + }, + "verify_channel_token_introspection_issuer": { + "type": "boolean", + "description": "Quickly turn off and on the channel token introspection allowed issuers verification, specified with `config.channel_token_introspection_issuers_allowed`.", + "default": true + }, + "access_token_introspection_hint": { + "type": "string", + "description": "If you need to give `hint` parameter when introspecting an access token, use this parameter to specify the value. By default, the plugin sends `hint=access_token`.", + "default": "access_token" + }, + "channel_token_subject_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token to verify against values of `config.channel_token_subjects_allowed`.", + "default": [ + "sub" + ] + }, + "access_token_keyset_client_username": { + "type": "string", + "description": "The client username that will be used to authenticate Kong if `access_token_keyset` is a uri that requires Basic Auth. Should be configured together with `access_token_keyset_client_password`", + "x-referenceable": true + }, + "access_token_consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "When the plugin tries to apply an access token to a Kong consumer mapping, it tries to find a matching Kong consumer from properties defined using this configuration parameter. The parameter can take an array of values. Valid values are `id`, `username`, and `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "access_token_introspection_optional_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the optional claims of the access token introspection result. These claims are only validated when they are present. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "verify_access_token_introspection_notbefore": { + "type": "boolean", + "description": "Quickly turn off and on the access token introspection notbefore verification.", + "default": false + }, + "channel_token_issuer": { + "type": "string", + "description": "The `iss` claim of the re-signed channel token is set to this value, which is `kong` by default. The original `iss` claim of the incoming token (possibly introspected) is stored in the `original_iss` claim of the newly signed channel token.", + "default": "kong" + }, + "channel_token_audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token to verify against values of `config.channel_token_audiences_allowed`.", + "default": [ + "aud" + ] + }, + "channel_token_introspection_endpoint": { + "type": "string", + "description": "When you use `opaque` access tokens and you want to turn on access token introspection, you need to specify the OAuth 2.0 introspection endpoint URI with this configuration parameter. Otherwise, the plugin does not try introspection and returns `401 Unauthorized` instead." + }, + "access_token_audiences_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences allowed to be present in the access token claim specified by `config.access_token_audience_claim`." + }, + "access_token_upstream_header": { + "type": "string", + "description": "Removes the `config.access_token_request_header` from the request after reading its value. With `config.access_token_upstream_header`, you can specify the upstream header where the plugin adds the Kong signed token. If you don't specify a value, such as use `null` or `\"\"` (empty string), the plugin does not even try to sign or re-sign the token.", + "default": "Authorization:Bearer" + }, + "verify_access_token_introspection_subject": { + "type": "boolean", + "description": "Quickly turn off and on the access token introspection required subjects verification, specified with `config.access_token_introspection_subjects_required`.", + "default": true + }, + "channel_token_jwks_uri": { + "type": "string", + "description": "If you want to use `config.verify_channel_token_signature`, you must specify the URI where the plugin can fetch the public keys (JWKS) to verify the signature of the channel token. If you don't specify a URI and you pass a JWT token to the plugin, then the plugin responds with `401 Unauthorized`." + }, + "channel_token_introspection_issuers_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The issuers allowed to be present in the channel token introspection claim specified by `config.channel_token_introspection_issuer_claim`." + }, + "channel_token_introspection_notbefore_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the notbefore claim in a channel token to verify if the default `nbf` is not used.", + "default": [ + "nbf" + ] + }, + "verify_channel_token_introspection_subject": { + "type": "boolean", + "description": "Quickly turn off and on the channel token introspection required subjects verification, specified with `config.channel_token_introspection_subjects_required`.", + "default": true + }, + "access_token_leeway": { + "type": "number", + "description": "Adjusts clock skew between the token issuer and Kong. The value will be used to time-related claim verification. For example, it will be added to the token's `exp` claim before checking token expiry against Kong servers' current time in seconds. You can disable access token `expiry` verification altogether with `config.verify_access_token_expiry`.", + "default": 0 + }, + "access_token_introspection_subjects_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The subjects allowed to be present in the access token introspection claim specified by `config.access_token_introspection_subject_claim`." + }, + "access_token_audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token to verify against values of `config.access_token_audiences_allowed`.", + "default": [ + "aud" + ] + }, + "access_token_jwks_uri_client_username": { + "type": "string", + "description": "The client username that will be used to authenticate Kong if `access_token_jwks_uri` is a uri that requires Basic Auth. Should be configured together with `access_token_jwks_uri_client_password`", + "x-referenceable": true + }, + "access_token_introspection_expiry_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the expiry claim in an access token introspection to verify if the default `exp` is not used.", + "default": [ + "exp" + ] + }, + "verify_access_token_signature": { + "type": "boolean", + "description": "Quickly turn access token signature verification off and on as needed.", + "default": true + }, + "channel_token_issuers_allowed": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The issuers allowed to be present in the channel token claim specified by `config.channel_token_issuer_claim`." + }, + "verify_channel_token_introspection_expiry": { + "type": "boolean", + "description": "Quickly turn on/off the channel token introspection expiry verification.", + "default": true + }, + "access_token_scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in an access token to verify against values of `config.access_token_scopes_required`.", + "default": [ + "scope" + ] + }, + "channel_token_jwks_uri_client_username": { + "type": "string", + "description": "The client username that will be used to authenticate Kong if `channel_token_jwks_uri` is a uri that requires Basic Auth. Should be configured together with `channel_token_jwks_uri_client_password`", + "x-referenceable": true + }, + "channel_token_introspection_required_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Specify the required claims that must be present in the channel token introspection. Every claim is specified by an array. If the array has multiple elements, it means the claim is inside a nested object of the payload." + }, + "channel_token_introspection_audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify the claim in a channel token introspection to verify against values of `config.channel_token_introspection_audiences_allowed`.", + "default": [ + "aud" + ] + }, + "set_claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Set customized claims to both tokens. If a claim is already present, it will be overwritten. Value can be a regular or JSON string; if JSON, decoded data is used as the claim's value.", + "default": {} + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KafkaConsume.json b/app/_schemas/ai-gateway/policies/KafkaConsume.json new file mode 100644 index 00000000000..63501794dad --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KafkaConsume.json @@ -0,0 +1,626 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "config": { + "type": "object", + "properties": { + "enable_dlq": { + "type": "boolean", + "description": "Enables Dead Letter Queue. When enabled, if the message doesn't conform to the schema (from Schema Registry) or there's an error in the `message_by_lua_functions`, it will be forwarded to `dlq_topic` that can be processed later." + }, + "dlq_topic": { + "type": "string", + "description": "The topic to use for the Dead Letter Queue." + }, + "bootstrap_servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + }, + "required": [ + "host", + "port" + ] + }, + "description": "Set of bootstrap brokers in a `{host: host, port: port}` list format." + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "username": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + } + } + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + } + } + } + }, + "description": "The plugin-global schema registry configuration." + }, + "mode": { + "type": "string", + "enum": [ + "http-get", + "server-sent-events", + "websocket" + ], + "description": "The mode of operation for the plugin.", + "default": "http-get" + }, + "message_deserializer": { + "type": "string", + "enum": [ + "json", + "noop" + ], + "description": "The deserializer to use for the consumed messages.", + "default": "noop" + }, + "commit_strategy": { + "type": "string", + "enum": [ + "auto", + "off" + ], + "description": "The strategy to use for committing offsets.", + "default": "auto" + }, + "enforce_latest_offset_reset": { + "type": "boolean", + "description": "When true, 'latest' offset reset behaves correctly (starts from end). When false (default), maintains backwards compatibility where 'latest' acts like 'earliest'.", + "default": false + }, + "cluster_name": { + "type": "string", + "description": "An identifier for the Kafka cluster." + }, + "message_by_lua_functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates the message being sent to the client." + }, + "topics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "password": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + }, + "username": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-encrypted": true, + "x-referenceable": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + } + } + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + } + } + } + }, + "description": "The plugin-global schema registry configuration." + } + }, + "required": [ + "name" + ] + }, + "minLength": 1, + "description": "The Kafka topics and their configuration you want to consume from." + }, + "auto_offset_reset": { + "type": "string", + "enum": [ + "earliest", + "latest" + ], + "description": "The offset to start from when there is no initial offset in the consumer group.", + "default": "latest" + }, + "authentication": { + "type": "object", + "properties": { + "tokenauth": { + "type": "boolean", + "description": "Enable this to indicate `DelegationToken` authentication" + }, + "user": { + "type": "string", + "description": "Username for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "Password for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "strategy": { + "type": "string", + "enum": [ + "sasl" + ], + "description": "The authentication strategy for the plugin, the only option for the value is `sasl`." + }, + "mechanism": { + "type": "string", + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "description": "The SASL authentication mechanism. Supported options: `PLAIN` or `SCRAM-SHA-256`." + } + } + }, + "security": { + "type": "object", + "properties": { + "certificate_id": { + "type": "string", + "description": "UUID of certificate entity for mTLS authentication." + }, + "ssl": { + "type": "boolean", + "description": "Enables TLS." + }, + "ssl_verify": { + "type": "boolean", + "description": "When using TLS, this option enables verification of the certificate presented by the server.", + "default": true + } + } + } + }, + "required": [ + "bootstrap_servers", + "topics" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KafkaLog.json b/app/_schemas/ai-gateway/policies/KafkaLog.json new file mode 100644 index 00000000000..20af7068d20 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KafkaLog.json @@ -0,0 +1,460 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "config": { + "type": "object", + "properties": { + "producer_async": { + "type": "boolean", + "description": "Flag to enable asynchronous mode.", + "default": true + }, + "producer_request_limits_bytes_per_request": { + "type": "integer", + "description": "Maximum size of a Produce request in bytes.", + "default": 1048576 + }, + "timeout": { + "type": "integer", + "description": "Socket timeout in milliseconds.", + "default": 10000 + }, + "keepalive_enabled": { + "type": "boolean", + "default": false + }, + "authentication": { + "type": "object", + "properties": { + "mechanism": { + "type": "string", + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "description": "The SASL authentication mechanism. Supported options: `PLAIN`, `SCRAM-SHA-256` or `SCRAM-SHA-512`." + }, + "tokenauth": { + "type": "boolean", + "description": "Enable this to indicate `DelegationToken` authentication" + }, + "user": { + "type": "string", + "description": "Username for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "Password for SASL authentication.", + "x-encrypted": true, + "x-referenceable": true + }, + "strategy": { + "type": "string", + "enum": [ + "sasl" + ], + "description": "The authentication strategy for the plugin, the only option for the value is `sasl`." + } + } + }, + "security": { + "type": "object", + "properties": { + "certificate_id": { + "type": "string", + "description": "UUID of certificate entity for mTLS authentication." + }, + "ssl": { + "type": "boolean", + "description": "Enables TLS." + }, + "ssl_verify": { + "type": "boolean", + "description": "When using TLS, this option enables verification of the certificate presented by the server.", + "default": true + } + } + }, + "producer_async_buffering_limits_messages_in_memory": { + "type": "integer", + "description": "Maximum number of messages that can be buffered in memory in asynchronous mode.", + "default": 50000 + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + }, + "key_query_arg": { + "type": "string", + "description": "The request query parameter name that contains the Kafka message key. If specified, messages with the same key will be sent to the same Kafka partition, ensuring consistent ordering." + }, + "producer_request_acks": { + "type": "integer", + "enum": [ + -1, + 0, + 1 + ], + "description": "The number of acknowledgments the producer requires the leader to have received before considering a request complete. Allowed values: 0 for no acknowledgments; 1 for only the leader; and -1 for the full ISR (In-Sync Replica set).", + "default": 1 + }, + "producer_request_timeout": { + "type": "integer", + "description": "Time to wait for a Produce response in milliseconds", + "default": 2000 + }, + "producer_request_limits_messages_per_request": { + "type": "integer", + "description": "Maximum number of messages to include into a single Produce request.", + "default": 200 + }, + "producer_async_flush_timeout": { + "type": "integer", + "description": "Maximum time interval in milliseconds between buffer flushes in asynchronous mode.", + "default": 1000 + }, + "bootstrap_servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + }, + "required": [ + "host", + "port" + ] + }, + "description": "Set of bootstrap brokers in a `{host: host, port: port}` list format." + }, + "topic": { + "type": "string", + "description": "The Kafka topic to publish to." + }, + "keepalive": { + "type": "integer", + "default": 60000 + }, + "cluster_name": { + "type": "string", + "description": "An identifier for the Kafka cluster. By default, this field generates a random string. You can also set your own custom cluster identifier. If more than one Kafka plugin is configured without a `cluster_name` (that is, if the default autogenerated value is removed), these plugins will use the same producer, and by extension, the same cluster. Logs will be sent to the leader of the cluster." + }, + "producer_request_retries_max_attempts": { + "type": "integer", + "description": "Maximum number of retry attempts per single Produce request.", + "default": 10 + }, + "producer_request_retries_backoff_timeout": { + "type": "integer", + "description": "Backoff interval between retry attempts in milliseconds.", + "default": 100 + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "value_schema": { + "type": "object", + "properties": { + "subject_name": { + "type": "string", + "description": "The name of the subject" + }, + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + } + } + }, + "key_schema": { + "type": "object", + "properties": { + "subject_name": { + "type": "string", + "description": "The name of the subject" + }, + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + }, + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "basic": { + "type": "object", + "properties": { + "password": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + } + } + }, + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + } + } + } + } + } + }, + "description": "The plugin-global schema registry configuration. This can be overwritten by the topic configuration." + } + }, + "required": [ + "topic" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KafkaUpstream.json b/app/_schemas/ai-gateway/policies/KafkaUpstream.json new file mode 100644 index 00000000000..3fe2478f972 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KafkaUpstream.json @@ -0,0 +1,488 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "producer_request_acks": { + "type": "integer", + "enum": [ + -1, + 0, + 1 + ], + "description": "The number of acknowledgments the producer requires the leader to have received before considering a request complete. Allowed values: 0 for no acknowledgments; 1 for only the leader; and -1 for the full ISR (In-Sync Replica set).", + "default": 1 + }, + "producer_request_timeout": { + "type": "integer", + "description": "Time to wait for a Produce response in milliseconds.", + "default": 2000 + }, + "producer_request_limits_messages_per_request": { + "type": "integer", + "description": "Maximum number of messages to include into a single producer request.", + "default": 200 + }, + "producer_request_limits_bytes_per_request": { + "type": "integer", + "description": "Maximum size of a Produce request in bytes.", + "default": 1048576 + }, + "schema_registry": { + "type": "object", + "properties": { + "confluent": { + "type": "object", + "properties": { + "authentication": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "basic", + "none", + "oauth2" + ], + "description": "Authentication mode to use with the schema registry.", + "default": "none" + }, + "basic": { + "type": "object", + "properties": { + "username": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + }, + "password": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + } + }, + "required": [ + "password", + "username" + ] + }, + "oauth2": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "required": [ + "token_endpoint" + ] + }, + "oauth2_client": { + "type": "object", + "properties": { + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + }, + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + } + } + } + } + }, + "value_schema": { + "type": "object", + "properties": { + "subject_name": { + "type": "string", + "description": "The name of the subject" + }, + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + } + } + }, + "key_schema": { + "type": "object", + "properties": { + "subject_name": { + "type": "string", + "description": "The name of the subject" + }, + "schema_version": { + "type": "string", + "description": "The schema version to use for serialization/deserialization. Use 'latest' to always fetch the most recent version." + } + } + }, + "url": { + "type": "string", + "description": "The URL of the schema registry." + }, + "ttl": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "The TTL in seconds for the schema registry cache." + }, + "ssl_verify": { + "type": "boolean", + "description": "Set to false to disable SSL certificate verification when connecting to the schema registry.", + "default": true + } + } + } + }, + "description": "The plugin-global schema registry configuration. This can be overwritten by the topic configuration." + }, + "allowed_topics": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of allowed topic names to which messages can be sent. The default topic configured in the `topic` field is always allowed, regardless of its inclusion in `allowed_topics`." + }, + "topic": { + "type": "string", + "description": "The default Kafka topic to publish to if the query parameter defined in the `topics_query_arg` does not exist in the request" + }, + "keepalive": { + "type": "integer", + "description": "Keepalive timeout in milliseconds.", + "default": 60000 + }, + "keepalive_enabled": { + "type": "boolean", + "default": false + }, + "forward_method": { + "type": "boolean", + "description": "Include the request method in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "producer_request_retries_backoff_timeout": { + "type": "integer", + "description": "Backoff interval between retry attempts in milliseconds.", + "default": 100 + }, + "producer_async": { + "type": "boolean", + "description": "Flag to enable asynchronous mode.", + "default": true + }, + "topics_query_arg": { + "type": "string", + "description": "The request query parameter name that contains the topics to publish to" + }, + "key_query_arg": { + "type": "string", + "description": "The request query parameter name that contains the Kafka message key. If specified, messages with the same key will be sent to the same Kafka partition, ensuring consistent ordering." + }, + "timeout": { + "type": "integer", + "description": "Socket timeout in milliseconds.", + "default": 10000 + }, + "forward_uri": { + "type": "boolean", + "description": "Include the request URI and URI arguments (as in, query arguments) in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "cluster_name": { + "type": "string", + "description": "An identifier for the Kafka cluster. By default, this field generates a random string. You can also set your own custom cluster identifier. If more than one Kafka plugin is configured without a `cluster_name` (that is, if the default autogenerated value is removed), these plugins will use the same producer, and by extension, the same cluster. Logs will be sent to the leader of the cluster." + }, + "producer_async_flush_timeout": { + "type": "integer", + "description": "Maximum time interval in milliseconds between buffer flushes in asynchronous mode.", + "default": 1000 + }, + "producer_async_buffering_limits_messages_in_memory": { + "type": "integer", + "description": "Maximum number of messages that can be buffered in memory in asynchronous mode.", + "default": 50000 + }, + "authentication": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "sasl" + ], + "description": "The authentication strategy for the plugin, the only option for the value is `sasl`." + }, + "mechanism": { + "type": "string", + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "description": "The SASL authentication mechanism. Supported options: `PLAIN`, `SCRAM-SHA-256`, or `SCRAM-SHA-512`." + }, + "tokenauth": { + "type": "boolean", + "description": "Enable this to indicate `DelegationToken` authentication." + }, + "user": { + "type": "string", + "description": "Username for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "Password for SASL authentication.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "forward_body": { + "type": "boolean", + "description": "Include the request body in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": true + }, + "producer_request_retries_max_attempts": { + "type": "integer", + "description": "Maximum number of retry attempts per single Produce request.", + "default": 10 + }, + "bootstrap_servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + } + }, + "required": [ + "host", + "port" + ] + }, + "description": "Set of bootstrap brokers in a `{host: host, port: port}` list format." + }, + "security": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "When using TLS, this option enables verification of the certificate presented by the server.", + "default": true + }, + "certificate_id": { + "type": "string", + "description": "UUID of certificate entity for mTLS authentication." + }, + "ssl": { + "type": "boolean", + "description": "Enables TLS." + } + } + }, + "forward_headers": { + "type": "boolean", + "description": "Include the request headers in the message. At least one of these must be true: `forward_method`, `forward_uri`, `forward_headers`, `forward_body`.", + "default": false + }, + "message_by_lua_functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates the message being sent to the Kafka topic." + } + }, + "required": [ + "topic" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KeyAuth.json b/app/_schemas/ai-gateway/policies/KeyAuth.json new file mode 100644 index 00000000000..601c936b870 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KeyAuth.json @@ -0,0 +1,129 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "key_names": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "description": "Describes an array of parameter names where the plugin will look for a key. The key names may only contain [a-z], [A-Z], [0-9], [_] underscore, and [-] hyphen.", + "default": [ + "apikey" + ] + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request will fail with an authentication failure `4xx`." + }, + "key_in_header": { + "type": "boolean", + "description": "If enabled (default), the plugin reads the request header and tries to find the key in it.", + "default": true + }, + "key_in_query": { + "type": "boolean", + "description": "If enabled (default), the plugin reads the query parameter in the request and tries to find the key in it.", + "default": true + }, + "key_in_body": { + "type": "boolean", + "description": "If enabled, the plugin reads the request body. Supported MIME types: `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`.", + "default": false + }, + "run_on_preflight": { + "type": "boolean", + "description": "A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests are always allowed.", + "default": true + }, + "identity_realms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "scope": { + "type": "string", + "enum": [ + "cp", + "realm" + ] + }, + "id": { + "type": "string", + "description": "A string representing a UUID (universally unique identifier)." + }, + "region": { + "type": "string" + } + } + }, + "description": "A configuration of Konnect Identity Realms that indicate where to source a consumer from." + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin strips the credential from the request.", + "default": true + }, + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KeyAuthEnc.json b/app/_schemas/ai-gateway/policies/KeyAuthEnc.json new file mode 100644 index 00000000000..dda9de3a143 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KeyAuthEnc.json @@ -0,0 +1,106 @@ +{ + "properties": { + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + }, + "key_names": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "description": "Describes an array of parameter names where the plugin will look for a key. The client must send the authentication key in one of those key names, and the plugin will try to read the credential from a header, request body, or query string parameter with the same name. Key names may only contain [a-z], [A-Z], [0-9], [_] underscore, and [-] hyphen.", + "default": [ + "apikey" + ] + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin strips the credential from the request (i.e., the header, query string, or request body containing the key) before proxying it.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request will fail with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "key_in_header": { + "type": "boolean", + "description": "If enabled (default), the plugin reads the request header and tries to find the key in it.", + "default": true + }, + "key_in_query": { + "type": "boolean", + "description": "If enabled (default), the plugin reads the query parameter in the request and tries to find the key in it.", + "default": true + }, + "key_in_body": { + "type": "boolean", + "description": "If enabled, the plugin reads the request body (if said request has one and its MIME type is supported) and tries to find the key in it. Supported MIME types: `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`.", + "default": false + }, + "run_on_preflight": { + "type": "boolean", + "description": "A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests are always allowed.", + "default": true + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/KonnectApplicationAuth.json b/app/_schemas/ai-gateway/policies/KonnectApplicationAuth.json new file mode 100644 index 00000000000..75a99aca84f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/KonnectApplicationAuth.json @@ -0,0 +1,2429 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "v2_strategies": { + "type": "object", + "properties": { + "openid_connect": { + "type": "array", + "items": { + "type": "object", + "properties": { + "strategy_id": { + "type": "string", + "description": "The strategy id the config is tied to." + }, + "config": { + "type": "object", + "properties": { + "authenticated_groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains authenticated groups. This setting can be used together with ACL plugin, but it also enables IdP managed groups with other applications and integrations. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "token_headers_prefix": { + "type": "string", + "description": "Add a prefix to the token endpoint response headers before forwarding them to the downstream client." + }, + "forbidden_error_message": { + "type": "string", + "description": "The error message for the forbidden requests (when not using the redirection).", + "default": "Forbidden" + }, + "pushed_authorization_request_endpoint": { + "type": "string", + "description": "The pushed authorization endpoint. If set it overrides the value in `pushed_authorization_request_endpoint` returned by the discovery endpoint." + }, + "require_proof_key_for_code_exchange": { + "type": "boolean", + "description": "Forcibly enable or disable the proof key for code exchange. When not set the value is determined through the discovery using the value of `code_challenge_methods_supported`, and enabled automatically (in case the `code_challenge_methods_supported` is missing, the PKCE will not be enabled)." + }, + "session_memcached_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "The memcached port.", + "default": 11211 + }, + "upstream_headers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The name of the header." + }, + "path": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The path of the header value." + } + }, + "required": [ + "header", + "path" + ] + }, + "description": "The upstream claim to header mappings." + }, + "introspection_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The introspection endpoint authentication method: : `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "token_exchange_endpoint": { + "type": "string", + "description": "Endpoint used to perform the legacy token exchange." + }, + "session_cookie_domain": { + "type": "string", + "description": "The session cookie Domain flag." + }, + "upstream_access_token_header": { + "type": "string", + "description": "The upstream access token header.", + "default": "authorization:bearer" + }, + "downstream_headers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The name of the header." + }, + "path": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The path of the header value." + } + }, + "required": [ + "header", + "path" + ] + }, + "description": "The downstream claim to header mappings." + }, + "using_pseudo_issuer": { + "type": "boolean", + "description": "If the plugin uses a pseudo issuer. When set to true, the plugin will not discover the configuration from the issuer URL specified with `config.issuer`.", + "default": false + }, + "require_pushed_authorization_requests": { + "type": "boolean", + "description": "Forcibly enable or disable the pushed authorization requests. When not set the value is determined through the discovery using the value of `require_pushed_authorization_requests` (which defaults to `false`)." + }, + "reverify": { + "type": "boolean", + "description": "Specifies whether to always verify tokens stored in the session.", + "default": false + }, + "client_credentials_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the client credentials: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search from the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "cache_tokens_salt": { + "type": "string", + "description": "Salt used for generating the cache key that is used for caching the token endpoint requests." + }, + "auth_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Types of credentials/grants to enable.", + "default": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "authorization_query_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument values passed to the authorization endpoint." + }, + "session_remember_cookie_name": { + "type": "string", + "description": "Persistent session cookie name. Use with the `remember` configuration parameter.", + "default": "remember" + }, + "session_memcached_ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to memcached" + }, + "upstream_headers_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The upstream header claims. Only top level claims are supported." + }, + "proof_of_possession_mtls": { + "type": "string", + "enum": [ + "off", + "optional", + "strict" + ], + "description": "Enable mtls proof of possession. If set to strict, all tokens (from supported auth_methods: bearer, introspection, and session granted with bearer or introspection) are verified, if set to optional, only tokens that contain the certificate hash claim are verified. If the verification fails, the request will be rejected with 401.", + "default": "off" + }, + "session_audience": { + "type": "string", + "description": "The session audience, which is the intended target application. For example `\"my-application\"`.", + "default": "default" + }, + "dpop_proof_lifetime": { + "type": "number", + "description": "Specifies the lifetime in seconds of the DPoP proof. It determines how long the same proof can be used after creation. The creation time is determined by the nonce creation time if a nonce is used, and the iat claim otherwise.", + "default": 300 + }, + "client_alg": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS384", + "RS512" + ] + }, + "description": "The algorithm to use for client_secret_jwt (only HS***) or private_key_jwt authentication." + }, + "ssl_verify": { + "type": "boolean", + "description": "Verify identity provider server certificate. If set to `true`, the plugin uses the CA certificate set in the `kong.conf` config parameter `lua_ssl_trusted_certificate`.", + "default": true + }, + "unauthorized_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client on unauthorized requests." + }, + "audience_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences (`audience_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "authorization_cookie_domain": { + "type": "string", + "description": "The authorization cookie Domain flag." + }, + "token_post_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument names passed to the token endpoint." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The HTTP proxy authorization.", + "x-referenceable": true + }, + "introspection_accept": { + "type": "string", + "enum": [ + "application/json", + "application/jwt", + "application/token-introspection+jwt" + ], + "description": "The value of `Accept` header for introspection requests: - `application/json`: introspection response as JSON - `application/token-introspection+jwt`: introspection response as JWT (from the current IETF draft document) - `application/jwt`: introspection response as JWT (from the obsolete IETF draft document).", + "default": "application/json" + }, + "bearer_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "cookie", + "header", + "query" + ] + }, + "description": "Where to look for the bearer token: - `header`: search the `Authorization`, `access-token`, and `x-access-token` HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body - `cookie`: search the HTTP request cookies specified with `config.bearer_token_cookie_name`.", + "default": [ + "body", + "header", + "query" + ] + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for the requests by this plugin: - `1.1`: HTTP 1.1 (the default) - `1.0`: HTTP 1.0.", + "default": 1.1 + }, + "unauthorized_destroy_session": { + "type": "boolean", + "description": "Destroy any active session for the unauthorized requests.", + "default": true + }, + "upstream_refresh_token_header": { + "type": "string", + "description": "The upstream refresh token header." + }, + "ignore_signature": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "introspection", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Skip the token signature verification on certain grants: - `password`: OAuth password grant - `client_credentials`: OAuth client credentials grant - `authorization_code`: authorization code flow - `refresh_token`: OAuth refresh token grant - `session`: session cookie authentication - `introspection`: OAuth introspection - `userinfo`: OpenID Connect user info endpoint authentication.", + "default": [] + }, + "https_proxy": { + "type": "string", + "description": "The HTTPS proxy." + }, + "forbidden_destroy_session": { + "type": "boolean", + "description": "Destroy any active session for the forbidden requests.", + "default": true + }, + "session_remember_absolute_timeout": { + "type": "number", + "description": "Limits how long the persistent session can be renewed in seconds, until re-authentication is required. 0 disables the checks.", + "default": 2592000 + }, + "session_cookie_path": { + "type": "string", + "description": "The session cookie Path flag.", + "default": "/" + }, + "leeway": { + "type": "number", + "description": "Defines leeway time (in seconds) for `auth_time`, `exp`, `iat`, and `nbf` claims", + "default": 0 + }, + "discovery_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the discovery endpoint." + }, + "introspection_check_active": { + "type": "boolean", + "description": "Check that the introspection response has an `active` claim with a value of `true`.", + "default": true + }, + "session_idling_timeout": { + "type": "number", + "description": "Specifies how long the session can be inactive until it is considered invalid in seconds. 0 disables the checks and touching.", + "default": 900 + }, + "session_cookie_http_only": { + "type": "boolean", + "description": "Forbids JavaScript from accessing the cookie, for example, through the `Document.cookie` property.", + "default": true + }, + "session_storage": { + "type": "string", + "enum": [ + "cookie", + "memcache", + "memcached", + "redis" + ], + "description": "The session storage for session data: - `cookie`: stores session data with the session cookie (the session cannot be invalidated or revoked without changing session secret, but is stateless, and doesn't require a database) - `memcache`: stores session data in memcached - `redis`: stores session data in Redis.", + "default": "cookie" + }, + "response_mode": { + "type": "string", + "enum": [ + "form_post", + "form_post.jwt", + "fragment", + "fragment.jwt", + "jwt", + "query", + "query.jwt" + ], + "description": "Response mode passed to the authorization endpoint: - `query`: for parameters in query string - `form_post`: for parameters in request body - `fragment`: for parameters in uri fragment (rarely useful as the plugin itself cannot read it) - `query.jwt`, `form_post.jwt`, `fragment.jwt`: similar to `query`, `form_post` and `fragment` but the parameters are encoded in a JWT - `jwt`: shortcut that indicates the default encoding for the requested response type.", + "default": "query" + }, + "response_type": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The response type passed to the authorization endpoint.", + "default": [ + "code" + ] + }, + "token_post_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Pass extra arguments from the client to the OpenID-Connect plugin. If arguments exist, the client can pass them using: - Query parameters - Request Body - Request Header This parameter can be used with `scope` values, like this: `config.token_post_args_client=scope` In this case, the token would take the `scope` value from the query parameter or from the request body or from the header and send it to the token endpoint." + }, + "downstream_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The downstream header names for the claim values." + }, + "token_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the token endpoint." + }, + "password_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the username and password: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "upstream_id_token_header": { + "type": "string", + "description": "The upstream id token header." + }, + "login_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Enable login functionality with specified grants.", + "default": [ + "authorization_code" + ] + }, + "userinfo_query_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query arguments passed from the client to the user info endpoint." + }, + "timeout": { + "type": "number", + "description": "Network IO timeout in milliseconds.", + "default": 10000 + }, + "refresh_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the refresh token: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "tls_client_auth_ssl_verify": { + "type": "boolean", + "description": "Verify identity provider server certificate during mTLS client authentication.", + "default": true + }, + "unexpected_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client when unexpected errors happen with the requests." + }, + "session_memcached_ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the memcached server SSL certificate", + "default": true + }, + "upstream_introspection_jwt_header": { + "type": "string", + "description": "The upstream introspection JWT header." + }, + "consumer_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A path of strings representing the location of the claim in a nested object. For example, to map to `user.info.id`, set `[ \"user\", \"info\", \"id\" ]`." + }, + "description": "The claims used for consumer mapping. Each entry represents a claim path inside the token payload. The paths are evaluated in order, and the first matching claim is used." + }, + "run_on_preflight": { + "type": "boolean", + "description": "Specifies whether to run this plugin on pre-flight (`OPTIONS`) requests.", + "default": true + }, + "verify_parameters": { + "type": "boolean", + "description": "Verify plugin configuration against discovery.", + "default": false + }, + "authorization_cookie_name": { + "type": "string", + "description": "The authorization cookie name.", + "default": "authorization" + }, + "session_remember": { + "type": "boolean", + "description": "Enables or disables persistent sessions.", + "default": false + }, + "session_rolling_timeout": { + "type": "number", + "description": "Specifies how long the session can be used in seconds until it needs to be renewed. 0 disables the checks and rolling.", + "default": 3600 + }, + "downstream_headers_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The downstream header claims. Only top level claims are supported." + }, + "cluster_cache_redis": { + "type": "object", + "properties": { + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-encrypted": true, + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + } + } + }, + "redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "The redirect URI passed to the authorization and token endpoints." + }, + "logout_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "Where to redirect the client after the logout." + }, + "session_hash_subject": { + "type": "boolean", + "description": "When set to `true`, the value of subject is hashed before being stored. Only applies when `session_store_metadata` is enabled.", + "default": false + }, + "jwt_session_claim": { + "type": "string", + "description": "The claim to match against the JWT session cookie.", + "default": "sid" + }, + "client_secret": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The client secret.", + "x-encrypted": true + }, + "login_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "Where to redirect the client when `login_action` is set to `redirect`." + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint. If set it overrides the value in `token_endpoint` returned by the discovery endpoint." + }, + "revocation_endpoint": { + "type": "string", + "description": "The revocation endpoint. If set it overrides the value in `revocation_endpoint` returned by the discovery endpoint." + }, + "id_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the id token: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "downstream_refresh_token_header": { + "type": "string", + "description": "The downstream refresh token header." + }, + "logout_post_arg": { + "type": "string", + "description": "The request body argument that activates the logout." + }, + "introspection_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the introspection endpoint." + }, + "userinfo_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the user info endpoint." + }, + "upstream_introspection_header": { + "type": "string", + "description": "The upstream introspection header." + }, + "client_jwk": { + "type": "array", + "items": { + "type": "object", + "properties": { + "use": { + "type": "string" + }, + "x5c": { + "type": "array", + "items": { + "type": "string" + } + }, + "x5t#S256": { + "type": "string" + }, + "x": { + "type": "string" + }, + "d": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "p": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "q": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "dq": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + }, + "kty": { + "type": "string" + }, + "kid": { + "type": "string" + }, + "y": { + "type": "string" + }, + "crv": { + "type": "string" + }, + "n": { + "type": "string" + }, + "oth": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "t": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "key_ops": { + "type": "array", + "items": { + "type": "string" + } + }, + "alg": { + "type": "string" + }, + "e": { + "type": "string" + }, + "r": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "issuer": { + "type": "string" + }, + "x5u": { + "type": "string" + }, + "x5t": { + "type": "string" + }, + "k": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "dp": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "qi": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "description": "The JWK used for the private_key_jwt authentication." + }, + "roles_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the roles. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "roles" + ] + }, + "authorization_query_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument names passed to the authorization endpoint." + }, + "token_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the token endpoint." + }, + "introspection_post_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument names passed to the introspection endpoint." + }, + "userinfo_accept": { + "type": "string", + "enum": [ + "application/json", + "application/jwt" + ], + "description": "The value of `Accept` header for user info requests: - `application/json`: user info response as JSON - `application/jwt`: user info response as JWT (from the obsolete IETF draft document).", + "default": "application/json" + }, + "userinfo_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the user info endpoint." + }, + "mtls_introspection_endpoint": { + "type": "string", + "description": "Alias for the introspection endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "client_id": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The client id(s) that the plugin uses when it calls authenticated endpoints on the identity provider.", + "x-encrypted": true + }, + "token_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the token endpoint." + }, + "session_response_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "Set of headers to send to downstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. E.g. `[ \"id\", \"timeout\" ]` will set Session-Id and Session-Timeout response headers." + }, + "cache_ttl_neg": { + "type": "number", + "description": "The negative cache ttl in seconds." + }, + "authorization_rolling_timeout": { + "type": "number", + "description": "Specifies how long the session used for the authorization code flow can be used in seconds until it needs to be renewed. 0 disables the checks and rolling.", + "default": 600 + }, + "upstream_session_id_header": { + "type": "string", + "description": "The upstream session id header." + }, + "display_errors": { + "type": "boolean", + "description": "Display errors on failure responses.", + "default": false + }, + "expose_error_code": { + "type": "boolean", + "description": "Specifies whether to expose the error code header, as defined in RFC 6750. If an authorization request fails, this header is sent in the response. Set to `false` to disable.", + "default": true + }, + "login_redirect_mode": { + "type": "string", + "enum": [ + "fragment", + "query" + ], + "description": "Where to place `login_tokens` when using `redirect` `login_action`: - `query`: place tokens in query string - `fragment`: place tokens in url fragment (not readable by servers).", + "default": "fragment" + }, + "cache_ttl_max": { + "type": "number", + "description": "The maximum cache ttl in seconds (enforced)." + }, + "cache_ttl_min": { + "type": "number", + "description": "The minimum cache ttl in seconds (enforced)." + }, + "token_post_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument values passed to the token endpoint." + }, + "session_cookie_name": { + "type": "string", + "description": "The session cookie name.", + "default": "session" + }, + "downstream_access_token_jwk_header": { + "type": "string", + "description": "The downstream access token JWK header." + }, + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "Consumer fields used for mapping: - `id`: try to find the matching Consumer by `id` - `username`: try to find the matching Consumer by `username` - `custom_id`: try to find the matching Consumer by `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "rediscovery_lifetime": { + "type": "number", + "description": "Specifies how long (in seconds) the plugin waits between discovery attempts. Discovery is still triggered on an as-needed basis.", + "default": 30 + }, + "authorization_cookie_http_only": { + "type": "boolean", + "description": "Forbids JavaScript from accessing the cookie, for example, through the `Document.cookie` property.", + "default": true + }, + "token_headers_replay": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The names of token endpoint response headers to forward to the downstream client." + }, + "downstream_id_token_jwk_header": { + "type": "string", + "description": "The downstream id token JWK header." + }, + "revocation_token_param_name": { + "type": "string", + "description": "Designate token's parameter name for revocation.", + "default": "token" + }, + "cluster_cache_strategy": { + "type": "string", + "enum": [ + "off", + "redis" + ], + "description": "The strategy to use for the cluster cache. If set, the plugin will share cache with nodes configured with the same strategy backend. Currentlly only introspection cache is shared.", + "default": "off" + }, + "forbidden_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client on forbidden requests." + }, + "roles_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The roles (`roles_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "authorization_cookie_path": { + "type": "string", + "description": "The authorization cookie Path flag.", + "default": "/" + }, + "session_secret": { + "type": "string", + "description": "The session secret.", + "x-referenceable": true, + "x-encrypted": true + }, + "no_proxy": { + "type": "string", + "description": "Do not use proxy with these hosts." + }, + "session_cookie_secure": { + "type": "boolean", + "description": "Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks." + }, + "refresh_token_param_name": { + "type": "string", + "description": "The name of the parameter used to pass the refresh token." + }, + "downstream_id_token_header": { + "type": "string", + "description": "The downstream id token header." + }, + "search_user_info": { + "type": "boolean", + "description": "Specify whether to use the user info endpoint to get additional claims for consumer mapping, credential mapping, authenticated groups, and upstream and downstream headers.", + "default": false + }, + "audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the audience. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "aud" + ] + }, + "introspection_headers_values": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra header values passed to the introspection endpoint.", + "x-encrypted": true + }, + "cache_introspection": { + "type": "boolean", + "description": "Cache the introspection endpoint requests.", + "default": true + }, + "claims_forbidden": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If given, these claims are forbidden in the token payload." + }, + "max_age": { + "type": "number", + "description": "The maximum age (in seconds) compared to the `auth_time` claim." + }, + "id_token_param_name": { + "type": "string", + "description": "The name of the parameter used to pass the id token." + }, + "downstream_user_info_jwt_header": { + "type": "string", + "description": "The downstream user info JWT header (in case the user info returns a JWT response)." + }, + "consumer_groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim used for consumer groups mapping. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "session_remember_rolling_timeout": { + "type": "number", + "description": "Specifies how long the persistent session is considered valid in seconds. 0 disables the checks and rolling.", + "default": 604800 + }, + "mtls_revocation_endpoint": { + "type": "string", + "description": "Alias for the introspection endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "client_arg": { + "type": "string", + "description": "The client to use for this request (the selection is made with a request parameter with the same name).", + "default": "client_id" + }, + "scopes": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The scopes passed to the authorization and token endpoints.", + "default": [ + "openid" + ] + }, + "authorization_query_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query arguments passed from the client to the authorization endpoint." + }, + "introspection_post_args_client_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post arguments passed from the client headers to the introspection endpoint." + }, + "proof_of_possession_auth_methods_validation": { + "type": "boolean", + "description": "If set to true, only the auth_methods that are compatible with Proof of Possession (PoP) can be configured when PoP is enabled. If set to false, all auth_methods will be configurable and PoP checks will be silently skipped for those auth_methods that are not compatible with PoP.", + "default": true + }, + "upstream_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The upstream header names for the claim values." + }, + "logout_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "POST" + ] + }, + "description": "The request methods that can activate the logout: - `POST`: HTTP POST method - `GET`: HTTP GET method - `DELETE`: HTTP DELETE method.", + "default": [ + "DELETE", + "POST" + ] + }, + "proof_of_possession_dpop": { + "type": "string", + "enum": [ + "off", + "optional", + "strict" + ], + "description": "Enable Demonstrating Proof-of-Possession (DPoP). If set to strict, all request are verified despite the presence of the DPoP key claim (cnf.jkt). If set to optional, only tokens bound with DPoP's key are verified with the proof.", + "default": "off" + }, + "userinfo_endpoint": { + "type": "string", + "description": "The user info endpoint. If set it overrides the value in `userinfo_endpoint` returned by the discovery endpoint." + }, + "session_bind": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ip", + "scheme", + "user-agent" + ] + }, + "description": "Bind the session to data acquired from the HTTP request or connection." + }, + "credential_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim used to derive virtual credentials (e.g. to be consumed by the rate-limiting plugin), in case the consumer mapping is not used. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "sub" + ] + }, + "verify_claims": { + "type": "boolean", + "description": "Verify tokens for standard claims.", + "default": true + }, + "cache_tokens": { + "type": "boolean", + "description": "Cache the token endpoint requests.", + "default": true + }, + "session_memcached_host": { + "type": "string", + "description": "The memcached host.", + "default": "127.0.0.1" + }, + "logout_revoke": { + "type": "boolean", + "description": "Revoke tokens as part of the logout.\n\nFor more granular token revocation, you can also adjust the `logout_revoke_access_token` and `logout_revoke_refresh_token` parameters.", + "default": false + }, + "cache_ttl_resurrect": { + "type": "number", + "description": "The resurrection ttl in seconds." + }, + "http_proxy": { + "type": "string", + "description": "The HTTP proxy." + }, + "authorization_cookie_secure": { + "type": "boolean", + "description": "Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks." + }, + "verify_signature": { + "type": "boolean", + "description": "Verify signature of tokens.", + "default": true + }, + "cache_ttl": { + "type": "number", + "description": "The default cache ttl in seconds that is used in case the cached object does not specify the expiry.", + "default": 3600 + }, + "cache_token_exchange": { + "type": "boolean", + "description": "Cache the legacy token exchange endpoint requests.", + "default": true + }, + "cache_user_info": { + "type": "boolean", + "description": "Cache the user info requests.", + "default": true + }, + "groups_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The groups (`groups_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "introspection_post_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument values passed to the introspection endpoint." + }, + "session_memcached_socket": { + "type": "string", + "description": "The memcached unix socket path." + }, + "dpop_use_nonce": { + "type": "boolean", + "description": "Specifies whether to challenge the client with a nonce value for DPoP proof. When enabled it will also be used to calculate the DPoP proof lifetime.", + "default": false + }, + "domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The allowed values for the `hd` claim." + }, + "require_signed_request_object": { + "type": "boolean", + "description": "Forcibly enable or disable the usage of signed request object on authorization or pushed authorization endpoint. When not set the value is determined through the discovery using the value of `require_signed_request_object`, and enabled automatically (in case the `require_signed_request_object` is missing, the feature will not be enabled)." + }, + "userinfo_query_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument names passed to the user info endpoint." + }, + "redis": { + "type": "object", + "properties": { + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "prefix": { + "type": "string", + "description": "The Redis session key prefix." + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "socket": { + "type": "string", + "description": "The Redis unix socket path." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + } + } + }, + "consumer_groups_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer groups mapping fails.", + "default": false + }, + "session_memcached_prefix": { + "type": "string", + "description": "The memcached session key prefix." + }, + "logout_revoke_refresh_token": { + "type": "boolean", + "description": "Revoke the refresh token as part of the logout. Requires `logout_revoke` to be set to `true`.", + "default": true + }, + "introspection_post_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post arguments passed from the client to the introspection endpoint." + }, + "client_auth": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ] + }, + "description": "The default OpenID Connect client authentication method is 'client_secret_basic' (using 'Authorization: Basic' header), 'client_secret_post' (credentials in body), 'client_secret_jwt' (signed client assertion in body), 'private_key_jwt' (private key-signed assertion), 'tls_client_auth' (client certificate), 'self_signed_tls_client_auth' (self-signed client certificate), and 'none' (no authentication)." + }, + "scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The scopes (`scopes_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "session_store_metadata": { + "type": "boolean", + "description": "Configures whether or not session metadata should be stored. This metadata includes information about the active sessions for a specific audience belonging to a specific subject.", + "default": false + }, + "logout_query_arg": { + "type": "string", + "description": "The request query argument that activates the logout." + }, + "by_username_ignore_case": { + "type": "boolean", + "description": "If `consumer_by` is set to `username`, specify whether `username` can match consumers case-insensitively.", + "default": false + }, + "introspect_jwt_tokens": { + "type": "boolean", + "description": "Specifies whether to introspect the JWT access tokens (can be used to check for revocations).", + "default": false + }, + "jwt_session_cookie": { + "type": "string", + "description": "The name of the JWT session cookie." + }, + "bearer_token_cookie_name": { + "type": "string", + "description": "The name of the cookie in which the bearer token is passed." + }, + "downstream_introspection_jwt_header": { + "type": "string", + "description": "The downstream introspection JWT header." + }, + "token_exchange": { + "type": "object", + "properties": { + "request": { + "type": "object", + "properties": { + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Scopes used in the token exchange request. Values defined here override those defined in `config.scopes`." + }, + "empty_scopes": { + "type": "boolean", + "description": "Use empty scopes. Use this field to override scopes defined in `config.scopes`.", + "default": false + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Audiences used in the token exchange request. Values defined here override those defined in `config.audience`." + }, + "empty_audience": { + "type": "boolean", + "description": "Use empty audiences. Use this field to override audiences defined in `config.audience`.", + "default": false + } + }, + "description": "Parameters used in the token exchange request." + }, + "cache": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether to enable caching.", + "default": true + }, + "ttl": { + "type": "integer", + "description": "Cache ttl in seconds used when caching exchanged tokens, use it to override `conf.cache_ttl`. Token expiry will be used if shorter than this value." + } + }, + "description": "Cache support for token exchange" + }, + "subject_token_issuers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "issuer": { + "type": "string", + "description": "Tokens of whose iss claim matches this value will be exchanged." + }, + "conditions": { + "type": "object", + "properties": { + "has_scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "missing_scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "has_audience": { + "type": "array", + "items": { + "type": "string" + } + }, + "missing_audience": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "A tokens will only be exchange when it matches all these criteria. To exchanging tokens issued from a different issuer, conditions must not be defined; On the contrary, to exchange tokens issued from the target issuer itself, conditions must be defined." + } + }, + "required": [ + "issuer" + ] + }, + "minLength": 1, + "description": "Trusted token issuers from which the upstream may accept tokens to be exchanged. If a JWT bearer matches all the conditions of a subject token issuer item, the token will be exchanged." + } + }, + "required": [ + "subject_token_issuers" + ], + "description": "Details on how to accept tokens from other identity providers." + }, + "scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the scopes. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "scope" + ] + }, + "pushed_authorization_request_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The pushed authorization request endpoint authentication method: `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "introspection_endpoint": { + "type": "string", + "description": "The introspection endpoint. If set it overrides the value in `introspection_endpoint` returned by the discovery endpoint.", + "x-referenceable": true + }, + "downstream_user_info_header": { + "type": "string", + "description": "The downstream user info header." + }, + "login_tokens": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "access_token", + "id_token", + "introspection", + "refresh_token", + "tokens" + ] + }, + "description": "What tokens to include in `response` body or `redirect` query string or fragment: - `id_token`: include id token - `access_token`: include access token - `refresh_token`: include refresh token - `tokens`: include the full token endpoint response - `introspection`: include introspection response.", + "default": [ + "id_token" + ] + }, + "enable_hs_signatures": { + "type": "boolean", + "description": "Enable shared secret, for example, HS256, signatures (when disabled they will not be accepted).", + "default": false + }, + "resolve_distributed_claims": { + "type": "boolean", + "description": "Distributed claims are represented by the `_claim_names` and `_claim_sources` members of the JSON object containing the claims. If this parameter is set to `true`, the plugin explicitly resolves these distributed claims.", + "default": false + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audience passed to the authorization endpoint." + }, + "authorization_endpoint": { + "type": "string", + "description": "The authorization endpoint. If set it overrides the value in `authorization_endpoint` returned by the discovery endpoint." + }, + "revocation_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The revocation endpoint authentication method: : `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "session_cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.", + "default": "Lax" + }, + "upstream_user_info_header": { + "type": "string", + "description": "The upstream user info header." + }, + "upstream_user_info_jwt_header": { + "type": "string", + "description": "The upstream user info JWT header (in case the user info returns a JWT response)." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The HTTPS proxy authorization.", + "x-referenceable": true + }, + "introspection_token_param_name": { + "type": "string", + "description": "Designate token's parameter name for introspection.", + "default": "token" + }, + "jwks_endpoint": { + "type": "string", + "description": "Overrides the `jwks_uri` returned by discovery. Use when the IdP exposes a non-standard JWKS endpoint." + }, + "token_headers_grants": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ] + }, + "description": "Enable the sending of the token endpoint response headers only with certain grants: - `password`: with OAuth password grant - `client_credentials`: with OAuth client credentials grant - `authorization_code`: with authorization code flow - `refresh_token` with refresh token grant." + }, + "session_absolute_timeout": { + "type": "number", + "description": "Limits how long the session can be renewed in seconds, until re-authentication is required. 0 disables the checks.", + "default": 86400 + }, + "session_enforce_same_subject": { + "type": "boolean", + "description": "When set to `true`, audiences are forced to share the same subject.", + "default": false + }, + "downstream_session_id_header": { + "type": "string", + "description": "The downstream session id header." + }, + "consumer_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer mapping fails.", + "default": false + }, + "mtls_token_endpoint": { + "type": "string", + "description": "Alias for the token endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the groups. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "groups" + ] + }, + "introspection_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the introspection endpoint." + }, + "userinfo_query_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument values passed to the user info endpoint." + }, + "introspection_hint": { + "type": "string", + "description": "Introspection hint parameter value passed to the introspection endpoint.", + "default": "access_token" + }, + "unauthorized_error_message": { + "type": "string", + "description": "The error message for the unauthorized requests (when not using the redirection).", + "default": "Unauthorized" + }, + "login_action": { + "type": "string", + "enum": [ + "redirect", + "response", + "upstream" + ], + "description": "What to do after successful login: - `upstream`: proxy request to upstream service - `response`: terminate request with a response - `redirect`: redirect to a different location.", + "default": "upstream" + }, + "keepalive": { + "type": "boolean", + "description": "Use keepalive with the HTTP client.", + "default": true + }, + "end_session_endpoint": { + "type": "string", + "description": "The end session endpoint. If set it overrides the value in `end_session_endpoint` returned by the discovery endpoint." + }, + "userinfo_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the user info endpoint." + }, + "session_hash_storage_key": { + "type": "boolean", + "description": "When set to `true`, the storage key (session ID) is hashed for extra security. Hashing the storage key means it is impossible to decrypt data from the storage without a cookie.", + "default": false + }, + "upstream_access_token_jwk_header": { + "type": "string", + "description": "The upstream access token JWK header." + }, + "upstream_id_token_jwk_header": { + "type": "string", + "description": "The upstream id token JWK header." + }, + "downstream_access_token_header": { + "type": "string", + "description": "The downstream access token header." + }, + "hide_credentials": { + "type": "boolean", + "description": "Remove the credentials used for authentication from the request. If multiple credentials are sent with the same request, the plugin will remove those that were used for successful authentication.", + "default": true + }, + "discovery_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the discovery endpoint." + }, + "extra_jwks_uris": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "JWKS URIs whose public keys are trusted (in addition to the keys found with the discovery)." + }, + "issuers_allowed": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The issuers allowed to be present in the tokens (`iss` claim)." + }, + "preserve_query_args": { + "type": "boolean", + "description": "With this parameter, you can preserve request query arguments even when doing authorization code flow.", + "default": false + }, + "downstream_introspection_header": { + "type": "string", + "description": "The downstream introspection header." + }, + "disable_session": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Disable issuing the session cookie with the specified grants." + }, + "issuer": { + "type": "string", + "description": "The discovery endpoint (or the issuer identifier). When there is no discovery endpoint, please also configure `config.using_pseudo_issuer=true`.", + "x-referenceable": true + }, + "authorization_cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.", + "default": "Default" + }, + "token_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The token endpoint authentication method: `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "logout_uri_suffix": { + "type": "string", + "description": "The request URI suffix that activates the logout." + }, + "verify_nonce": { + "type": "boolean", + "description": "Verify nonce on authorization code flow.", + "default": true + }, + "token_cache_key_include_scope": { + "type": "boolean", + "description": "Include the scope in the token cache key, so token with different scopes are considered diffrent tokens.", + "default": false + }, + "tls_client_auth_cert_id": { + "type": "string", + "description": "ID of the Certificate entity representing the client certificate to use for mTLS client authentication for connections between Kong and the Auth Server." + }, + "session_request_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "Set of headers to send to upstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. E.g. `[ \"id\", \"timeout\" ]` will set Session-Id and Session-Timeout request headers." + }, + "refresh_tokens": { + "type": "boolean", + "description": "Specifies whether the plugin should try to refresh (soon to be) expired access tokens if the plugin has a `refresh_token` available.", + "default": true + }, + "logout_revoke_access_token": { + "type": "boolean", + "description": "Revoke the access token as part of the logout. Requires `logout_revoke` to be set to `true`.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value that functions as an “anonymous” consumer if authentication fails. If empty (default null), requests that fail authentication will return a `4xx` HTTP status code. This value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + } + }, + "required": [ + "issuer" + ], + "description": "openid-connect plugin configuration." + } + }, + "required": [ + "strategy_id" + ] + }, + "description": "List of openid_connect strategies." + }, + "key_auth": { + "type": "array", + "items": { + "type": "object", + "properties": { + "strategy_id": { + "type": "string", + "description": "The strategy id the config is tied to." + }, + "config": { + "type": "object", + "properties": { + "key_names": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "description": "The names of the headers containing the API key. You can specify multiple header names.", + "default": [ + "apikey" + ] + } + } + } + }, + "required": [ + "strategy_id" + ] + }, + "description": "List of key_auth strategies." + } + }, + "description": "The map of v2 strategies.", + "default": {} + }, + "key_names": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "description": "The names of the headers containing the API key. You can specify multiple header names.", + "default": [ + "apikey" + ] + }, + "auth_type": { + "type": "string", + "enum": [ + "key-auth", + "openid-connect", + "v2-strategies" + ], + "description": "The type of authentication to be performed. Possible values are: 'openid-connect', 'key-auth', 'v2-strategies'.", + "default": "openid-connect" + }, + "scope": { + "type": "string", + "description": "The unique scope identifier for the plugin configuration." + } + }, + "required": [ + "scope" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/LdapAuth.json b/app/_schemas/ai-gateway/policies/LdapAuth.json new file mode 100644 index 00000000000..53bae0bcc81 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/LdapAuth.json @@ -0,0 +1,137 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "ldap_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 389 + }, + "ldaps": { + "type": "boolean", + "description": "Set to `true` to connect using the LDAPS protocol (LDAP over TLS). When `ldaps` is configured, you must use port 636. If the `ldap` setting is enabled, ensure the `start_tls` setting is disabled.", + "default": false + }, + "start_tls": { + "type": "boolean", + "description": "Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` setting is disabled.", + "default": false + }, + "cache_ttl": { + "type": "number", + "description": "Cache expiry time in seconds.", + "default": 60 + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when waiting for connection with LDAP server.", + "default": 10000 + }, + "keepalive": { + "type": "number", + "description": "An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed.", + "default": 60000 + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure `4xx`." + }, + "header_type": { + "type": "string", + "description": "An optional string to use as part of the Authorization header", + "default": "ldap" + }, + "ldap_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "verify_ldap_host": { + "type": "boolean", + "description": "Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive.", + "default": true + }, + "base_dn": { + "type": "string", + "description": "Base DN as the starting point for the search; e.g., dc=example,dc=com" + }, + "attribute": { + "type": "string", + "description": "Attribute to be used to search the user; e.g. cn" + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request.", + "default": true + }, + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + } + }, + "required": [ + "attribute", + "base_dn", + "ldap_host" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/LdapAuthAdvanced.json b/app/_schemas/ai-gateway/policies/LdapAuthAdvanced.json new file mode 100644 index 00000000000..9b3897264ae --- /dev/null +++ b/app/_schemas/ai-gateway/policies/LdapAuthAdvanced.json @@ -0,0 +1,192 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + }, + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "username" + ] + }, + "description": "Whether to authenticate consumers based on `username`, `custom_id`, or both.", + "default": [ + "custom_id", + "username" + ] + }, + "groups_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The groups required to be present in the LDAP search result for successful authorization. This config parameter works in both **AND** / **OR** cases. - When `[\"group1 group2\"]` are in the same array indices, both `group1` AND `group2` need to be present in the LDAP search result. - When `[\"group1\", \"group2\"]` are in different array indices, either `group1` OR `group2` need to be present in the LDAP search result." + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to hide the credential to the upstream server. It will be removed by Kong before proxying the request.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request will fail with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`.", + "default": "" + }, + "ldap_host": { + "type": "string", + "description": "Host on which the LDAP server is running." + }, + "ldap_password": { + "type": "string", + "description": "The password to the LDAP server.", + "x-encrypted": true, + "x-referenceable": true + }, + "ldap_port": { + "type": "number", + "description": "TCP port where the LDAP server is listening. 389 is the default port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If `ldaps` is configured, you must use port 636.", + "default": 389 + }, + "ldaps": { + "type": "boolean", + "description": "Set it to `true` to use `ldaps`, a secure protocol (that can be configured to TLS) to connect to the LDAP server. When `ldaps` is configured, you must use port 636. If the `ldap` setting is enabled, ensure the `start_tls` setting is disabled.", + "default": false + }, + "base_dn": { + "type": "string", + "description": "Base DN as the starting point for the search; e.g., 'dc=example,dc=com'." + }, + "consumer_optional": { + "type": "boolean", + "description": "Whether consumer mapping is optional. If `consumer_optional=true`, the plugin will not attempt to associate a consumer with the LDAP authenticated user.", + "default": false + }, + "verify_ldap_host": { + "type": "boolean", + "description": "Set to `true` to authenticate LDAP server. The server certificate will be verified according to the CA certificates specified by the `lua_ssl_trusted_certificate` directive.", + "default": true + }, + "attribute": { + "type": "string", + "description": "Attribute to be used to search the user; e.g., \"cn\"." + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when waiting for connection with LDAP server.", + "default": 10000 + }, + "keepalive": { + "type": "number", + "description": "An optional value in milliseconds that defines how long an idle connection to LDAP server will live before being closed.", + "default": 60000 + }, + "group_base_dn": { + "type": "string", + "description": "Sets a distinguished name (DN) for the entry where LDAP searches for groups begin. This field is case-insensitive.',dc=com'." + }, + "group_name_attribute": { + "type": "string", + "description": "Sets the attribute holding the name of a group, typically called `name` (in Active Directory) or `cn` (in OpenLDAP). This field is case-insensitive." + }, + "group_member_attribute": { + "type": "string", + "description": "Sets the attribute holding the members of the LDAP group. This field is case-sensitive.", + "default": "memberOf" + }, + "bind_dn": { + "type": "string", + "description": "The DN to bind to. Used to perform LDAP search of user. This `bind_dn` should have permissions to search for the user being authenticated.", + "x-referenceable": true + }, + "start_tls": { + "type": "boolean", + "description": "Set it to `true` to issue StartTLS (Transport Layer Security) extended operation over `ldap` connection. If the `start_tls` setting is enabled, ensure the `ldaps` setting is disabled.", + "default": false + }, + "cache_ttl": { + "type": "number", + "description": "Cache expiry time in seconds.", + "default": 60 + }, + "header_type": { + "type": "string", + "description": "An optional string to use as part of the Authorization header. By default, a valid Authorization header looks like this: `Authorization: ldap base64(username:password)`. If `header_type` is set to \"basic\", then the Authorization header would be `Authorization: basic base64(username:password)`. Note that `header_type` can take any string, not just `'ldap'` and `'basic'`.", + "default": "ldap" + }, + "log_search_results": { + "type": "boolean", + "description": "Displays all the LDAP search results received from the LDAP server for debugging purposes. Not recommended to be enabled in a production environment.", + "default": false + } + }, + "required": [ + "attribute", + "base_dn", + "ldap_host" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Loggly.json b/app/_schemas/ai-gateway/policies/Loggly.json new file mode 100644 index 00000000000..c0296966df4 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Loggly.json @@ -0,0 +1,164 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "successful_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "server_errors_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "timeout": { + "type": "number", + "default": 10000 + }, + "log_level": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "client_errors_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "logs-01.loggly.com" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 514 + }, + "key": { + "type": "string", + "x-encrypted": true, + "x-referenceable": true + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "default": [ + "kong" + ] + } + }, + "required": [ + "key" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/MeteringAndBilling.json b/app/_schemas/ai-gateway/policies/MeteringAndBilling.json new file mode 100644 index 00000000000..cdc8407da55 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/MeteringAndBilling.json @@ -0,0 +1,217 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "ingest_endpoint": { + "type": "string", + "description": "The HTTP endpoint where usage events are sent.", + "x-referenceable": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Verify the TLS certificate presented by the ingest endpoint.", + "default": true + }, + "keepalive": { + "type": "number", + "description": "How long in milliseconds an idle connection to the ingest endpoint is kept open before being closed.", + "default": 60000 + }, + "queue": { + "type": "object", + "properties": { + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + }, + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + }, + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + } + } + }, + "attributes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "source": { + "type": "string", + "enum": [ + "header", + "query" + ], + "description": "Where to find this attribute in the request." + }, + "look_up_value_in": { + "type": "string", + "description": "The header name or query parameter that contains the value, e.g 'x-department-id'" + }, + "event_property_name": { + "type": "string", + "description": "The property name in the usage event data payload." + } + }, + "required": [ + "event_property_name", + "look_up_value_in", + "source" + ] + }, + "description": "Capture custom properties to the usage event data payload for pricing dimensions or reporting. Attributes add dimensions like provider, department or project that your billing model needs for tiered or per-dimension pricing." + }, + "subject": { + "type": "object", + "properties": { + "look_up_value_in": { + "type": "string", + "enum": [ + "application", + "consumer", + "header", + "query" + ], + "description": "Where to find the customer identifier in the request.", + "default": "consumer" + }, + "field": { + "type": "string", + "description": "The header name, query parameter, consumer field, or application field that contains the customer identifier, e.g. 'x-customer-id'" + } + }, + "description": "The subject identifies who gets billed for each request. Choose where the plugin should look for the customer identifier." + }, + "meter_api_requests": { + "type": "boolean", + "description": "Emit a usage event for each API Gateway request.", + "default": true + }, + "meter_ai_token_usage": { + "type": "boolean", + "description": "Emit events for LLM input and output tokens on AI Gateway requests.", + "default": true + }, + "api_token": { + "type": "string", + "description": "Bearer token for authenticating with the ingest endpoint.", + "x-referenceable": true, + "x-encrypted": true + }, + "timeout": { + "type": "number", + "description": "Maximum time in milliseconds to wait for a response from the ingest endpoint.", + "default": 10000 + } + }, + "required": [ + "api_token", + "ingest_endpoint" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Mocking.json b/app/_schemas/ai-gateway/policies/Mocking.json new file mode 100644 index 00000000000..af4e1741489 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Mocking.json @@ -0,0 +1,107 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "included_status_codes": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "A global list of the HTTP status codes that can only be selected and returned." + }, + "random_status_code": { + "type": "boolean", + "description": "Determines whether to randomly select an HTTP status code from the responses of the corresponding API method. The default value is `false`, which means the minimum HTTP status code is always selected and returned.", + "default": false + }, + "custom_base_path": { + "type": "string", + "description": "The base path to be used for path match evaluation. This value is ignored if `include_base_path` is set to `false`." + }, + "random_delay": { + "type": "boolean", + "description": "Enables a random delay in the mocked response. Introduces delays to simulate real-time response times by APIs.", + "default": false + }, + "min_delay_time": { + "type": "number", + "description": "The minimum value in seconds of delay time. Set this value when `random_delay` is enabled and you want to adjust the default. The value must be less than the `max_delay_time`.", + "default": 0.001 + }, + "include_base_path": { + "type": "boolean", + "description": "Indicates whether to include the base path when performing path match evaluation.", + "default": false + }, + "api_specification_filename": { + "type": "string", + "description": "The path and name of the specification file loaded into Kong Gateway's database. You cannot use this option for DB-less or hybrid mode." + }, + "api_specification": { + "type": "string", + "description": "The contents of the specification file. You must use this option for hybrid or DB-less mode. You can include the full specification as part of the configuration. In Kong Manager, you can copy and paste the contents of the spec directly into the `Config.Api Specification` text field." + }, + "max_delay_time": { + "type": "number", + "description": "The maximum value in seconds of delay time. Set this value when `random_delay` is enabled and you want to adjust the default. The value must be greater than the `min_delay_time`.", + "default": 1 + }, + "random_examples": { + "type": "boolean", + "description": "Randomly selects one example and returns it. This parameter requires the spec to have multiple examples configured.", + "default": false + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/MtlsAuth.json b/app/_schemas/ai-gateway/policies/MtlsAuth.json new file mode 100644 index 00000000000..059381fbfe9 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/MtlsAuth.json @@ -0,0 +1,178 @@ +{ + "properties": { + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "http_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "skip_consumer_lookup": { + "type": "boolean", + "description": "Skip consumer lookup once certificate is trusted against the configured CA list.", + "default": false + }, + "authenticated_group_by": { + "type": "string", + "enum": [ + "CN", + "DN" + ], + "description": "Certificate property to use as the authenticated group. Valid values are `CN` (Common Name) or `DN` (Distinguished Name). Once `skip_consumer_lookup` is applied, any client with a valid certificate can access the Service/API. To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create allowed or denied groups of users.", + "default": "CN" + }, + "http_timeout": { + "type": "number", + "description": "HTTP timeout threshold in milliseconds when communicating with the OCSP server or downloading CRL.", + "default": 30000 + }, + "https_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "cache_ttl": { + "type": "number", + "description": "Cache expiry time in seconds.", + "default": 60 + }, + "cert_cache_ttl": { + "type": "number", + "description": "The length of time in seconds between refreshes of the revocation check status cache.", + "default": 60000 + }, + "http_proxy_host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "https_proxy_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "allow_partial_chain": { + "type": "boolean", + "description": "Allow certificate verification with only an intermediate certificate. When this is enabled, you don't need to upload the full chain to Kong Certificates.", + "default": false + }, + "default_consumer": { + "type": "string", + "description": "The UUID or username of the consumer to use when a trusted client certificate is presented but no consumer matches. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "ssl_verify": { + "type": "boolean", + "description": "This option enables verification of the certificate presented by the server of the OCSP responder's URL and by the server of the CRL Distribution Point.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "username" + ] + }, + "description": "Whether to match the subject name of the client-supplied certificate against consumer's `username` and/or `custom_id` attribute. If set to `[]` (the empty array), then auto-matching is disabled.", + "default": [ + "custom_id", + "username" + ] + }, + "ca_certificates": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of CA Certificates strings to use as Certificate Authorities (CA) when validating a client certificate. At least one is required but you can specify as many as needed. The value of this array is comprised of primary keys (`id`)." + }, + "san_dirname_matcher": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specifies a list of Subject Alternative Name (SAN) DirectoryName attributes to use for consumer lookup. Applicable only when `skip_consumer_lookup` is false. Supported formats: OID, Long Name, or Short Name. Examples: `commonName` (Long Name), `CN` (Short Name), `2.5.4.3` (OID). If left empty (default), all attributes present in the SAN DirectoryName extension are used. The matcher is case sensitive.", + "default": [] + }, + "revocation_check_mode": { + "type": "string", + "enum": [ + "IGNORE_CA_ERROR", + "SKIP", + "STRICT" + ], + "description": "Controls client certificate revocation check behavior. If set to `SKIP`, no revocation check is performed. If set to `IGNORE_CA_ERROR`, the plugin respects the revocation status when either OCSP or CRL URL is set, and doesn't fail on network issues. If set to `STRICT`, the plugin only treats the certificate as valid when it's able to verify the revocation status.", + "default": "IGNORE_CA_ERROR" + }, + "send_ca_dn": { + "type": "boolean", + "description": "Sends the distinguished names (DN) of the configured CA list in the TLS handshake message.", + "default": false + } + }, + "required": [ + "ca_certificates" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/OasValidation.json b/app/_schemas/ai-gateway/policies/OasValidation.json new file mode 100644 index 00000000000..d4409d22362 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/OasValidation.json @@ -0,0 +1,142 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "validate_request_body": { + "type": "boolean", + "description": "If set to true, validates the request body content against the API specification.", + "default": true + }, + "validate_request_query_params": { + "type": "boolean", + "description": "If set to true, validates query parameters against the API specification.", + "default": true + }, + "query_parameter_check": { + "type": "boolean", + "description": "If set to true, checks if query parameters in the request exist in the API specification.", + "default": false + }, + "validate_request_uri_params": { + "type": "boolean", + "description": "If set to true, validates URI parameters in the request against the API specification.", + "default": true + }, + "api_spec_encoded": { + "type": "boolean", + "description": "Indicates whether the api_spec is URI-Encoded.", + "default": true + }, + "api_spec": { + "type": "string", + "description": "The API specification defined using either Swagger or the OpenAPI. This can be either a JSON or YAML based file. If using a YAML file, the spec needs to be URI-Encoded to preserve the YAML format." + }, + "notify_only_request_validation_failure": { + "type": "boolean", + "description": "If set to true, notifications via event hooks are enabled, but request based validation failures don't affect the request flow.", + "default": false + }, + "validate_response_body": { + "type": "boolean", + "description": "If set to true, validates the response from the upstream services against the API specification. If validation fails, it results in an `HTTP 406 Not Acceptable` status code.", + "default": false + }, + "notify_only_response_body_validation_failure": { + "type": "boolean", + "description": "If set to true, notifications via event hooks are enabled, but response validation failures don't affect the response flow.", + "default": false + }, + "allowed_header_parameters": { + "type": "string", + "description": "List of header parameters in the request that will be ignored when performing HTTP header validation. These are additional headers added to an API request beyond those defined in the API specification. For example, you might include the HTTP header `User-Agent`, which lets servers and network peers identify the application, operating system, vendor, and/or version of the requesting user agent.", + "default": "Host,Content-Type,User-Agent,Accept,Content-Length" + }, + "custom_base_path": { + "type": "string", + "description": "The base path to be used for path match evaluation. This value is ignored if `include_base_path` is set to `false`." + }, + "verbose_response": { + "type": "boolean", + "description": "If set to true, returns a detailed error message for invalid requests \u0026 responses. This is useful while testing.", + "default": false + }, + "validate_request_header_params": { + "type": "boolean", + "description": "If set to true, validates HTTP header parameters against the API specification.", + "default": true + }, + "header_parameter_check": { + "type": "boolean", + "description": "If set to true, checks if HTTP header parameters in the request exist in the API specification.", + "default": false + }, + "include_base_path": { + "type": "boolean", + "description": "Indicates whether to include the base path when performing path match evaluation.", + "default": false + }, + "collect_all_errors": { + "type": "boolean", + "description": "If set to true, collects all validation errors instead of stopping at the first error. Note: Enabling this option with OpenAPI 3.0 will affect performance.", + "default": false + } + }, + "required": [ + "api_spec" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Oauth2.json b/app/_schemas/ai-gateway/policies/Oauth2.json new file mode 100644 index 00000000000..ab2bd0e529b --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Oauth2.json @@ -0,0 +1,158 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "realm": { + "type": "string", + "description": "When authentication fails the plugin sends `WWW-Authenticate` header with `realm` attribute value." + }, + "enable_authorization_code": { + "type": "boolean", + "description": "An optional boolean value to enable the three-legged Authorization Code flow (RFC 6742 Section 4.1).", + "default": false + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service.", + "default": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Describes an array of scope names that will be available to the end user. If `mandatory_scope` is set to `true`, then `scopes` are required." + }, + "mandatory_scope": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to require at least one `scope` to be authorized by the end user.", + "default": false + }, + "token_expiration": { + "type": "number", + "description": "An optional integer value telling the plugin how many seconds a token should last, after which the client will need to refresh the token. Set to `0` to disable the expiration.", + "default": 7200 + }, + "enable_client_credentials": { + "type": "boolean", + "description": "An optional boolean value to enable the Client Credentials Grant flow (RFC 6742 Section 4.4).", + "default": false + }, + "global_credentials": { + "type": "boolean", + "description": "An optional boolean value that allows using the same OAuth credentials generated by the plugin with any other service whose OAuth 2.0 plugin configuration also has `config.global_credentials=true`.", + "default": false + }, + "pkce": { + "type": "string", + "enum": [ + "lax", + "none", + "strict" + ], + "description": "Specifies a mode of how the Proof Key for Code Exchange (PKCE) should be handled by the plugin.", + "default": "lax" + }, + "enable_implicit_grant": { + "type": "boolean", + "description": "An optional boolean value to enable the Implicit Grant flow which allows to provision a token as a result of the authorization process (RFC 6742 Section 4.2).", + "default": false + }, + "accept_http_if_already_terminated": { + "type": "boolean", + "description": "Accepts HTTPs requests that have already been terminated by a proxy or load balancer.", + "default": false + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails." + }, + "refresh_token_ttl": { + "type": "number", + "maximum": 100000000, + "minimum": 0, + "description": "Time-to-live value for data", + "default": 1209600 + }, + "persistent_refresh_token": { + "type": "boolean", + "default": false + }, + "provision_key": { + "type": "string", + "description": "The unique key the plugin has generated when it has been added to the Service.", + "x-encrypted": true + }, + "enable_password_grant": { + "type": "boolean", + "description": "An optional boolean value to enable the Resource Owner Password Credentials Grant flow (RFC 6742 Section 4.3).", + "default": false + }, + "auth_header_name": { + "type": "string", + "description": "The name of the header that is supposed to carry the access token.", + "default": "authorization" + }, + "reuse_refresh_token": { + "type": "boolean", + "description": "An optional boolean value that indicates whether an OAuth refresh token is reused when refreshing an access token.", + "default": false + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Oauth2Introspection.json b/app/_schemas/ai-gateway/policies/Oauth2Introspection.json new file mode 100644 index 00000000000..e7e18a62ebe --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Oauth2Introspection.json @@ -0,0 +1,139 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "ttl": { + "type": "number", + "description": "The TTL in seconds for the introspection response. Set to 0 to disable the expiration.", + "default": 30 + }, + "timeout": { + "type": "integer", + "description": "An optional timeout in milliseconds when sending data to the upstream server.", + "default": 10000 + }, + "keepalive": { + "type": "integer", + "description": "An optional value in milliseconds that defines how long an idle connection lives before being closed.", + "default": 60000 + }, + "introspect_request": { + "type": "boolean", + "description": "A boolean indicating whether to forward information about the current downstream request to the introspect endpoint. If true, headers `X-Request-Path` and `X-Request-Http-Method` will be inserted into the introspect request.", + "default": false + }, + "run_on_preflight": { + "type": "boolean", + "description": "A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests will always be allowed.", + "default": true + }, + "custom_introspection_headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "A list of custom headers to be added in the introspection request.", + "default": {} + }, + "custom_claims_forward": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of custom claims to be forwarded from the introspection response to the upstream request. Claims are forwarded in headers with prefix `X-Credential-{claim-name}`.", + "default": [] + }, + "introspection_url": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "token_type_hint": { + "type": "string", + "description": "The `token_type_hint` value to associate to introspection requests." + }, + "authorization_value": { + "type": "string", + "description": "The value to set as the `Authorization` header when querying the introspection endpoint. This depends on the OAuth 2.0 server, but usually is the `client_id` and `client_secret` as a Base64-encoded Basic Auth string (`Basic MG9hNWl...`).", + "x-referenceable": true, + "x-encrypted": true + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to hide the credential to the upstream API server. It will be removed by Kong before proxying the request.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`.", + "default": "" + }, + "consumer_by": { + "type": "string", + "enum": [ + "client_id", + "username" + ], + "description": "A string indicating whether to associate OAuth2 `username` or `client_id` with the consumer's username. OAuth2 `username` is mapped to a consumer's `username` field, while an OAuth2 `client_id` maps to a consumer's `custom_id`.", + "default": "username" + } + }, + "required": [ + "authorization_value", + "introspection_url" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Opa.json b/app/_schemas/ai-gateway/policies/Opa.json new file mode 100644 index 00000000000..57eabe4f0b9 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Opa.json @@ -0,0 +1,113 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "opa_path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes)." + }, + "include_route_in_opa_input": { + "type": "boolean", + "description": "If set to true, the Kong Gateway Route object in use for the current request is included as input to OPA.", + "default": false + }, + "include_uri_captures_in_opa_input": { + "type": "boolean", + "description": "If set to true, the regex capture groups captured on the Kong Gateway Route's path field in the current request (if any) are included as input to OPA.", + "default": false + }, + "opa_protocol": { + "type": "string", + "enum": [ + "http", + "https" + ], + "description": "The protocol to use when talking to Open Policy Agent (OPA) server. Allowed protocols are `http` and `https`.", + "default": "http" + }, + "include_service_in_opa_input": { + "type": "boolean", + "description": "If set to true, the Kong Gateway Service object in use for the current request is included as input to OPA.", + "default": false + }, + "include_consumer_in_opa_input": { + "type": "boolean", + "description": "If set to true, the Kong Gateway Consumer object in use for the current request (if any) is included as input to OPA.", + "default": false + }, + "include_body_in_opa_input": { + "type": "boolean", + "default": false + }, + "include_parsed_json_body_in_opa_input": { + "type": "boolean", + "description": "If set to true and the `Content-Type` header of the current request is `application/json`, the request body will be JSON decoded and the decoded struct is included as input to OPA.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, the OPA certificate will be verified according to the CA certificates specified in lua_ssl_trusted_certificate.", + "default": true + }, + "opa_host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "localhost" + }, + "opa_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 8181 + } + }, + "required": [ + "opa_path" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/OpenidConnect.json b/app/_schemas/ai-gateway/policies/OpenidConnect.json new file mode 100644 index 00000000000..18631f8344f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/OpenidConnect.json @@ -0,0 +1,2360 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "userinfo_query_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument names passed to the user info endpoint." + }, + "scopes": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The scopes passed to the authorization and token endpoints.", + "default": [ + "openid" + ] + }, + "userinfo_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the user info endpoint." + }, + "session_secret": { + "type": "string", + "description": "The session secret.", + "x-encrypted": true, + "x-referenceable": true + }, + "session_remember": { + "type": "boolean", + "description": "Enables or disables persistent sessions.", + "default": false + }, + "session_cookie_domain": { + "type": "string", + "description": "The session cookie Domain flag." + }, + "session_bind": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ip", + "scheme", + "user-agent" + ] + }, + "description": "Bind the session to data acquired from the HTTP request or connection." + }, + "session_memcached_prefix": { + "type": "string", + "description": "The memcached session key prefix." + }, + "downstream_headers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The name of the header." + }, + "path": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The path of the header value." + } + }, + "required": [ + "header", + "path" + ] + }, + "description": "The downstream claim to header mappings." + }, + "pushed_authorization_request_endpoint": { + "type": "string", + "description": "The pushed authorization endpoint. If set it overrides the value in `pushed_authorization_request_endpoint` returned by the discovery endpoint." + }, + "session_rolling_timeout": { + "type": "number", + "description": "Specifies how long the session can be used in seconds until it needs to be renewed. 0 disables the checks and rolling.", + "default": 3600 + }, + "session_absolute_timeout": { + "type": "number", + "description": "Limits how long the session can be renewed in seconds, until re-authentication is required. 0 disables the checks.", + "default": 86400 + }, + "downstream_headers_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The downstream header claims. Only top level claims are supported." + }, + "downstream_session_id_header": { + "type": "string", + "description": "The downstream session id header." + }, + "cache_ttl_min": { + "type": "number", + "description": "The minimum cache ttl in seconds (enforced)." + }, + "hide_credentials": { + "type": "boolean", + "description": "Remove the credentials used for authentication from the request. If multiple credentials are sent with the same request, the plugin will remove those that were used for successful authentication.", + "default": true + }, + "display_errors": { + "type": "boolean", + "description": "Display errors on failure responses.", + "default": false + }, + "client_arg": { + "type": "string", + "description": "The client to use for this request (the selection is made with a request parameter with the same name).", + "default": "client_id" + }, + "token_headers_grants": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "password", + "refresh_token" + ] + }, + "description": "Enable the sending of the token endpoint response headers only with certain grants: - `password`: with OAuth password grant - `client_credentials`: with OAuth client credentials grant - `authorization_code`: with authorization code flow - `refresh_token` with refresh token grant." + }, + "logout_revoke_access_token": { + "type": "boolean", + "description": "Revoke the access token as part of the logout. Requires `logout_revoke` to be set to `true`.", + "default": true + }, + "revocation_token_param_name": { + "type": "string", + "description": "Designate token's parameter name for revocation.", + "default": "token" + }, + "credential_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim used to derive virtual credentials (e.g. to be consumed by the rate-limiting plugin), in case the consumer mapping is not used. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "sub" + ] + }, + "unexpected_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client when unexpected errors happen with the requests." + }, + "ssl_verify": { + "type": "boolean", + "description": "Verify identity provider server certificate. If set to `true`, the plugin uses the CA certificate set in the `kong.conf` config parameter `lua_ssl_trusted_certificate`.", + "default": true + }, + "token_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the token endpoint." + }, + "downstream_refresh_token_header": { + "type": "string", + "description": "The downstream refresh token header." + }, + "consumer_groups_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer groups mapping fails.", + "default": false + }, + "extra_jwks_uris": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "JWKS URIs whose public keys are trusted (in addition to the keys found with the discovery)." + }, + "upstream_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The upstream header names for the claim values." + }, + "downstream_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The downstream header names for the claim values." + }, + "cluster_cache_strategy": { + "type": "string", + "enum": [ + "off", + "redis" + ], + "description": "The strategy to use for the cluster cache. If set, the plugin will share cache with nodes configured with the same strategy backend. Currentlly only introspection cache is shared.", + "default": "off" + }, + "introspect_jwt_tokens": { + "type": "boolean", + "description": "Specifies whether to introspect the JWT access tokens (can be used to check for revocations).", + "default": false + }, + "login_action": { + "type": "string", + "enum": [ + "redirect", + "response", + "upstream" + ], + "description": "What to do after successful login: - `upstream`: proxy request to upstream service - `response`: terminate request with a response - `redirect`: redirect to a different location.", + "default": "upstream" + }, + "login_tokens": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "access_token", + "id_token", + "introspection", + "refresh_token", + "tokens" + ] + }, + "description": "What tokens to include in `response` body or `redirect` query string or fragment: - `id_token`: include id token - `access_token`: include access token - `refresh_token`: include refresh token - `tokens`: include the full token endpoint response - `introspection`: include introspection response.", + "default": [ + "id_token" + ] + }, + "cache_ttl": { + "type": "number", + "description": "The default cache ttl in seconds that is used in case the cached object does not specify the expiry.", + "default": 3600 + }, + "authorization_cookie_path": { + "type": "string", + "description": "The authorization cookie Path flag.", + "default": "/" + }, + "client_auth": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ] + }, + "description": "The default OpenID Connect client authentication method is 'client_secret_basic' (using 'Authorization: Basic' header), 'client_secret_post' (credentials in body), 'client_secret_jwt' (signed client assertion in body), 'private_key_jwt' (private key-signed assertion), 'tls_client_auth' (client certificate), 'self_signed_tls_client_auth' (self-signed client certificate), and 'none' (no authentication)." + }, + "domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The allowed values for the `hd` claim." + }, + "token_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the token endpoint." + }, + "end_session_endpoint": { + "type": "string", + "description": "The end session endpoint. If set it overrides the value in `end_session_endpoint` returned by the discovery endpoint." + }, + "upstream_access_token_jwk_header": { + "type": "string", + "description": "The upstream access token JWK header." + }, + "unauthorized_error_message": { + "type": "string", + "description": "The error message for the unauthorized requests (when not using the redirection).", + "default": "Unauthorized" + }, + "resolve_distributed_claims": { + "type": "boolean", + "description": "Distributed claims are represented by the `_claim_names` and `_claim_sources` members of the JSON object containing the claims. If this parameter is set to `true`, the plugin explicitly resolves these distributed claims.", + "default": false + }, + "authorization_cookie_secure": { + "type": "boolean", + "description": "Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks." + }, + "timeout": { + "type": "number", + "description": "Network IO timeout in milliseconds.", + "default": 10000 + }, + "id_token_param_name": { + "type": "string", + "description": "The name of the parameter used to pass the id token." + }, + "upstream_refresh_token_header": { + "type": "string", + "description": "The upstream refresh token header." + }, + "cache_ttl_neg": { + "type": "number", + "description": "The negative cache ttl in seconds." + }, + "session_cookie_name": { + "type": "string", + "description": "The session cookie name.", + "default": "session" + }, + "session_cookie_secure": { + "type": "boolean", + "description": "Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks." + }, + "refresh_token_param_name": { + "type": "string", + "description": "The name of the parameter used to pass the refresh token." + }, + "token_post_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument values passed to the token endpoint." + }, + "dpop_use_nonce": { + "type": "boolean", + "description": "Specifies whether to challenge the client with a nonce value for DPoP proof. When enabled it will also be used to calculate the DPoP proof lifetime.", + "default": false + }, + "forbidden_error_message": { + "type": "string", + "description": "The error message for the forbidden requests (when not using the redirection).", + "default": "Forbidden" + }, + "session_memcached_socket": { + "type": "string", + "description": "The memcached unix socket path." + }, + "client_alg": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ES256", + "ES384", + "ES512", + "EdDSA", + "HS256", + "HS384", + "HS512", + "PS256", + "PS384", + "PS512", + "RS256", + "RS384", + "RS512" + ] + }, + "description": "The algorithm to use for client_secret_jwt (only HS***) or private_key_jwt authentication." + }, + "login_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "Where to redirect the client when `login_action` is set to `redirect`." + }, + "authorization_cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.", + "default": "Default" + }, + "jwt_session_claim": { + "type": "string", + "description": "The claim to match against the JWT session cookie.", + "default": "sid" + }, + "token_headers_replay": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The names of token endpoint response headers to forward to the downstream client." + }, + "upstream_id_token_jwk_header": { + "type": "string", + "description": "The upstream id token JWK header." + }, + "logout_query_arg": { + "type": "string", + "description": "The request query argument that activates the logout." + }, + "cache_ttl_max": { + "type": "number", + "description": "The maximum cache ttl in seconds (enforced)." + }, + "logout_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "description": "Where to redirect the client after the logout." + }, + "authorization_cookie_domain": { + "type": "string", + "description": "The authorization cookie Domain flag." + }, + "token_post_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument names passed to the token endpoint." + }, + "upstream_access_token_header": { + "type": "string", + "description": "The upstream access token header.", + "default": "authorization:bearer" + }, + "downstream_id_token_header": { + "type": "string", + "description": "The downstream id token header." + }, + "cache_tokens": { + "type": "boolean", + "description": "Cache the token endpoint requests.", + "default": true + }, + "rediscovery_lifetime": { + "type": "number", + "description": "Specifies how long (in seconds) the plugin waits between discovery attempts. Discovery is still triggered on an as-needed basis.", + "default": 30 + }, + "session_store_metadata": { + "type": "boolean", + "description": "Configures whether or not session metadata should be stored. This metadata includes information about the active sessions for a specific audience belonging to a specific subject.", + "default": false + }, + "https_proxy_authorization": { + "type": "string", + "description": "The HTTPS proxy authorization.", + "x-referenceable": true + }, + "tls_client_auth_ssl_verify": { + "type": "boolean", + "description": "Verify identity provider server certificate during mTLS client authentication.", + "default": true + }, + "logout_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "POST" + ] + }, + "description": "The request methods that can activate the logout: - `POST`: HTTP POST method - `GET`: HTTP GET method - `DELETE`: HTTP DELETE method.", + "default": [ + "DELETE", + "POST" + ] + }, + "introspection_post_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument values passed to the introspection endpoint." + }, + "upstream_headers_claims": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The upstream header claims. Only top level claims are supported." + }, + "downstream_access_token_jwk_header": { + "type": "string", + "description": "The downstream access token JWK header." + }, + "logout_post_arg": { + "type": "string", + "description": "The request body argument that activates the logout." + }, + "issuer": { + "type": "string", + "description": "The discovery endpoint (or the issuer identifier). When there is no discovery endpoint, please also configure `config.using_pseudo_issuer=true`.", + "x-referenceable": true + }, + "require_signed_request_object": { + "type": "boolean", + "description": "Forcibly enable or disable the usage of signed request object on authorization or pushed authorization endpoint. When not set the value is determined through the discovery using the value of `require_signed_request_object`, and enabled automatically (in case the `require_signed_request_object` is missing, the feature will not be enabled)." + }, + "userinfo_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the user info endpoint." + }, + "session_memcached_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "The memcached port.", + "default": 11211 + }, + "proof_of_possession_dpop": { + "type": "string", + "enum": [ + "off", + "optional", + "strict" + ], + "description": "Enable Demonstrating Proof-of-Possession (DPoP). If set to strict, all request are verified despite the presence of the DPoP key claim (cnf.jkt). If set to optional, only tokens bound with DPoP's key are verified with the proof.", + "default": "off" + }, + "refresh_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the refresh token: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "introspection_hint": { + "type": "string", + "description": "Introspection hint parameter value passed to the introspection endpoint.", + "default": "access_token" + }, + "session_remember_absolute_timeout": { + "type": "number", + "description": "Limits how long the persistent session can be renewed in seconds, until re-authentication is required. 0 disables the checks.", + "default": 2592000 + }, + "session_cookie_path": { + "type": "string", + "description": "The session cookie Path flag.", + "default": "/" + }, + "redis": { + "type": "object", + "properties": { + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "prefix": { + "type": "string", + "description": "The Redis session key prefix." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "socket": { + "type": "string", + "description": "The Redis unix socket path." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "reverify": { + "type": "boolean", + "description": "Specifies whether to always verify tokens stored in the session.", + "default": false + }, + "discovery_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the discovery endpoint." + }, + "jwks_endpoint": { + "type": "string", + "description": "Overrides the `jwks_uri` returned by discovery. Use when the IdP exposes a non-standard JWKS endpoint." + }, + "response_type": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The response type passed to the authorization endpoint.", + "default": [ + "code" + ] + }, + "roles_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the roles. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "roles" + ] + }, + "max_age": { + "type": "number", + "description": "The maximum age (in seconds) compared to the `auth_time` claim." + }, + "password_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the username and password: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "cache_ttl_resurrect": { + "type": "number", + "description": "The resurrection ttl in seconds." + }, + "mtls_token_endpoint": { + "type": "string", + "description": "Alias for the token endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "auth_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Types of credentials/grants to enable.", + "default": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "token_exchange_endpoint": { + "type": "string", + "description": "Endpoint used to perform the legacy token exchange." + }, + "upstream_headers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The name of the header." + }, + "path": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "The path of the header value." + } + }, + "required": [ + "header", + "path" + ] + }, + "description": "The upstream claim to header mappings." + }, + "keepalive": { + "type": "boolean", + "description": "Use keepalive with the HTTP client.", + "default": true + }, + "require_proof_key_for_code_exchange": { + "type": "boolean", + "description": "Forcibly enable or disable the proof key for code exchange. When not set the value is determined through the discovery using the value of `code_challenge_methods_supported`, and enabled automatically (in case the `code_challenge_methods_supported` is missing, the PKCE will not be enabled)." + }, + "authorization_query_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument values passed to the authorization endpoint." + }, + "introspection_headers_values": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra header values passed to the introspection endpoint.", + "x-encrypted": true + }, + "client_credentials_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the client credentials: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search from the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "upstream_user_info_header": { + "type": "string", + "description": "The upstream user info header." + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audience passed to the authorization endpoint." + }, + "using_pseudo_issuer": { + "type": "boolean", + "description": "If the plugin uses a pseudo issuer. When set to true, the plugin will not discover the configuration from the issuer URL specified with `config.issuer`.", + "default": false + }, + "unauthorized_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client on unauthorized requests." + }, + "groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the groups. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "groups" + ] + }, + "forbidden_destroy_session": { + "type": "boolean", + "description": "Destroy any active session for the forbidden requests.", + "default": true + }, + "scopes_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The scopes (`scopes_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "scopes_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the scopes. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "scope" + ] + }, + "introspection_headers_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra headers passed from the client to the introspection endpoint." + }, + "consumer_claims": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A path of strings representing the location of the claim in a nested object. For example, to map to `user.info.id`, set `[ \"user\", \"info\", \"id\" ]`." + }, + "description": "The claims used for consumer mapping. Each entry represents a claim path inside the token payload. The paths are evaluated in order, and the first matching claim is used." + }, + "authorization_query_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query arguments passed from the client to the authorization endpoint." + }, + "jwt_session_cookie": { + "type": "string", + "description": "The name of the JWT session cookie." + }, + "bearer_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "cookie", + "header", + "query" + ] + }, + "description": "Where to look for the bearer token: - `header`: search the `Authorization`, `access-token`, and `x-access-token` HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body - `cookie`: search the HTTP request cookies specified with `config.bearer_token_cookie_name`.", + "default": [ + "body", + "header", + "query" + ] + }, + "login_redirect_mode": { + "type": "string", + "enum": [ + "fragment", + "query" + ], + "description": "Where to place `login_tokens` when using `redirect` `login_action`: - `query`: place tokens in query string - `fragment`: place tokens in url fragment (not readable by servers).", + "default": "fragment" + }, + "session_remember_rolling_timeout": { + "type": "number", + "description": "Specifies how long the persistent session is considered valid in seconds. 0 disables the checks and rolling.", + "default": 604800 + }, + "downstream_introspection_header": { + "type": "string", + "description": "The downstream introspection header." + }, + "token_exchange": { + "type": "object", + "properties": { + "subject_token_issuers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "issuer": { + "type": "string", + "description": "Tokens of whose iss claim matches this value will be exchanged." + }, + "conditions": { + "type": "object", + "properties": { + "missing_scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "has_audience": { + "type": "array", + "items": { + "type": "string" + } + }, + "missing_audience": { + "type": "array", + "items": { + "type": "string" + } + }, + "has_scopes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "A tokens will only be exchange when it matches all these criteria. To exchanging tokens issued from a different issuer, conditions must not be defined; On the contrary, to exchange tokens issued from the target issuer itself, conditions must be defined." + } + }, + "required": [ + "issuer" + ] + }, + "minLength": 1, + "description": "Trusted token issuers from which the upstream may accept tokens to be exchanged. If a JWT bearer matches all the conditions of a subject token issuer item, the token will be exchanged." + }, + "request": { + "type": "object", + "properties": { + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Scopes used in the token exchange request. Values defined here override those defined in `config.scopes`." + }, + "empty_scopes": { + "type": "boolean", + "description": "Use empty scopes. Use this field to override scopes defined in `config.scopes`.", + "default": false + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Audiences used in the token exchange request. Values defined here override those defined in `config.audience`." + }, + "empty_audience": { + "type": "boolean", + "description": "Use empty audiences. Use this field to override audiences defined in `config.audience`.", + "default": false + } + }, + "description": "Parameters used in the token exchange request." + }, + "cache": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether to enable caching.", + "default": true + }, + "ttl": { + "type": "integer", + "description": "Cache ttl in seconds used when caching exchanged tokens, use it to override `conf.cache_ttl`. Token expiry will be used if shorter than this value." + } + }, + "description": "Cache support for token exchange" + } + }, + "required": [ + "subject_token_issuers" + ], + "description": "Details on how to accept tokens from other identity providers." + }, + "introspection_endpoint": { + "type": "string", + "description": "The introspection endpoint. If set it overrides the value in `introspection_endpoint` returned by the discovery endpoint.", + "x-referenceable": true + }, + "userinfo_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the user info endpoint." + }, + "id_token_param_type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "body", + "header", + "query" + ] + }, + "description": "Where to look for the id token: - `header`: search the HTTP headers - `query`: search the URL's query string - `body`: search the HTTP request body.", + "default": [ + "body", + "header", + "query" + ] + }, + "logout_revoke": { + "type": "boolean", + "description": "Revoke tokens as part of the logout.\n\nFor more granular token revocation, you can also adjust the `logout_revoke_access_token` and `logout_revoke_refresh_token` parameters.", + "default": false + }, + "http_proxy_authorization": { + "type": "string", + "description": "The HTTP proxy authorization.", + "x-referenceable": true + }, + "mtls_revocation_endpoint": { + "type": "string", + "description": "Alias for the introspection endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "authorization_cookie_http_only": { + "type": "boolean", + "description": "Forbids JavaScript from accessing the cookie, for example, through the `Document.cookie` property.", + "default": true + }, + "logout_uri_suffix": { + "type": "string", + "description": "The request URI suffix that activates the logout." + }, + "cache_user_info": { + "type": "boolean", + "description": "Cache the user info requests.", + "default": true + }, + "introspection_post_args_client_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post arguments passed from the client headers to the introspection endpoint." + }, + "refresh_tokens": { + "type": "boolean", + "description": "Specifies whether the plugin should try to refresh (soon to be) expired access tokens if the plugin has a `refresh_token` available.", + "default": true + }, + "consumer_by": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "custom_id", + "id", + "username" + ] + }, + "description": "Consumer fields used for mapping: - `id`: try to find the matching Consumer by `id` - `username`: try to find the matching Consumer by `username` - `custom_id`: try to find the matching Consumer by `custom_id`.", + "default": [ + "custom_id", + "username" + ] + }, + "cache_tokens_salt": { + "type": "string", + "description": "Salt used for generating the cache key that is used for caching the token endpoint requests." + }, + "expose_error_code": { + "type": "boolean", + "description": "Specifies whether to expose the error code header, as defined in RFC 6750. If an authorization request fails, this header is sent in the response. Set to `false` to disable.", + "default": true + }, + "introspection_check_active": { + "type": "boolean", + "description": "Check that the introspection response has an `active` claim with a value of `true`.", + "default": true + }, + "by_username_ignore_case": { + "type": "boolean", + "description": "If `consumer_by` is set to `username`, specify whether `username` can match consumers case-insensitively.", + "default": false + }, + "issuers_allowed": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The issuers allowed to be present in the tokens (`iss` claim)." + }, + "introspection_post_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post arguments passed from the client to the introspection endpoint." + }, + "disable_session": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Disable issuing the session cookie with the specified grants." + }, + "audience_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The audiences (`audience_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "session_hash_subject": { + "type": "boolean", + "description": "When set to `true`, the value of subject is hashed before being stored. Only applies when `session_store_metadata` is enabled.", + "default": false + }, + "pushed_authorization_request_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The pushed authorization request endpoint authentication method: `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "authorization_cookie_name": { + "type": "string", + "description": "The authorization cookie name.", + "default": "authorization" + }, + "introspection_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The introspection endpoint authentication method: : `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value that functions as an “anonymous” consumer if authentication fails. If empty (default null), requests that fail authentication will return a `4xx` HTTP status code. This value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "search_user_info": { + "type": "boolean", + "description": "Specify whether to use the user info endpoint to get additional claims for consumer mapping, credential mapping, authenticated groups, and upstream and downstream headers.", + "default": false + }, + "proof_of_possession_auth_methods_validation": { + "type": "boolean", + "description": "If set to true, only the auth_methods that are compatible with Proof of Possession (PoP) can be configured when PoP is enabled. If set to false, all auth_methods will be configurable and PoP checks will be silently skipped for those auth_methods that are not compatible with PoP.", + "default": true + }, + "session_enforce_same_subject": { + "type": "boolean", + "description": "When set to `true`, audiences are forced to share the same subject.", + "default": false + }, + "session_hash_storage_key": { + "type": "boolean", + "description": "When set to `true`, the storage key (session ID) is hashed for extra security. Hashing the storage key means it is impossible to decrypt data from the storage without a cookie.", + "default": false + }, + "enable_hs_signatures": { + "type": "boolean", + "description": "Enable shared secret, for example, HS256, signatures (when disabled they will not be accepted).", + "default": false + }, + "claims_forbidden": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If given, these claims are forbidden in the token payload." + }, + "audience_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains the audience. If multiple values are set, it means the claim is inside a nested object of the token payload.", + "default": [ + "aud" + ] + }, + "userinfo_accept": { + "type": "string", + "enum": [ + "application/json", + "application/jwt" + ], + "description": "The value of `Accept` header for user info requests: - `application/json`: user info response as JSON - `application/jwt`: user info response as JWT (from the obsolete IETF draft document).", + "default": "application/json" + }, + "session_idling_timeout": { + "type": "number", + "description": "Specifies how long the session can be inactive until it is considered invalid in seconds. 0 disables the checks and touching.", + "default": 900 + }, + "leeway": { + "type": "number", + "description": "Defines leeway time (in seconds) for `auth_time`, `exp`, `iat`, and `nbf` claims", + "default": 0 + }, + "cache_token_exchange": { + "type": "boolean", + "description": "Cache the legacy token exchange endpoint requests.", + "default": true + }, + "dpop_proof_lifetime": { + "type": "number", + "description": "Specifies the lifetime in seconds of the DPoP proof. It determines how long the same proof can be used after creation. The creation time is determined by the nonce creation time if a nonce is used, and the iat claim otherwise.", + "default": 300 + }, + "session_memcached_host": { + "type": "string", + "description": "The memcached host.", + "default": "127.0.0.1" + }, + "revocation_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The revocation endpoint authentication method: : `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "userinfo_query_args_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument values passed to the user info endpoint." + }, + "https_proxy": { + "type": "string", + "description": "The HTTPS proxy." + }, + "forbidden_redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "Where to redirect the client on forbidden requests." + }, + "response_mode": { + "type": "string", + "enum": [ + "form_post", + "form_post.jwt", + "fragment", + "fragment.jwt", + "jwt", + "query", + "query.jwt" + ], + "description": "Response mode passed to the authorization endpoint: - `query`: for parameters in query string - `form_post`: for parameters in request body - `fragment`: for parameters in uri fragment (rarely useful as the plugin itself cannot read it) - `query.jwt`, `form_post.jwt`, `fragment.jwt`: similar to `query`, `form_post` and `fragment` but the parameters are encoded in a JWT - `jwt`: shortcut that indicates the default encoding for the requested response type.", + "default": "query" + }, + "session_audience": { + "type": "string", + "description": "The session audience, which is the intended target application. For example `\"my-application\"`.", + "default": "default" + }, + "session_cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.", + "default": "Lax" + }, + "session_memcached_ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the memcached server SSL certificate", + "default": true + }, + "login_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "bearer", + "client_credentials", + "introspection", + "kong_oauth2", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Enable login functionality with specified grants.", + "default": [ + "authorization_code" + ] + }, + "mtls_introspection_endpoint": { + "type": "string", + "description": "Alias for the introspection endpoint to be used for mTLS client authentication. If set it overrides the value in `mtls_endpoint_aliases` returned by the discovery endpoint." + }, + "client_jwk": { + "type": "array", + "items": { + "type": "object", + "properties": { + "y": { + "type": "string" + }, + "crv": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "kid": { + "type": "string" + }, + "x5u": { + "type": "string" + }, + "k": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "x5t": { + "type": "string" + }, + "n": { + "type": "string" + }, + "e": { + "type": "string" + }, + "dq": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "t": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "key_ops": { + "type": "array", + "items": { + "type": "string" + } + }, + "alg": { + "type": "string" + }, + "x5c": { + "type": "array", + "items": { + "type": "string" + } + }, + "x": { + "type": "string" + }, + "d": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "qi": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "oth": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "r": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "kty": { + "type": "string" + }, + "use": { + "type": "string" + }, + "x5t#S256": { + "type": "string" + }, + "p": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "q": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + }, + "dp": { + "type": "string", + "x-referenceable": true, + "x-encrypted": true + } + } + }, + "description": "The JWK used for the private_key_jwt authentication." + }, + "upstream_introspection_jwt_header": { + "type": "string", + "description": "The upstream introspection JWT header." + }, + "upstream_session_id_header": { + "type": "string", + "description": "The upstream session id header." + }, + "downstream_access_token_header": { + "type": "string", + "description": "The downstream access token header." + }, + "verify_signature": { + "type": "boolean", + "description": "Verify signature of tokens.", + "default": true + }, + "groups_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The groups (`groups_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "authorization_query_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query argument names passed to the authorization endpoint." + }, + "token_post_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Pass extra arguments from the client to the OpenID-Connect plugin. If arguments exist, the client can pass them using: - Query parameters - Request Body - Request Header This parameter can be used with `scope` values, like this: `config.token_post_args_client=scope` In this case, the token would take the `scope` value from the query parameter or from the request body or from the header and send it to the token endpoint." + }, + "session_storage": { + "type": "string", + "enum": [ + "cookie", + "memcache", + "memcached", + "redis" + ], + "description": "The session storage for session data: - `cookie`: stores session data with the session cookie (the session cannot be invalidated or revoked without changing session secret, but is stateless, and doesn't require a database) - `memcache`: stores session data in memcached - `redis`: stores session data in Redis.", + "default": "cookie" + }, + "downstream_user_info_header": { + "type": "string", + "description": "The downstream user info header." + }, + "ignore_signature": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "authorization_code", + "client_credentials", + "introspection", + "password", + "refresh_token", + "session", + "userinfo" + ] + }, + "description": "Skip the token signature verification on certain grants: - `password`: OAuth password grant - `client_credentials`: OAuth client credentials grant - `authorization_code`: authorization code flow - `refresh_token`: OAuth refresh token grant - `session`: session cookie authentication - `introspection`: OAuth introspection - `userinfo`: OpenID Connect user info endpoint authentication.", + "default": [] + }, + "cache_introspection": { + "type": "boolean", + "description": "Cache the introspection endpoint requests.", + "default": true + }, + "token_cache_key_include_scope": { + "type": "boolean", + "description": "Include the scope in the token cache key, so token with different scopes are considered diffrent tokens.", + "default": false + }, + "revocation_endpoint": { + "type": "string", + "description": "The revocation endpoint. If set it overrides the value in `revocation_endpoint` returned by the discovery endpoint." + }, + "consumer_groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim used for consumer groups mapping. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "redirect_uri": { + "type": "array", + "items": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "description": "The redirect URI passed to the authorization and token endpoints." + }, + "require_pushed_authorization_requests": { + "type": "boolean", + "description": "Forcibly enable or disable the pushed authorization requests. When not set the value is determined through the discovery using the value of `require_pushed_authorization_requests` (which defaults to `false`)." + }, + "session_memcached_ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to memcached" + }, + "downstream_id_token_jwk_header": { + "type": "string", + "description": "The downstream id token JWK header." + }, + "verify_claims": { + "type": "boolean", + "description": "Verify tokens for standard claims.", + "default": true + }, + "client_secret": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The client secret.", + "x-encrypted": true + }, + "authorization_rolling_timeout": { + "type": "number", + "description": "Specifies how long the session used for the authorization code flow can be used in seconds until it needs to be renewed. 0 disables the checks and rolling.", + "default": 600 + }, + "token_endpoint_auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none", + "private_key_jwt", + "self_signed_tls_client_auth", + "tls_client_auth" + ], + "description": "The token endpoint authentication method: `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, or `none`: do not authenticate" + }, + "introspection_post_args_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra post argument names passed to the introspection endpoint." + }, + "session_cookie_http_only": { + "type": "boolean", + "description": "Forbids JavaScript from accessing the cookie, for example, through the `Document.cookie` property.", + "default": true + }, + "upstream_id_token_header": { + "type": "string", + "description": "The upstream id token header." + }, + "upstream_introspection_header": { + "type": "string", + "description": "The upstream introspection header." + }, + "run_on_preflight": { + "type": "boolean", + "description": "Specifies whether to run this plugin on pre-flight (`OPTIONS`) requests.", + "default": true + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for the requests by this plugin: - `1.1`: HTTP 1.1 (the default) - `1.0`: HTTP 1.0.", + "default": 1.1 + }, + "preserve_query_args": { + "type": "boolean", + "description": "With this parameter, you can preserve request query arguments even when doing authorization code flow.", + "default": false + }, + "introspection_accept": { + "type": "string", + "enum": [ + "application/json", + "application/jwt", + "application/token-introspection+jwt" + ], + "description": "The value of `Accept` header for introspection requests: - `application/json`: introspection response as JSON - `application/token-introspection+jwt`: introspection response as JWT (from the current IETF draft document) - `application/jwt`: introspection response as JWT (from the obsolete IETF draft document).", + "default": "application/json" + }, + "userinfo_endpoint": { + "type": "string", + "description": "The user info endpoint. If set it overrides the value in `userinfo_endpoint` returned by the discovery endpoint." + }, + "bearer_token_cookie_name": { + "type": "string", + "description": "The name of the cookie in which the bearer token is passed." + }, + "http_proxy": { + "type": "string", + "description": "The HTTP proxy." + }, + "authenticated_groups_claim": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The claim that contains authenticated groups. This setting can be used together with ACL plugin, but it also enables IdP managed groups with other applications and integrations. If multiple values are set, it means the claim is inside a nested object of the token payload." + }, + "authorization_endpoint": { + "type": "string", + "description": "The authorization endpoint. If set it overrides the value in `authorization_endpoint` returned by the discovery endpoint." + }, + "token_headers_prefix": { + "type": "string", + "description": "Add a prefix to the token endpoint response headers before forwarding them to the downstream client." + }, + "tls_client_auth_cert_id": { + "type": "string", + "description": "ID of the Certificate entity representing the client certificate to use for mTLS client authentication for connections between Kong and the Auth Server." + }, + "token_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the token endpoint." + }, + "session_request_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "Set of headers to send to upstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. E.g. `[ \"id\", \"timeout\" ]` will set Session-Id and Session-Timeout request headers." + }, + "verify_parameters": { + "type": "boolean", + "description": "Verify plugin configuration against discovery.", + "default": false + }, + "introspection_token_param_name": { + "type": "string", + "description": "Designate token's parameter name for introspection.", + "default": "token" + }, + "unauthorized_destroy_session": { + "type": "boolean", + "description": "Destroy any active session for the unauthorized requests.", + "default": true + }, + "roles_required": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The roles (`roles_claim` claim) required to be present in the access token (or introspection results) for successful authorization. This config parameter works in both **AND** / **OR** cases." + }, + "introspection_headers_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header names passed to the introspection endpoint." + }, + "userinfo_query_args_client": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra query arguments passed from the client to the user info endpoint." + }, + "upstream_user_info_jwt_header": { + "type": "string", + "description": "The upstream user info JWT header (in case the user info returns a JWT response)." + }, + "downstream_user_info_jwt_header": { + "type": "string", + "description": "The downstream user info JWT header (in case the user info returns a JWT response)." + }, + "downstream_introspection_jwt_header": { + "type": "string", + "description": "The downstream introspection JWT header." + }, + "logout_revoke_refresh_token": { + "type": "boolean", + "description": "Revoke the refresh token as part of the logout. Requires `logout_revoke` to be set to `true`.", + "default": true + }, + "discovery_headers_values": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra header values passed to the discovery endpoint." + }, + "client_id": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "description": "The client id(s) that the plugin uses when it calls authenticated endpoints on the identity provider.", + "x-encrypted": true + }, + "token_endpoint": { + "type": "string", + "description": "The token endpoint. If set it overrides the value in `token_endpoint` returned by the discovery endpoint." + }, + "session_response_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "Set of headers to send to downstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. E.g. `[ \"id\", \"timeout\" ]` will set Session-Id and Session-Timeout response headers." + }, + "proof_of_possession_mtls": { + "type": "string", + "enum": [ + "off", + "optional", + "strict" + ], + "description": "Enable mtls proof of possession. If set to strict, all tokens (from supported auth_methods: bearer, introspection, and session granted with bearer or introspection) are verified, if set to optional, only tokens that contain the certificate hash claim are verified. If the verification fails, the request will be rejected with 401.", + "default": "off" + }, + "consumer_optional": { + "type": "boolean", + "description": "Do not terminate the request if consumer mapping fails.", + "default": false + }, + "verify_nonce": { + "type": "boolean", + "description": "Verify nonce on authorization code flow.", + "default": true + }, + "cluster_cache_redis": { + "type": "object", + "properties": { + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + } + } + }, + "session_remember_cookie_name": { + "type": "string", + "description": "Persistent session cookie name. Use with the `remember` configuration parameter.", + "default": "remember" + }, + "no_proxy": { + "type": "string", + "description": "Do not use proxy with these hosts." + } + }, + "required": [ + "issuer" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Opentelemetry.json b/app/_schemas/ai-gateway/policies/Opentelemetry.json new file mode 100644 index 00000000000..518aeb333cf --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Opentelemetry.json @@ -0,0 +1,344 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "resource_attributes": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-lua-required": true + } + }, + "queue": { + "type": "object", + "properties": { + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 200 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + }, + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + }, + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + } + }, + "default": { + "max_batch_size": 200 + } + }, + "propagation": { + "type": "object", + "properties": { + "extract": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "aws", + "b3", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "w3c" + ] + }, + "description": "Header formats used to extract tracing context from incoming requests. If multiple values are specified, the first one found will be used for extraction. If left empty, Kong will not extract any tracing context information from incoming requests and generate a trace with no parent and a new trace ID." + }, + "clear": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Header names to clear after context extraction. This allows to extract the context from a certain header and then remove it from the request, useful when extraction and injection are performed on different header formats and the original header should not be sent to the upstream. If left empty, no headers are cleared." + }, + "inject": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "preserve", + "w3c" + ] + }, + "description": "Header formats used to inject tracing context. The value `preserve` will use the same header format as the incoming request. If multiple values are specified, all of them will be used during injection. If left empty, Kong will not inject any tracing context information in outgoing requests." + }, + "default_format": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "w3c" + ], + "description": "The default header format to use when extractors did not match any format in the incoming headers and `inject` is configured with the value: `preserve`. This can happen when no tracing header was found in the request, or the incoming tracing header formats were not included in `extract`.", + "default": "w3c" + } + }, + "default": { + "default_format": "w3c" + } + }, + "logs_endpoint": { + "type": "string", + "description": "An HTTP URL endpoint where internal logs are exported.", + "x-referenceable": true + }, + "batch_span_count": { + "type": "integer", + "description": "The number of spans to be sent in a single batch." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 5000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 5000 + }, + "sampling_rate": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Tracing sampling rate for configuring the probability-based sampler. When set, this value supersedes the global `tracing_sampling_rate` setting from kong.conf." + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The custom headers to be added in the HTTP request sent to the OTLP server. This setting is useful for adding the authentication headers (token) for the APM backend." + }, + "traces_endpoint": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search.", + "x-referenceable": true + }, + "access_logs": { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "description": "An HTTP URL endpoint where access logs (e.g. request/response, route/service, latency, etc.) are exported.", + "x-referenceable": true + }, + "custom_attributes_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string", + "minLength": 1 + }, + "description": "A key-value map that dynamically modifies access log fields using Lua code." + } + } + }, + "batch_flush_delay": { + "type": "integer", + "description": "The delay, in seconds, between two consecutive batches." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 1000 + }, + "http_response_header_for_traceid": { + "type": "string" + }, + "header_type": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "ignore", + "instana", + "jaeger", + "ot", + "preserve", + "w3c" + ], + "default": "preserve" + }, + "sampling_strategy": { + "type": "string", + "enum": [ + "parent_drop_probability_fallback", + "parent_probability_fallback" + ], + "description": "The sampling strategy to use for OTLP `traces`. Set `parent_drop_probability_fallback` if you want parent-based sampling when the parent span contains a `false` sampled flag, and fallback to probability-based sampling otherwise. Set `parent_probability_fallback` if you want parent-based sampling when the parent span contains a valid sampled flag (`true` or `false`), and fallback to probability-based sampling otherwise.", + "default": "parent_drop_probability_fallback" + }, + "metrics": { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "description": "An HTTP URL endpoint where metrics are exported.", + "x-referenceable": true + }, + "push_interval": { + "type": "number", + "description": "The interval in seconds at which metrics are pushed to the OTLP server. This setting is only applicable when `endpoint` is set.", + "default": 60 + }, + "enable_consumer_attribute": { + "type": "boolean", + "description": "A boolean value that determines if `http.server.request.count`, `http.server.request.size` and `http.server.response.size` metrics should fill in the consumer attribute when available.", + "default": false + }, + "enable_request_metrics": { + "type": "boolean", + "description": "A boolean value that determines if request count metrics should be collected. If enabled, `http.server.request.count` metrics will be exported.", + "default": false + }, + "enable_bandwidth_metrics": { + "type": "boolean", + "description": "A boolean value that determines if bandwidth metrics should be collected. If enabled, `http.server.request.size` and `http.server.response.size` metrics will be exported.", + "default": false + }, + "enable_latency_metrics": { + "type": "boolean", + "description": "A boolean value that determines if latency metrics should be collected. If enabled, `kong.latency.total`, `kong.latency.internal` and `kong.latency.upstream` metrics will be exported.", + "default": false + }, + "enable_upstream_health_metrics": { + "type": "boolean", + "description": "A boolean value that determines if upstream health metrics should be collected. If enabled, `kong.upstream.target.status` metrics will be exported.", + "default": false + }, + "enable_ai_metrics": { + "type": "boolean", + "description": "A boolean value that determines if AI metrics should be collected. If enabled, `gen_ai.*`, `mcp.*`, `kong.gen_ai.*`, `kong.gen_ai.a2a.*` and `kong.mcp.*` metrics will be exported. To enable latency metrics for AI metrics, `enable_latency_metrics` must also be set to `true`. To enable `error.type` attribute for AI metrics, `enable_request_metrics` must also be set to `true`.", + "default": false + } + } + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/PostFunction.json b/app/_schemas/ai-gateway/policies/PostFunction.json new file mode 100644 index 00000000000..b1e0aa5214e --- /dev/null +++ b/app/_schemas/ai-gateway/policies/PostFunction.json @@ -0,0 +1,125 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "access": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "body_filter": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "log": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_handshake": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_client_frame": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "certificate": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "rewrite": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "header_filter": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_upstream_frame": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_close": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/PreFunction.json b/app/_schemas/ai-gateway/policies/PreFunction.json new file mode 100644 index 00000000000..03cf2d1f5ef --- /dev/null +++ b/app/_schemas/ai-gateway/policies/PreFunction.json @@ -0,0 +1,125 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "header_filter": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "body_filter": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_upstream_frame": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_close": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "certificate": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "rewrite": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "access": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "log": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_handshake": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "ws_client_frame": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Prometheus.json b/app/_schemas/ai-gateway/policies/Prometheus.json new file mode 100644 index 00000000000..ffb851d1a0f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Prometheus.json @@ -0,0 +1,98 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "ai_metrics": { + "type": "boolean", + "description": "A boolean value that determines if ai metrics should be collected. If enabled, the `ai_llm_requests_total`, `ai_llm_cost_total` and `ai_llm_tokens_total` metrics will be exported.", + "default": false + }, + "latency_metrics": { + "type": "boolean", + "description": "A boolean value that determines if latency metrics should be collected. If enabled, `kong_latency_ms`, `upstream_latency_ms` and `request_latency_ms` metrics will be exported.", + "default": false + }, + "bandwidth_metrics": { + "type": "boolean", + "description": "A boolean value that determines if bandwidth metrics should be collected. If enabled, `bandwidth_bytes` and `stream_sessions_total` metrics will be exported.", + "default": false + }, + "upstream_health_metrics": { + "type": "boolean", + "description": "A boolean value that determines if upstream metrics should be collected. If enabled, `upstream_target_health` metric will be exported.", + "default": false + }, + "wasm_metrics": { + "type": "boolean" + }, + "per_consumer": { + "type": "boolean", + "description": "A boolean value that determines if per-consumer metrics should be collected. If enabled, the `kong_http_requests_total` and `kong_bandwidth_bytes` metrics fill in the consumer label when available.", + "default": false + }, + "status_code_metrics": { + "type": "boolean", + "description": "A boolean value that determines if status code metrics should be collected. If enabled, `http_requests_total`, `stream_sessions_total` metrics will be exported.", + "default": false + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ProxyCache.json b/app/_schemas/ai-gateway/policies/ProxyCache.json new file mode 100644 index 00000000000..ebaad9d8d23 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ProxyCache.json @@ -0,0 +1,192 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "cache_ttl": { + "type": "integer", + "description": "TTL, in seconds, of cache entities.", + "default": 300 + }, + "strategy": { + "type": "string", + "enum": [ + "memory" + ], + "description": "The backing data store in which to hold cache entities." + }, + "cache_control": { + "type": "boolean", + "description": "When enabled, respect the Cache-Control behaviors defined in RFC7234.", + "default": false + }, + "ignore_uri_case": { + "type": "boolean", + "default": false + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template.", + "default": "kong_db_cache" + } + } + }, + "response_headers": { + "type": "object", + "properties": { + "age": { + "type": "boolean", + "default": true + }, + "X-Cache-Status": { + "type": "boolean", + "default": true + }, + "X-Cache-Key": { + "type": "boolean", + "default": true + } + }, + "description": "Caching related diagnostic headers that should be included in cached responses" + }, + "response_code": { + "type": "array", + "items": { + "type": "integer", + "maximum": 900, + "minimum": 100 + }, + "minLength": 1, + "description": "Upstream response status code considered cacheable.", + "default": [ + 200, + 301, + 404 + ] + }, + "storage_ttl": { + "type": "integer", + "description": "Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors." + }, + "vary_query_params": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration." + }, + "vary_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration." + }, + "request_method": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "GET", + "HEAD", + "PATCH", + "POST", + "PUT" + ] + }, + "description": "Downstream request methods considered cacheable.", + "default": [ + "GET", + "HEAD" + ] + }, + "content_type": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Upstream response content types considered cacheable. The plugin performs an **exact match** against each specified value.", + "default": [ + "application/json", + "text/plain" + ] + } + }, + "required": [ + "strategy" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ProxyCacheAdvanced.json b/app/_schemas/ai-gateway/policies/ProxyCacheAdvanced.json new file mode 100644 index 00000000000..9ec878a4291 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ProxyCacheAdvanced.json @@ -0,0 +1,441 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "request_method": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "GET", + "HEAD", + "PATCH", + "POST", + "PUT" + ] + }, + "description": "Downstream request methods considered cacheable. Available options: `HEAD`, `GET`, `POST`, `PATCH`, `PUT`.", + "default": [ + "GET", + "HEAD" + ] + }, + "content_type": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Upstream response content types considered cacheable. The plugin performs an **exact match** against each specified value; for example, if the upstream is expected to respond with a `application/json; charset=utf-8` content-type, the plugin configuration must contain said value or a `Bypass` cache status is returned.", + "default": [ + "application/json", + "text/plain" + ] + }, + "cache_ttl": { + "type": "integer", + "description": "TTL in seconds of cache entities.", + "default": 300 + }, + "strategy": { + "type": "string", + "enum": [ + "memory", + "redis" + ], + "description": "The backing data store in which to hold cache entities. Accepted values are: `memory` and `redis`." + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template.", + "default": "kong_db_cache" + } + } + }, + "response_headers": { + "type": "object", + "properties": { + "age": { + "type": "boolean", + "default": true + }, + "X-Cache-Status": { + "type": "boolean", + "default": true + }, + "X-Cache-Key": { + "type": "boolean", + "default": true + } + }, + "description": "Caching related diagnostic headers that should be included in cached responses" + }, + "bypass_on_err": { + "type": "boolean", + "description": "Unhandled errors while trying to retrieve a cache entry (such as redis down) are resolved with `Bypass`, with the request going upstream.", + "default": false + }, + "response_code": { + "type": "array", + "items": { + "type": "integer", + "maximum": 900, + "minimum": 100 + }, + "minLength": 1, + "description": "Upstream response status code considered cacheable. The integers must be a value between 100 and 900.", + "default": [ + 200, + 301, + 404 + ] + }, + "cache_control": { + "type": "boolean", + "description": "When enabled, respect the Cache-Control behaviors defined in RFC7234.", + "default": false + }, + "ignore_uri_case": { + "type": "boolean", + "description": "Determines whether to treat URIs as case sensitive. By default, case sensitivity is enabled. If set to true, requests are cached while ignoring case sensitivity in the URI.", + "default": false + }, + "storage_ttl": { + "type": "integer", + "description": "Number of seconds to keep resources in the storage backend. This value is independent of `cache_ttl` or resource TTLs defined by Cache-Control behaviors." + }, + "vary_query_params": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Relevant query parameters considered for the cache key. If undefined, all params are taken into consideration. By default, the max number of params accepted is 100. You can change this value via the `lua_max_post_args` in `kong.conf`." + }, + "vary_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Relevant headers considered for the cache key. If undefined, none of the headers are taken into consideration." + }, + "redis": { + "type": "object", + "properties": { + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-encrypted": true, + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-encrypted": true, + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + } + } + } + }, + "required": [ + "strategy" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RateLimiting.json b/app/_schemas/ai-gateway/policies/RateLimiting.json new file mode 100644 index 00000000000..8bbc7c76db2 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RateLimiting.json @@ -0,0 +1,293 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "second": { + "type": "number", + "description": "The number of HTTP requests that can be made per second." + }, + "header_name": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes)." + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers.", + "default": false + }, + "month": { + "type": "number", + "description": "The number of HTTP requests that can be made per month." + }, + "error_code": { + "type": "number", + "description": "Set a custom error code to return when the rate limit is exceeded.", + "default": 429 + }, + "hour": { + "type": "number", + "description": "The number of HTTP requests that can be made per hour." + }, + "day": { + "type": "number", + "description": "The number of HTTP requests that can be made per day." + }, + "limit_by": { + "type": "string", + "enum": [ + "consumer", + "consumer-group", + "credential", + "header", + "ip", + "path", + "service" + ], + "description": "The entity that is used when aggregating the limits.", + "default": "consumer" + }, + "fault_tolerant": { + "type": "boolean", + "description": "A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party data store. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the data store is working again. If `false`, then the clients will see `500` errors.", + "default": true + }, + "redis": { + "type": "object", + "properties": { + "cloud_authentication": { + "type": "object", + "properties": { + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-encrypted": true, + "x-referenceable": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-encrypted": true, + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Redis configuration" + }, + "error_message": { + "type": "string", + "description": "Set a custom error message to return when the rate limit is exceeded.", + "default": "API rate limit exceeded" + }, + "sync_rate": { + "type": "number", + "description": "How often to sync counter data to the central data store. A value of -1 results in synchronous behavior.", + "default": -1 + }, + "minute": { + "type": "number", + "description": "The number of HTTP requests that can be made per minute." + }, + "year": { + "type": "number", + "description": "The number of HTTP requests that can be made per year." + }, + "policy": { + "type": "string", + "enum": [ + "cluster", + "local", + "redis" + ], + "description": "The rate-limiting policies to use for retrieving and incrementing the limits.", + "default": "local" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "x-supported-partials": [ + { + "name": "redis-ce", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RateLimitingAdvanced.json b/app/_schemas/ai-gateway/policies/RateLimitingAdvanced.json new file mode 100644 index 00000000000..5b4212c785d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RateLimitingAdvanced.json @@ -0,0 +1,490 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "identifier": { + "type": "string", + "enum": [ + "consumer", + "consumer-group", + "credential", + "header", + "ip", + "path", + "route", + "service" + ], + "description": "The type of identifier used to generate the rate limit key. Defines the scope used to increment the rate limiting counters. Note if `identifier` is `consumer-group`, the plugin must be applied on a consumer group entity. Because a consumer may belong to multiple consumer groups, the plugin needs to know explicitly which consumer group to limit the rate.", + "default": "consumer" + }, + "window_size": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more window sizes to apply a limit to (defined in seconds). There must be a matching number of window limits and sizes specified." + }, + "window_type": { + "type": "string", + "enum": [ + "fixed", + "sliding" + ], + "description": "Sets the time window type to either `sliding` (default) or `fixed`. Sliding windows apply the rate limiting logic while taking into account previous hit rates (from the window that immediately precedes the current) using a dynamic weight. Fixed windows consist of buckets that are statically assigned to a definitive time range, each request is mapped to only one fixed window based on its timestamp and will affect only that window's counters.", + "default": "sliding" + }, + "namespace": { + "type": "string", + "description": "Specifies the rate-limiting namespace for this plugin instance. A namespace acts as a logical grouping for configuration and counter data used by the rate-limiting algorithm. Namespaces define how and where counter data is stored and synchronized. When multiple plugin instances share the same namespace, they also share the same rate-limiting counters and synchronization configuration. Conversely, using different namespaces ensures that each plugin instance maintains its own independent counters." + }, + "header_name": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes)." + }, + "redis": { + "type": "object", + "properties": { + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "redis_proxy_type": { + "type": "string", + "enum": [ + "envoy_v1.31" + ], + "description": "If the `connection_is_proxied` is enabled, this field indicates the proxy type and version you are using. For example, you can enable this optioin when you want authentication between Kong and Envoy proxy." + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + } + } + }, + "enforce_consumer_groups": { + "type": "boolean", + "description": "Determines if consumer groups are allowed to override the rate limiting settings for the given Route or Service. Flipping `enforce_consumer_groups` from `true` to `false` disables the group override, but does not clear the list of consumer groups. You can then flip `enforce_consumer_groups` to `true` to re-enforce the groups.", + "default": false + }, + "limit": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more requests-per-window limits to apply. There must be a matching number of window limits and sizes specified." + }, + "dictionary_name": { + "type": "string", + "description": "The shared dictionary where counters are stored. When the plugin is configured to synchronize counter data externally (that is `config.strategy` is `cluster` or `redis` and `config.sync_rate` isn't `-1`), this dictionary serves as a buffer to populate counters in the data store on each synchronization cycle.", + "default": "kong_rate_limiting_counters" + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers that would otherwise provide information about the current status of limits and counters.", + "default": false + }, + "disable_penalty": { + "type": "boolean", + "description": "If set to `true`, this doesn't count denied requests (status = `429`). If set to `false`, all requests, including denied ones, are counted. This parameter only affects the `sliding` window_type.", + "default": false + }, + "error_code": { + "type": "number", + "description": "Set a custom error code to return when the rate limit is exceeded.", + "default": 429 + }, + "compound_identifier": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "consumer", + "consumer-group", + "credential", + "header", + "ip", + "path", + "route", + "service" + ] + }, + "description": "Similar to `identifer`, but supports combining multiple items. The priority of `compound_identifier` is higher than `identifier`, which means if `compound_identifer` is set, it will be used, otherwise `identifier` will be used." + }, + "lock_dictionary_name": { + "type": "string", + "description": "The shared dictionary where concurrency control locks are stored. The default shared dictionary is `kong_locks`. The shared dictionary should be declare in nginx-kong.conf.", + "default": "kong_locks" + }, + "retry_after_jitter_max": { + "type": "number", + "description": "The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` header of denied requests (status = `429`) in order to prevent all the clients from coming back at the same time. The lower bound of the jitter is `0`; in this case, the `Retry-After` header is equal to the `RateLimit-Reset` header.", + "default": 0 + }, + "sync_rate": { + "type": "number", + "description": "How often to sync counter data to the central data store. A value of 0 results in synchronous behavior; a value of -1 ignores sync behavior entirely and only stores counters in node memory. A value greater than 0 will sync the counters in the specified number of seconds. The minimum allowed interval is 0.02 seconds (20ms)." + }, + "strategy": { + "type": "string", + "enum": [ + "cluster", + "local", + "redis" + ], + "description": "The rate-limiting strategy to use for retrieving and incrementing the limits. Available values are: `local`, `redis` and `cluster`.", + "default": "local" + }, + "throttling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Determines if the throttling feature is enabled or not", + "default": false + }, + "interval": { + "type": "number", + "maximum": 1000000, + "minimum": 1, + "description": "The period between two successive retries for an individual request (in seconds)", + "default": 5 + }, + "retry_times": { + "type": "number", + "maximum": 1000000, + "minimum": 1, + "description": "The maximum number of retries for an individual request", + "default": 3 + }, + "queue_limit": { + "type": "number", + "maximum": 1000000, + "minimum": 1, + "description": "The maximum number of requests allowed for throttling", + "default": 5 + } + } + }, + "consumer_groups": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of consumer groups allowed to override the rate limiting settings for the given Route or Service. Required if `enforce_consumer_groups` is set to `true`." + }, + "error_message": { + "type": "string", + "description": "Set a custom error message to return when the rate limit is exceeded.", + "default": "API rate limit exceeded" + } + }, + "required": [ + "limit", + "window_size" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Redirect.json b/app/_schemas/ai-gateway/policies/Redirect.json new file mode 100644 index 00000000000..15a4673312f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Redirect.json @@ -0,0 +1,90 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "keep_incoming_path": { + "type": "boolean", + "description": "Use the incoming request's path and query string in the redirect URL", + "default": false + }, + "status_code": { + "type": "integer", + "maximum": 599, + "minimum": 100, + "description": "The response code to send. Must be an integer between 100 and 599.", + "default": 301 + }, + "location": { + "type": "string", + "description": "The URL to redirect to" + } + }, + "required": [ + "location" + ] + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestCallout.json b/app/_schemas/ai-gateway/policies/RequestCallout.json new file mode 100644 index 00000000000..525baf2d194 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestCallout.json @@ -0,0 +1,678 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "cache": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "memory", + "off", + "redis" + ], + "description": "The backing data store in which to hold cache entities. Accepted values are: `off`, `memory`, and `redis`.", + "default": "off" + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The name of the shared dictionary in which to hold cache entities when the memory strategy is selected. Note that this dictionary currently must be defined manually in the Kong Nginx template.", + "default": "kong_db_cache" + } + } + }, + "redis": { + "type": "object", + "properties": { + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + } + } + }, + "cache_ttl": { + "type": "integer", + "description": "TTL in seconds of cache entities.", + "default": 300 + } + }, + "description": "Plugin global caching configuration." + }, + "upstream": { + "type": "object", + "properties": { + "query": { + "type": "object", + "properties": { + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom query params to be added in the upstream HTTP request. Values can contain Lua expressions in the form `$(some_lua_expression)`. The syntax is based on `request-transformer-advanced` templates." + }, + "forward": { + "type": "boolean", + "description": "If `false`, does not forward request query params to upstream request.", + "default": true + } + }, + "description": "Upstream request query param customizations." + }, + "headers": { + "type": "object", + "properties": { + "forward": { + "type": "boolean", + "description": "If `false`, does not forward request headers to upstream request.", + "default": true + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom headers to be added in the upstream HTTP request. Values can contain Lua expressions in the form $(some_lua_expression). The syntax is based on `request-transformer-advanced` templates." + } + }, + "description": "Callout request header customizations." + }, + "body": { + "type": "object", + "properties": { + "decode": { + "type": "boolean", + "description": "If `true`, decodes the request's body to make it available for upstream by_lua customizations. Only JSON content type is supported.", + "default": true + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom body fields to be added in the upstream request body. Values can contain Lua expressions in the form $(some_lua_expression). The syntax is based on `request-transformer-advanced` templates." + }, + "forward": { + "type": "boolean", + "description": "If `false`, skips forwarding the incoming request's body to the upstream request.", + "default": true + } + }, + "description": "Callout request body customizations." + }, + "by_lua": { + "type": "string", + "description": "Lua code that executes before the upstream request is made. Can produce side effects. Standard Lua sandboxing restrictions apply." + } + }, + "description": "Customizations to the upstream request." + }, + "callouts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "depends_on": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of callout names the current callout depends on. This dependency list determines the callout execution order via a topological sorting algorithm.", + "default": [] + }, + "request": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "properties": { + "forward": { + "type": "boolean", + "description": "If `true`, forwards the incoming request's headers to the callout request. ", + "default": false + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom headers to be added in the callout HTTP request. Values can contain Lua expressions in the form `$(some_lua_expression)`. The syntax is based on `request-transformer-advanced` templates." + } + }, + "description": "Callout request header customizations." + }, + "body": { + "type": "object", + "properties": { + "forward": { + "type": "boolean", + "description": "If `true`, forwards the incoming request's body to the callout request.", + "default": false + }, + "decode": { + "type": "boolean", + "description": "If `true`, decodes the request's body and make it available for customizations. Only JSON content type is supported.", + "default": false + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom body fields to be added to the callout HTTP request. Values can contain Lua expressions in the form $(some_lua_expression). The syntax is based on `request-transformer-advanced` templates." + } + }, + "description": "Callout request body customizations." + }, + "error": { + "type": "object", + "properties": { + "error_response_msg": { + "type": "string", + "description": "The error mesasge to respond with if `on_error` is set to `fail` or if `retries` is achieved. Templating with Lua expressions is supported.", + "default": "service callout error" + }, + "on_error": { + "type": "string", + "enum": [ + "continue", + "fail", + "retry" + ], + "default": "fail" + }, + "retries": { + "type": "integer", + "description": "The number of retries the plugin will attempt on TCP and HTTP errors if `on_error` is set to `retry`.", + "default": 2 + }, + "http_statuses": { + "type": "array", + "items": { + "type": "integer", + "maximum": 999, + "minimum": 100 + }, + "description": "The list of HTTP status codes considered errors under the error handling policy." + }, + "error_response_code": { + "type": "integer", + "description": "The error code to respond with if `on_error` is `fail` or if `retries` is achieved.", + "default": 400 + } + }, + "description": "The error handling policy the plugin will apply to TCP and HTTP errors." + }, + "by_lua": { + "type": "string", + "description": "Lua code that executes before the callout request is made. **Warning** can impact system behavior. Standard Lua sandboxing restrictions apply." + }, + "url": { + "type": "string", + "description": "The URL that will be requested. Values can contain Lua expressions in the form `$(some_lua_expression)`. The syntax is based on `request-transformer-advanced` templates.", + "x-referenceable": true + }, + "method": { + "type": "string", + "description": "The HTTP method that will be requested.", + "default": "GET" + }, + "http_opts": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "If set to `true`, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your callout API. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "ssl_server_name": { + "type": "string", + "description": "The SNI used in the callout request. Defaults to host if omitted." + }, + "timeouts": { + "type": "object", + "properties": { + "write": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The socket write timeout." + }, + "read": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The socket read timeout. " + }, + "connect": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The socket connect timeout." + } + }, + "description": "Socket timeouts in milliseconds. All or none must be set." + }, + "proxy": { + "type": "object", + "properties": { + "auth_password": { + "type": "string", + "description": "The password to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true, + "x-encrypted": true + }, + "https_proxy": { + "type": "string", + "description": "The HTTPS proxy URL. This proxy server will be used for HTTPS requests." + }, + "http_proxy": { + "type": "string", + "description": "The HTTP proxy URL. This proxy server will be used for HTTP requests." + }, + "auth_username": { + "type": "string", + "description": "The username to authenticate with, if the forward proxy is protected by basic authentication.", + "x-referenceable": true + } + }, + "description": "Proxy settings." + } + }, + "description": "HTTP connection parameters." + }, + "query": { + "type": "object", + "properties": { + "forward": { + "type": "boolean", + "description": "If `true`, forwards the incoming request's query params to the callout request. ", + "default": false + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "The custom query params to be added in the callout HTTP request. Values can contain Lua expressions in the form `$(some_lua_expression)`. The syntax is based on `request-transformer-advanced` templates." + } + }, + "description": "Callout request query param customizations." + } + }, + "required": [ + "url" + ], + "description": "The customizations for the callout request." + }, + "response": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "properties": { + "store": { + "type": "boolean", + "description": "If `false`, skips storing the callout response headers into kong.ctx.shared.callouts.\u003cname\u003e.response.headers.", + "default": true + } + }, + "description": "Callout response header customizations." + }, + "body": { + "type": "object", + "properties": { + "store": { + "type": "boolean", + "description": "If `false`, skips storing the callout response body into kong.ctx.shared.callouts.\u003cname\u003e.response.body.", + "default": true + }, + "decode": { + "type": "boolean", + "description": "If `true`, decodes the response body before storing into the context. Only JSON is supported.", + "default": false + } + } + }, + "by_lua": { + "type": "string", + "description": "Lua code that executes after the callout response is received, before caching takes place. Can produce side effects. Standard Lua sandboxing restrictions apply." + } + }, + "description": "Configurations of callout response handling." + }, + "cache": { + "type": "object", + "properties": { + "bypass": { + "type": "boolean", + "description": "If `true`, skips caching the callout response.", + "default": false + } + }, + "description": "Callout caching configuration." + }, + "name": { + "type": "string", + "description": "A string identifier for a callout. A callout object is referenceable via its name in the `kong.ctx.shared.callouts.\u003cname\u003e`" + } + }, + "required": [ + "name", + "request" + ] + }, + "description": "A collection of callout objects, where each object represents an HTTP request made in the context of a proxy request." + } + }, + "required": [ + "callouts" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestSizeLimiting.json b/app/_schemas/ai-gateway/policies/RequestSizeLimiting.json new file mode 100644 index 00000000000..9af7fbffa7c --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestSizeLimiting.json @@ -0,0 +1,78 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "allowed_payload_size": { + "type": "integer", + "description": "Allowed request payload size in megabytes. Default is `128` megabytes (128000000 bytes).", + "default": 128 + }, + "size_unit": { + "type": "string", + "enum": [ + "bytes", + "kilobytes", + "megabytes" + ], + "description": "Size unit can be set either in `bytes`, `kilobytes`, or `megabytes` (default). This configuration is not available in versions prior to Kong Gateway 1.3 and Kong Gateway (OSS) 2.0.", + "default": "megabytes" + }, + "require_content_length": { + "type": "boolean", + "description": "Set to `true` to ensure a valid `Content-Length` header exists before reading the request body.", + "default": false + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestTermination.json b/app/_schemas/ai-gateway/policies/RequestTermination.json new file mode 100644 index 00000000000..c39540ca8b9 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestTermination.json @@ -0,0 +1,96 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "The raw response body to send. This is mutually exclusive with the `config.message` field." + }, + "echo": { + "type": "boolean", + "description": "When set, the plugin will echo a copy of the request back to the client. The main usecase for this is debugging. It can be combined with `trigger` in order to debug requests on live systems without disturbing real traffic.", + "default": false + }, + "trigger": { + "type": "string", + "description": "A string representing an HTTP header name." + }, + "status_code": { + "type": "integer", + "maximum": 599, + "minimum": 100, + "description": "The response code to send. Must be an integer between 100 and 599.", + "default": 503 + }, + "message": { + "type": "string", + "description": "The message to send, if using the default response generator." + }, + "content_type": { + "type": "string", + "description": "Content type of the raw response configured with `config.body`." + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestTransformer.json b/app/_schemas/ai-gateway/policies/RequestTransformer.json new file mode 100644 index 00000000000..4994134cb0d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestTransformer.json @@ -0,0 +1,212 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "http_method": { + "type": "string", + "description": "A string representing an HTTP method, such as GET, POST, PUT, or DELETE. The string must contain only uppercase letters." + }, + "remove": { + "type": "object", + "properties": { + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "rename": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "replace": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "uri": { + "type": "string" + } + } + }, + "add": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "append": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestTransformerAdvanced.json b/app/_schemas/ai-gateway/policies/RequestTransformerAdvanced.json new file mode 100644 index 00000000000..40ad6828141 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestTransformerAdvanced.json @@ -0,0 +1,269 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "dots_in_keys": { + "type": "boolean", + "description": "Specify whether dots (for example, `customers.info.phone`) should be treated as part of a property name or used to descend into nested JSON objects.", + "default": true + }, + "http_method": { + "type": "string", + "description": "A string representing an HTTP method, such as GET, POST, PUT, or DELETE. The string must contain only uppercase letters." + }, + "remove": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "rename": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + } + } + }, + "replace": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "uri": { + "type": "string" + } + } + }, + "add": { + "type": "object", + "properties": { + "headers": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "body": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + } + } + }, + "append": { + "type": "object", + "properties": { + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "body": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + }, + "querystring": { + "type": "array", + "items": { + "type": "string", + "x-referenceable": true + }, + "default": [] + } + } + }, + "allow": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RequestValidator.json b/app/_schemas/ai-gateway/policies/RequestValidator.json new file mode 100644 index 00000000000..84d78d95571 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RequestValidator.json @@ -0,0 +1,147 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "version": { + "type": "string", + "enum": [ + "draft201909", + "draft202012", + "draft4", + "draft6", + "draft7", + "kong" + ], + "description": "Which validator to use. Supported values are `kong` (default) for using Kong's own schema validator, or `draft4`, `draft7`, `draft201909`, and `draft202012` for using their respective JSON Schema Draft compliant validators.", + "default": "kong" + }, + "parameter_schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "explode": { + "type": "boolean", + "description": "Required when `schema` and `style` are set. When `explode` is `true`, parameter values of type `array` or `object` generate separate parameters for each value of the array or key-value pair of the map. For other types of parameters, this property has no effect." + }, + "schema": { + "type": "string", + "description": "Required when `style` and `explode` are set. This is the schema defining the type used for the parameter. It is validated using `draft4` for JSON Schema draft 4 compliant validator. In addition to being a valid JSON Schema, the parameter schema MUST have a top-level `type` property to enable proper deserialization before validating." + }, + "in": { + "type": "string", + "enum": [ + "header", + "path", + "query" + ], + "description": "The location of the parameter." + }, + "name": { + "type": "string", + "description": "The name of the parameter. Parameter names are case-sensitive, and correspond to the parameter name used by the `in` property. If `in` is `path`, the `name` field MUST correspond to the named capture group from the configured `route`." + }, + "required": { + "type": "boolean", + "description": "Determines whether this parameter is mandatory." + }, + "style": { + "type": "string", + "enum": [ + "deepObject", + "form", + "label", + "matrix", + "pipeDelimited", + "simple", + "spaceDelimited" + ], + "description": "Required when `schema` and `explode` are set. Describes how the parameter value will be deserialized depending on the type of the parameter value." + } + }, + "required": [ + "in", + "name", + "required" + ] + }, + "description": "Array of parameter validator specification. One of `body_schema` or `parameter_schema` must be specified." + }, + "verbose_response": { + "type": "boolean", + "description": "If enabled, the plugin returns more verbose and detailed validation errors.", + "default": false + }, + "content_type_parameter_validation": { + "type": "boolean", + "description": "Determines whether to enable parameters validation of request content-type.", + "default": true + }, + "body_schema": { + "type": "string", + "description": "The request body schema specification. One of `body_schema` or `parameter_schema` must be specified." + }, + "allowed_content_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed content types. The value can be configured with the `charset` parameter. For example, `application/json; charset=UTF-8`.", + "default": [ + "application/json" + ] + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ResponseRatelimiting.json b/app/_schemas/ai-gateway/policies/ResponseRatelimiting.json new file mode 100644 index 00000000000..c7bda3c9396 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ResponseRatelimiting.json @@ -0,0 +1,270 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "limits": { + "type": "object", + "minLength": 1, + "additionalProperties": { + "type": "object", + "properties": { + "second": { + "type": "number" + }, + "minute": { + "type": "number" + }, + "hour": { + "type": "number" + }, + "day": { + "type": "number" + }, + "month": { + "type": "number" + }, + "year": { + "type": "number" + } + } + }, + "description": "A map that defines rate limits for the plugin." + }, + "header_name": { + "type": "string", + "description": "The name of the response header used to increment the counters.", + "default": "x-kong-limit" + }, + "limit_by": { + "type": "string", + "enum": [ + "consumer", + "credential", + "ip" + ], + "description": "The entity that will be used when aggregating the limits: `consumer`, `credential`, `ip`. If the `consumer` or the `credential` cannot be determined, the system will always fallback to `ip`.", + "default": "consumer" + }, + "policy": { + "type": "string", + "enum": [ + "cluster", + "local", + "redis" + ], + "description": "The rate-limiting policies to use for retrieving and incrementing the limits.", + "default": "local" + }, + "fault_tolerant": { + "type": "boolean", + "description": "A boolean value that determines if the requests should be proxied even if Kong has troubles connecting a third-party datastore. If `true`, requests will be proxied anyway, effectively disabling the rate-limiting function until the datastore is working again. If `false`, then the clients will see `500` errors.", + "default": true + }, + "redis": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "x-referenceable": true + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + } + }, + "description": "Redis configuration" + }, + "block_on_first_violation": { + "type": "boolean", + "description": "A boolean value that determines if the requests should be blocked as soon as one limit is being exceeded. This will block requests that are supposed to consume other limits too.", + "default": false + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers.", + "default": false + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "x-supported-partials": [ + { + "name": "redis-ce", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ResponseTransformer.json b/app/_schemas/ai-gateway/policies/ResponseTransformer.json new file mode 100644 index 00000000000..df5d117867d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ResponseTransformer.json @@ -0,0 +1,202 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "append": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "description": "List of JSON type names. Specify the types of the JSON values returned when appending\nJSON properties. Each string element can be one of: boolean, number, or string.", + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "remove": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "rename": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "replace": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "description": "List of JSON type names. Specify the types of the JSON values returned when appending\nJSON properties. Each string element can be one of: boolean, number, or string.", + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "add": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "description": "List of JSON type names. Specify the types of the JSON values returned when appending\nJSON properties. Each string element can be one of: boolean, number, or string.", + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + } + } + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ResponseTransformerAdvanced.json b/app/_schemas/ai-gateway/policies/ResponseTransformerAdvanced.json new file mode 100644 index 00000000000..7d8697a61ab --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ResponseTransformerAdvanced.json @@ -0,0 +1,273 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "add": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "append": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "allow": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "transform": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "functions": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "dots_in_keys": { + "type": "boolean", + "description": "Whether dots (for example, `customers.info.phone`) should be treated as part of a property name or used to descend into nested JSON objects..", + "default": true + }, + "remove": { + "type": "object", + "properties": { + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "rename": { + "type": "object", + "properties": { + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + }, + "replace": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "String with which to replace the entire response body." + }, + "json": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "json_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "boolean", + "number", + "string" + ] + }, + "default": [] + }, + "headers": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "if_status": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + } + } + } + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RouteByHeader.json b/app/_schemas/ai-gateway/policies/RouteByHeader.json new file mode 100644 index 00000000000..f84fae864f2 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RouteByHeader.json @@ -0,0 +1,81 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "upstream_name": { + "type": "string" + }, + "condition": { + "type": "object", + "minLength": 1, + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "upstream_name" + ] + }, + "description": "Route by header rules.", + "default": [] + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/RouteTransformerAdvanced.json b/app/_schemas/ai-gateway/policies/RouteTransformerAdvanced.json new file mode 100644 index 00000000000..ed4efbedbad --- /dev/null +++ b/app/_schemas/ai-gateway/policies/RouteTransformerAdvanced.json @@ -0,0 +1,71 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "port": { + "type": "string" + }, + "host": { + "type": "string" + }, + "escape_path": { + "type": "boolean", + "default": false + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Saml.json b/app/_schemas/ai-gateway/policies/Saml.json new file mode 100644 index 00000000000..d1a0090a86f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Saml.json @@ -0,0 +1,581 @@ +{ + "properties": { + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "idp_sso_url": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "issuer": { + "type": "string", + "description": "The unique identifier of the IdP application. Formatted as a URL containing information about the IdP so the SP can validate that the SAML assertions it receives are issued from the correct IdP." + }, + "session_cookie_secure": { + "type": "boolean", + "description": "The cookie is only sent to the server when a request is made with the https:scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks." + }, + "session_request_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + } + }, + "idp_certificate": { + "type": "string", + "description": "The public certificate provided by the IdP. This is used to validate responses from the IdP. Only include the contents of the certificate. Do not include the header (`BEGIN CERTIFICATE`) and footer (`END CERTIFICATE`) lines.", + "x-referenceable": true, + "x-encrypted": true + }, + "request_signing_key": { + "type": "string", + "description": "The private key for signing requests. If this parameter is set, requests sent to the IdP are signed. The `request_signing_certificate` parameter must be set as well.", + "x-referenceable": true, + "x-encrypted": true + }, + "session_secret": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "description": "The session secret. This must be a random string of 32 characters from the base64 alphabet (letters, numbers, `/`, `_` and `+`). It is used as the secret key for encrypting session data as well as state information that is sent to the IdP in the authentication exchange.", + "x-referenceable": true, + "x-encrypted": true + }, + "session_cookie_domain": { + "type": "string", + "description": "The session cookie domain flag." + }, + "session_storage": { + "type": "string", + "enum": [ + "cookie", + "memcache", + "memcached", + "redis" + ], + "description": "The session storage for session data: - `cookie`: stores session data with the session cookie. The session cannot be invalidated or revoked without changing the session secret, but is stateless, and doesn't require a database. - `memcached`: stores session data in memcached - `redis`: stores session data in Redis", + "default": "cookie" + }, + "response_encryption_key": { + "type": "string", + "description": "The private encryption key required to decrypt encrypted assertions.", + "x-referenceable": true, + "x-encrypted": true + }, + "request_signing_certificate": { + "type": "string", + "description": "The certificate for signing requests.", + "x-referenceable": true, + "x-encrypted": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer. If not set, a Kong Consumer must exist for the SAML IdP user credentials, mapping the username format to the Kong Consumer username." + }, + "session_rolling_timeout": { + "type": "number", + "description": "The session cookie absolute timeout in seconds. Specifies how long the session can be used until it is no longer valid.", + "default": 3600 + }, + "redis": { + "type": "object", + "properties": { + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + }, + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "prefix": { + "type": "string", + "description": "The Redis session key prefix." + }, + "socket": { + "type": "string", + "description": "The Redis unix socket path." + } + } + }, + "request_digest_algorithm": { + "type": "string", + "enum": [ + "SHA1", + "SHA256" + ], + "description": "The digest algorithm for Authn requests: - `SHA256` - `SHA1`", + "default": "SHA256" + }, + "session_cookie_name": { + "type": "string", + "description": "The session cookie name.", + "default": "session" + }, + "session_response_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + } + }, + "session_store_metadata": { + "type": "boolean", + "description": "Configures whether or not session metadata should be stored. This includes information about the active sessions for the `specific_audience` belonging to a specific subject.", + "default": false + }, + "session_hash_subject": { + "type": "boolean", + "description": "When set to `true`, the value of subject is hashed before being stored. Only applies when `session_store_metadata` is enabled.", + "default": false + }, + "session_memcached_socket": { + "type": "string", + "description": "The memcached unix socket path." + }, + "response_signature_algorithm": { + "type": "string", + "enum": [ + "SHA256", + "SHA384", + "SHA512" + ], + "description": "The algorithm for validating signatures in SAML responses. Options available are: - `SHA256` - `SHA384` - `SHA512`", + "default": "SHA256" + }, + "session_absolute_timeout": { + "type": "number", + "description": "The session cookie absolute timeout in seconds. Specifies how long the session can be used until it is no longer valid.", + "default": 86400 + }, + "session_cookie_http_only": { + "type": "boolean", + "description": "Forbids JavaScript from accessing the cookie, for example, through the `Document.cookie` property.", + "default": true + }, + "session_memcached_prefix": { + "type": "string", + "description": "The memcached session key prefix." + }, + "session_memcached_host": { + "type": "string", + "description": "The memcached host.", + "default": "127.0.0.1" + }, + "response_digest_algorithm": { + "type": "string", + "enum": [ + "SHA1", + "SHA256" + ], + "description": "The algorithm for verifying digest in SAML responses: - `SHA256` - `SHA1`", + "default": "SHA256" + }, + "session_audience": { + "type": "string", + "description": "The session audience, for example \"my-application\"", + "default": "default" + }, + "session_remember_cookie_name": { + "type": "string", + "description": "Persistent session cookie name", + "default": "remember" + }, + "session_remember_rolling_timeout": { + "type": "number", + "description": "Persistent session rolling timeout in seconds.", + "default": 604800 + }, + "session_enforce_same_subject": { + "type": "boolean", + "description": "When set to `true`, audiences are forced to share the same subject.", + "default": false + }, + "session_hash_storage_key": { + "type": "boolean", + "description": "When set to `true`, the storage key (session ID) is hashed for extra security. Hashing the storage key means it is impossible to decrypt data from the storage without a cookie.", + "default": false + }, + "assertion_consumer_path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes)." + }, + "nameid_format": { + "type": "string", + "enum": [ + "EmailAddress", + "Persistent", + "Transient", + "Unspecified" + ], + "description": "The requested `NameId` format. Options available are: - `Unspecified` - `EmailAddress` - `Persistent` - `Transient`", + "default": "EmailAddress" + }, + "validate_assertion_signature": { + "type": "boolean", + "description": "Enable signature validation for SAML responses.", + "default": true + }, + "session_remember": { + "type": "boolean", + "description": "Enables or disables persistent sessions", + "default": false + }, + "session_remember_absolute_timeout": { + "type": "number", + "description": "Persistent session absolute timeout in seconds.", + "default": 2592000 + }, + "session_idling_timeout": { + "type": "number", + "description": "The session cookie idle time in seconds.", + "default": 900 + }, + "session_memcached_port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 11211 + }, + "request_signature_algorithm": { + "type": "string", + "enum": [ + "SHA256", + "SHA384", + "SHA512" + ], + "description": "The signature algorithm for signing Authn requests. Options available are: - `SHA256` - `SHA384` - `SHA512`", + "default": "SHA256" + }, + "session_cookie_path": { + "type": "string", + "description": "A string representing a URL path, such as /path/to/resource. Must start with a forward slash (/) and must not contain empty segments (i.e., two consecutive forward slashes).", + "default": "/" + }, + "session_cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.", + "default": "Lax" + } + }, + "required": [ + "assertion_consumer_path", + "idp_sso_url", + "issuer", + "session_secret" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/ServiceProtection.json b/app/_schemas/ai-gateway/policies/ServiceProtection.json new file mode 100644 index 00000000000..af05a895073 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/ServiceProtection.json @@ -0,0 +1,370 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The shared dictionary where counters are stored. When the plugin is configured to synchronize counter data externally (that is `config.strategy` is `cluster` or `redis` and `config.sync_rate` isn't `-1`), this dictionary serves as a buffer to populate counters in the data store on each synchronization cycle.", + "default": "kong_rate_limiting_counters" + }, + "redis": { + "type": "object", + "properties": { + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "cloud_authentication": { + "type": "object", + "properties": { + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-encrypted": true, + "x-referenceable": true + }, + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-referenceable": true, + "x-encrypted": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + } + } + }, + "disable_penalty": { + "type": "boolean", + "description": "If set to `true`, this doesn't count denied requests (status = `429`). If set to `false`, all requests, including denied ones, are counted. This parameter only affects the `sliding` window_type.", + "default": false + }, + "error_code": { + "type": "number", + "description": "Set a custom error code to return when the rate limit is exceeded.", + "default": 429 + }, + "window_size": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more window sizes to apply a limit to (defined in seconds). There must be a matching number of window limits and sizes specified." + }, + "namespace": { + "type": "string", + "description": "The rate limiting library namespace to use for this plugin instance. Counter data and sync configuration is isolated in each namespace. NOTE: For the plugin instances sharing the same namespace, all the configurations that are required for synchronizing counters, e.g. `strategy`, `redis`, `sync_rate`, `dictionary_name`, need to be the same." + }, + "lock_dictionary_name": { + "type": "string", + "description": "The shared dictionary where concurrency control locks are stored. The default shared dictionary is `kong_locks`. The shared dictionary should be declared in nginx-kong.conf.", + "default": "kong_locks" + }, + "hide_client_headers": { + "type": "boolean", + "description": "Optionally hide informative response headers that would otherwise provide information about the current status of limits and counters.", + "default": false + }, + "retry_after_jitter_max": { + "type": "number", + "description": "The upper bound of a jitter (random delay) in seconds to be added to the `Retry-After` header of denied requests (status = `429`) in order to prevent all the clients from coming back at the same time. The lower bound of the jitter is `0`; in this case, the `Retry-After` header is equal to the `RateLimit-Reset` header.", + "default": 0 + }, + "error_message": { + "type": "string", + "description": "Set a custom error message to return when the rate limit is exceeded.", + "default": "API rate limit exceeded" + }, + "window_type": { + "type": "string", + "enum": [ + "fixed", + "sliding" + ], + "description": "Sets the time window type to either `sliding` (default) or `fixed`. Sliding windows apply the rate limiting logic while taking into account previous hit rates (from the window that immediately precedes the current) using a dynamic weight. Fixed windows consist of buckets that are statically assigned to a definitive time range, each request is mapped to only one fixed window based on its timestamp and will affect only that window's counters.", + "default": "sliding" + }, + "limit": { + "type": "array", + "items": { + "type": "number" + }, + "description": "One or more requests-per-window limits to apply. There must be a matching number of window limits and sizes specified." + }, + "sync_rate": { + "type": "number", + "description": "How often to sync counter data to the central data store. A value of 0 results in synchronous behavior; a value of -1 ignores sync behavior entirely and only stores counters in node memory. A value greater than 0 will sync the counters in the specified number of seconds. The minimum allowed interval is 0.02 seconds (20ms)." + }, + "strategy": { + "type": "string", + "enum": [ + "cluster", + "local", + "redis" + ], + "description": "The rate-limiting strategy to use for retrieving and incrementing the limits. Available values are: `local`, `redis` and `cluster`.", + "default": "local" + } + }, + "required": [ + "limit", + "window_size" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Session.json b/app/_schemas/ai-gateway/policies/Session.json new file mode 100644 index 00000000000..1665d414afa --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Session.json @@ -0,0 +1,244 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "stale_ttl": { + "type": "number", + "description": "The duration, in seconds, after which an old cookie is discarded, starting from the moment when the session becomes outdated and is replaced by a new one.", + "default": 10 + }, + "cookie_secure": { + "type": "boolean", + "description": "Applies the Secure directive so that the cookie may be sent to the server only with an encrypted request over the HTTPS protocol.", + "default": true + }, + "remember": { + "type": "boolean", + "description": "Enables or disables persistent sessions.", + "default": false + }, + "request_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "List of information to include, as headers, in the response to the downstream." + }, + "store_metadata": { + "type": "boolean", + "description": "Whether to also store metadata of sessions, such as collecting data of sessions for a specific audience belonging to a specific subject.", + "default": false + }, + "secret": { + "type": "string", + "description": "The secret that is used in keyed HMAC generation.", + "x-encrypted": true, + "x-referenceable": true + }, + "audience": { + "type": "string", + "description": "The session audience, which is the intended target application. For example `\"my-application\"`.", + "default": "default" + }, + "rolling_timeout": { + "type": "number", + "description": "The session cookie rolling timeout, in seconds. Specifies how long the session can be used until it needs to be renewed.", + "default": 3600 + }, + "cookie_domain": { + "type": "string", + "description": "The domain with which the cookie is intended to be exchanged." + }, + "cookie_same_site": { + "type": "string", + "enum": [ + "Default", + "Lax", + "None", + "Strict" + ], + "description": "Determines whether and how a cookie may be sent with cross-site requests.", + "default": "Strict" + }, + "logout_query_arg": { + "type": "string", + "description": "The query argument passed to logout requests.", + "default": "session_logout" + }, + "storage": { + "type": "string", + "enum": [ + "cookie", + "kong" + ], + "description": "Determines where the session data is stored. `kong`: Stores encrypted session data into Kong's current database strategy; the cookie will not contain any session data. `cookie`: Stores encrypted session data within the cookie itself.", + "default": "cookie" + }, + "cookie_name": { + "type": "string", + "description": "The name of the cookie.", + "default": "session" + }, + "cookie_path": { + "type": "string", + "description": "The resource in the host where the cookie is available.", + "default": "/" + }, + "cookie_http_only": { + "type": "boolean", + "description": "Applies the `HttpOnly` tag so that the cookie is sent only to a server.", + "default": true + }, + "remember_cookie_name": { + "type": "string", + "description": "Persistent session cookie name. Use with the `remember` configuration parameter.", + "default": "remember" + }, + "remember_rolling_timeout": { + "type": "number", + "description": "The persistent session rolling timeout window, in seconds.", + "default": 604800 + }, + "remember_absolute_timeout": { + "type": "number", + "description": "The persistent session absolute timeout limit, in seconds.", + "default": 2592000 + }, + "bind": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ip", + "scheme", + "user-agent" + ] + }, + "description": "Bind the session to data acquired from the HTTP request or connection." + }, + "idling_timeout": { + "type": "number", + "description": "The session cookie idle time, in seconds.", + "default": 900 + }, + "response_headers": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "absolute-timeout", + "audience", + "id", + "idling-timeout", + "rolling-timeout", + "subject", + "timeout" + ] + }, + "description": "List of information to include, as headers, in the response to the downstream." + }, + "read_body_for_logout": { + "type": "boolean", + "default": false + }, + "logout_methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "POST" + ] + }, + "description": "A set of HTTP methods that the plugin will respond to.", + "default": [ + "DELETE", + "POST" + ] + }, + "logout_post_arg": { + "type": "string", + "description": "The POST argument passed to logout requests. Do not change this property.", + "default": "session_logout" + }, + "hash_subject": { + "type": "boolean", + "description": "Whether to hash or not the subject when store_metadata is enabled.", + "default": false + }, + "absolute_timeout": { + "type": "number", + "description": "The session cookie absolute timeout, in seconds. Specifies how long the session can be used until it is no longer valid.", + "default": 86400 + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/SolaceConsume.json b/app/_schemas/ai-gateway/policies/SolaceConsume.json new file mode 100644 index 00000000000..6eeef31838d --- /dev/null +++ b/app/_schemas/ai-gateway/policies/SolaceConsume.json @@ -0,0 +1,302 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "flow": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "The selector when binding to an endpoint." + }, + "ack_mode": { + "type": "string", + "enum": [ + "AUTO", + "CLIENT" + ], + "description": "Controls how acknowledgments are generated for received Guaranteed messages. When set to `AUTO`, the messages are positively acknowledged upon receiving them. When set to 'CLIENT', the messages are positively or negatively acknowledged by Kong regarding to client delivery status.", + "default": "CLIENT" + }, + "max_unacked_messages": { + "type": "integer", + "description": "This property controls the maximum number of messages that may be unacknowledged on the Flow.", + "default": -1 + }, + "window_size": { + "type": "integer", + "maximum": 255, + "minimum": 1, + "description": "The Guaranteed message window size for the Flow.", + "default": 255 + }, + "wait_timeout": { + "type": "integer", + "maximum": 5000, + "minimum": 1, + "description": "Specifies in milliseconds how long to wait for messages to appear on each poll before giving up or retrying.", + "default": 50 + }, + "functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates the message being received from Solace. The `message` variable can be used to access the current message content, and the function can return a new content." + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true, + "x-lua-required": true + }, + "description": "Additional Solace flow properties (each setting needs to have `FLOW_` prefix)." + }, + "binds": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the Queue that is the target of the bind. You can use $(uri_captures['\u003ccapture-identifier\u003e']) in this field (replace `\u003ccapture-identifier\u003e` with a real value, for example `$uri_captures['queue']` when the matched route has a path `~/(?\u003cqueue\u003e[a-z]+)`)" + }, + "type": { + "type": "string", + "enum": [ + "QUEUE" + ], + "description": "The type of object to which this Flow is bound.", + "default": "QUEUE" + } + }, + "required": [ + "name" + ] + }, + "minLength": 1 + } + }, + "required": [ + "binds" + ], + "description": "The flow related configuration." + }, + "mode": { + "type": "string", + "enum": [ + "AUTO", + "POLLING", + "SERVER-SENT-EVENTS", + "WEBSOCKET" + ], + "description": "The mode of operation for the plugin. The `AUTO` determines the mode automatically from the client request.", + "default": "POLLING" + }, + "polling": { + "type": "object", + "properties": { + "timeout": { + "type": "integer", + "maximum": 300000, + "minimum": 0, + "description": "Polling timeout in milliseconds. When set to `0`, the polling works like short-polling and waits at maximum the Flow `wait_timeout` amount of time for the new messages (short-polling). When set to larger than `0`, the connection is kept open and only closed after the timeout or in case messages appear earlier (long-polling).", + "default": 0 + } + }, + "description": "The `POLLING` mode related configuration settings." + }, + "websocket": { + "type": "object", + "properties": { + "timeout": { + "type": "integer", + "maximum": 60000, + "minimum": 1, + "description": "Specifies the network timeout threshold in milliseconds.", + "default": 1000 + }, + "max_recv_len": { + "type": "integer", + "description": "Specifies the maximal length of payload allowed when receiving WebSocket frames.", + "default": 65536 + }, + "max_send_len": { + "type": "integer", + "description": "Specifies the maximal length of payload allowed when sending WebSocket frames.", + "default": 65536 + } + }, + "description": "The `WEBSOCKET` mode related configuration settings." + }, + "session": { + "type": "object", + "properties": { + "generate_send_timestamps": { + "type": "boolean", + "description": "When enabled, a send timestamp is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "generate_sequence_number": { + "type": "boolean", + "description": "When enabled, a sequence number is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true, + "x-lua-required": true + }, + "description": "Additional Solace session properties (each setting needs to have `SESSION_` prefix)." + }, + "host": { + "type": "string", + "description": "The IPv4 or IPv6 address or host name to connect to (see: https://docs.solace.com/API-Developer-Online-Ref-Documentation/c/index.html#host-entry).", + "x-referenceable": true + }, + "vpn_name": { + "type": "string", + "maxLength": 32, + "description": "The name of the Message VPN to attempt to join when connecting to an event broker." + }, + "authentication": { + "type": "object", + "properties": { + "id_token": { + "type": "string", + "description": "The OpenID Connect ID token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "id_token_header": { + "type": "string", + "description": "Specifies the header that contains id token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `id_token` field." + }, + "scheme": { + "type": "string", + "enum": [ + "BASIC", + "NONE", + "OAUTH2" + ], + "description": "The client authentication scheme used when connection to an event broker.", + "default": "BASIC" + }, + "username": { + "type": "string", + "maxLength": 189, + "description": "The username used with `BASIC` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "maxLength": 128, + "description": "The password used with `BASIC` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "basic_auth_header": { + "type": "string", + "description": "Specifies the header that contains Basic Authentication credentials for the `BASIC` authentication scheme when connecting to an event broker. This header takes precedence over the `username` and `password` fields." + }, + "access_token": { + "type": "string", + "description": "The OAuth2 access token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "access_token_header": { + "type": "string", + "description": "Specifies the header that contains access token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `access_token` field." + } + }, + "description": "Session authentication related configuration." + }, + "ssl_validate_certificate": { + "type": "boolean", + "description": "Indicates whether the API should validate server certificates with the trusted certificates.", + "default": true + }, + "calculate_message_expiry": { + "type": "boolean", + "description": "If this property is true and time-to-live has a positive value in a message, the expiration time is calculated when the message is sent or received", + "default": true + }, + "generate_sender_id": { + "type": "boolean", + "description": "When enabled, a sender id is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 100000, + "minimum": 100, + "description": "The timeout period (in milliseconds) for a connect operation to a given host (per host).", + "default": 3000 + }, + "generate_rcv_timestamps": { + "type": "boolean", + "description": "When enabled, a receive timestamp is recorded for each message.", + "default": true + } + }, + "required": [ + "host" + ], + "description": "Session related configuration." + } + }, + "required": [ + "flow", + "session" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/SolaceLog.json b/app/_schemas/ai-gateway/policies/SolaceLog.json new file mode 100644 index 00000000000..d0f08a5bafd --- /dev/null +++ b/app/_schemas/ai-gateway/policies/SolaceLog.json @@ -0,0 +1,267 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpc", + "grpcs", + "http", + "https", + "ws", + "wss" + ] + }, + "config": { + "type": "object", + "properties": { + "session": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "The IPv4 or IPv6 address or host name to connect to (see: https://docs.solace.com/API-Developer-Online-Ref-Documentation/c/index.html#host-entry).", + "x-referenceable": true + }, + "vpn_name": { + "type": "string", + "maxLength": 32, + "description": "The name of the Message VPN to attempt to join when connecting to an event broker." + }, + "connect_timeout": { + "type": "integer", + "maximum": 100000, + "minimum": 100, + "description": "The timeout period (in milliseconds) for a connect operation to a given host (per host).", + "default": 3000 + }, + "ssl_validate_certificate": { + "type": "boolean", + "description": "Indicates whether the API should validate server certificates with the trusted certificates.", + "default": true + }, + "generate_send_timestamps": { + "type": "boolean", + "description": "When enabled, a send timestamp is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "generate_sequence_number": { + "type": "boolean", + "description": "When enabled, a sequence number is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "authentication": { + "type": "object", + "properties": { + "username": { + "type": "string", + "maxLength": 189, + "description": "The username used with `BASIC` authentication scheme when connecting to an event broker.", + "x-encrypted": true, + "x-referenceable": true + }, + "password": { + "type": "string", + "maxLength": 128, + "description": "The password used with `BASIC` authentication scheme when connecting to an event broker.", + "x-encrypted": true, + "x-referenceable": true + }, + "basic_auth_header": { + "type": "string", + "description": "Specifies the header that contains Basic Authentication credentials for the `BASIC` authentication scheme when connecting to an event broker. This header takes precedence over the `username` and `password` fields." + }, + "access_token": { + "type": "string", + "description": "The OAuth2 access token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "access_token_header": { + "type": "string", + "description": "Specifies the header that contains access token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `access_token` field." + }, + "id_token": { + "type": "string", + "description": "The OpenID Connect ID token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "id_token_header": { + "type": "string", + "description": "Specifies the header that contains id token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `id_token` field." + }, + "scheme": { + "type": "string", + "enum": [ + "BASIC", + "NONE", + "OAUTH2" + ], + "description": "The client authentication scheme used when connection to an event broker.", + "default": "BASIC" + } + }, + "description": "Session authentication related configuration." + }, + "calculate_message_expiry": { + "type": "boolean", + "description": "If this property is true and time-to-live has a positive value in a message, the expiration time is calculated when the message is sent or received", + "default": true + }, + "generate_rcv_timestamps": { + "type": "boolean", + "description": "When enabled, a receive timestamp is recorded for each message.", + "default": true + }, + "generate_sender_id": { + "type": "boolean", + "description": "When enabled, a sender id is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true, + "x-lua-required": true + }, + "description": "Additional Solace session properties (each setting needs to have `SESSION_` prefix)." + } + }, + "required": [ + "host" + ], + "description": "Session related configuration." + }, + "message": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Sets the time to live (TTL) in milliseconds for the log message. Setting the time to live to zero disables the TTL for the log message.", + "default": 0 + }, + "ack_timeout": { + "type": "integer", + "maximum": 100000, + "minimum": 1, + "description": "When using a non-DIRECT guaranteed delivery mode, this property sets the log message acknowledgement timeout (waiting time).", + "default": 2000 + }, + "tracing": { + "type": "boolean", + "description": "Enable or disable the tracing propagation. This is primarily used for distributed tracing and message correlation, especially in debugging or tracking message flows across multiple systems.", + "default": false + }, + "tracing_sampled": { + "type": "boolean", + "description": "Forcibly turn on the tracing on all the messages for distributed tracing (tracing needs to be enabled as well).", + "default": false + }, + "delivery_mode": { + "type": "string", + "enum": [ + "DIRECT", + "PERSISTENT" + ], + "description": "Sets the log message delivery mode.", + "default": "DIRECT" + }, + "priority": { + "type": "integer", + "maximum": 255, + "minimum": 0, + "description": "Sets the log message priority.", + "default": 4 + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "A key-value map that dynamically modifies log fields using Lua code." + }, + "destinations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the destination. You can use `$(uri_captures['\u003ccapture-identifier\u003e'])` in this field to capture the name from a regex request URI (replace `\u003ccapture-identifier\u003e` with a real value; for example `$(uri_captures['queue'])` when the matched route has a path `~/(?\u003cqueue\u003e[a-z]+)`)." + }, + "type": { + "type": "string", + "enum": [ + "QUEUE", + "TOPIC" + ], + "description": "The type of the destination.", + "default": "QUEUE" + } + }, + "required": [ + "name" + ] + }, + "minLength": 1, + "description": "The log message destinations." + }, + "sender_id": { + "type": "string", + "description": "Allows the application to set the sender identifier." + }, + "dmq_eligible": { + "type": "boolean", + "description": "Sets the dead message queue (DMQ) eligible property on the log message.", + "default": false + } + }, + "required": [ + "destinations" + ], + "description": "The log message related configuration." + } + }, + "required": [ + "message", + "session" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/SolaceUpstream.json b/app/_schemas/ai-gateway/policies/SolaceUpstream.json new file mode 100644 index 00000000000..40e44fe1c67 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/SolaceUpstream.json @@ -0,0 +1,342 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "message": { + "type": "object", + "properties": { + "destinations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the destination. You can use $(uri_captures['\u003ccapture-identifier\u003e']) in this field (replace `\u003ccapture-identifier\u003e` with a real value, for example `$uri_captures[’queue’]` when the matched route has a path `~/(?\u003cqueue\u003e[a-z]+)`)." + }, + "type": { + "type": "string", + "enum": [ + "QUEUE", + "TOPIC" + ], + "description": "The type of the destination.", + "default": "QUEUE" + } + }, + "required": [ + "name" + ] + }, + "minLength": 1, + "description": "The message destinations." + }, + "tracing": { + "type": "boolean", + "description": "Enable or disable the tracing propagation. This is primarily used for distributed tracing and message correlation, especially in debugging or tracking message flows across multiple systems.", + "default": false + }, + "forward_headers": { + "type": "boolean", + "description": "Include the request headers in the message.", + "default": false + }, + "functions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The Lua functions that manipulates (or generates) the message being sent to Solace. The `message` variable can be used to access the current message content, and the function can return a new content." + }, + "ttl": { + "type": "integer", + "description": "Sets the time to live (TTL) in milliseconds for the message. Setting the time to live to zero disables the TTL for the message.", + "default": 0 + }, + "ack_timeout": { + "type": "integer", + "maximum": 100000, + "minimum": 1, + "description": "When using a non-DIRECT guaranteed delivery mode, this property sets the message acknowledgement timeout in milliseconds (waiting time).", + "default": 2000 + }, + "forward_body": { + "type": "boolean", + "description": "Include the request body and the body arguments in the message.", + "default": false + }, + "content_type": { + "type": "string", + "description": "Sets the HTTP Content-Type applied to the Solace message payload. If unset, the request Content-Type header is used when available." + }, + "user_properties": { + "type": "object", + "properties": { + "predefined_properties": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-lua-required": true + }, + "description": "Predefined user properties to set on every message (key = property name, value = property value)." + }, + "headers": { + "type": "object", + "properties": { + "exclude_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Headers that must not be forwarded into user properties. This is used to exclude sensitive headers such as authorization from being forwarded as user properties, or to avoid duplication when a header is mapped to a user property but you don't want the original header to be included as well." + }, + "mappings": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-lua-required": true + }, + "description": "Header-to-user_property mapping (key = HTTP header name, value = target user property name)." + }, + "include_headers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Headers to include as user properties even without explicit mapping." + } + }, + "description": "Header settings for user properties (mapping, inclusion and exclusion)." + } + }, + "description": "User defined properties to be included in the message. Separate static properties from header mappings." + }, + "delivery_mode": { + "type": "string", + "enum": [ + "DIRECT", + "PERSISTENT" + ], + "description": "Sets the message delivery mode.", + "default": "DIRECT" + }, + "priority": { + "type": "integer", + "maximum": 255, + "minimum": 0, + "description": "Sets the message priority.", + "default": 4 + }, + "tracing_sampled": { + "type": "boolean", + "description": "Forcibly turn on the tracing on all the messages for distributed tracing (tracing needs to be enabled as well).", + "default": false + }, + "forward_uri": { + "type": "boolean", + "description": "Include the request URI and the URI arguments (as in, query arguments) in the message.", + "default": false + }, + "forward_body_raw_only": { + "type": "boolean", + "description": "Forward only the raw request body without wrapping it in a JSON payload or adding extra fields.", + "default": false + }, + "content_encoding": { + "type": "string", + "description": "Sets the HTTP Content-Encoding applied to the Solace message payload (for example, gzip). If unset, the request Content-Encoding header is used when available." + }, + "sender_id": { + "type": "string", + "description": "Allows the application to set the content of the sender identifier." + }, + "dmq_eligible": { + "type": "boolean", + "description": "Sets the dead message queue (DMQ) eligible property on the message.", + "default": false + }, + "forward_method": { + "type": "boolean", + "description": "Include the request method in the message.", + "default": false + }, + "default_content": { + "type": "string", + "description": "When not using `forward_method`, `forward_uri`, `forward_headers`, `forward_body` or `forward_body_raw_only`, this sets the message content." + } + }, + "required": [ + "destinations" + ], + "description": "The message related configuration." + }, + "session": { + "type": "object", + "properties": { + "generate_rcv_timestamps": { + "type": "boolean", + "description": "When enabled, a receive timestamp is recorded for each message.", + "default": true + }, + "generate_send_timestamps": { + "type": "boolean", + "description": "When enabled, a send timestamp is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true, + "x-lua-required": true + }, + "description": "Additional Solace session properties (each setting needs to have `SESSION_` prefix)." + }, + "host": { + "type": "string", + "description": "The IPv4 or IPv6 address or host name to connect to (see: https://docs.solace.com/API-Developer-Online-Ref-Documentation/c/index.html#host-entry).", + "x-referenceable": true + }, + "authentication": { + "type": "object", + "properties": { + "id_token_header": { + "type": "string", + "description": "Specifies the header that contains id token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `id_token` field." + }, + "scheme": { + "type": "string", + "enum": [ + "BASIC", + "NONE", + "OAUTH2" + ], + "description": "The client authentication scheme used when connection to an event broker.", + "default": "BASIC" + }, + "username": { + "type": "string", + "maxLength": 189, + "description": "The username used with `BASIC` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "maxLength": 128, + "description": "The password used with `BASIC` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "basic_auth_header": { + "type": "string", + "description": "Specifies the header that contains Basic Authentication credentials for the `BASIC` authentication scheme when connecting to an event broker. This header takes precedence over the `username` and `password` fields." + }, + "access_token": { + "type": "string", + "description": "The OAuth2 access token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + }, + "access_token_header": { + "type": "string", + "description": "Specifies the header that contains access token for the `OAUTH2` authentication scheme when connecting to an event broker. This header takes precedence over the `access_token` field." + }, + "id_token": { + "type": "string", + "description": "The OpenID Connect ID token used with `OAUTH2` authentication scheme when connecting to an event broker.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Session authentication related configuration." + }, + "connect_timeout": { + "type": "integer", + "maximum": 100000, + "minimum": 100, + "description": "The timeout period (in milliseconds) for a connect operation to a given host (per host).", + "default": 3000 + }, + "calculate_message_expiry": { + "type": "boolean", + "description": "If this property is true and time-to-live has a positive value in a message, the expiration time is calculated when the message is sent or received", + "default": true + }, + "generate_sender_id": { + "type": "boolean", + "description": "When enabled, a sender id is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "generate_sequence_number": { + "type": "boolean", + "description": "When enabled, a sequence number is automatically included (if not already present) in the Solace-defined fields for each message sent.", + "default": true + }, + "vpn_name": { + "type": "string", + "maxLength": 32, + "description": "The name of the Message VPN to attempt to join when connecting to an event broker." + }, + "ssl_validate_certificate": { + "type": "boolean", + "description": "Indicates whether the API should validate server certificates with the trusted certificates.", + "default": true + } + }, + "required": [ + "host" + ], + "description": "Session related configuration." + } + }, + "required": [ + "message", + "session" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/StandardWebhooks.json b/app/_schemas/ai-gateway/policies/StandardWebhooks.json new file mode 100644 index 00000000000..0f3cebc32fe --- /dev/null +++ b/app/_schemas/ai-gateway/policies/StandardWebhooks.json @@ -0,0 +1,75 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "secret_v1": { + "type": "string", + "description": "Webhook secret", + "x-referenceable": true, + "x-encrypted": true + }, + "tolerance_second": { + "type": "integer", + "description": "Tolerance of the webhook timestamp in seconds. If the webhook timestamp is older than this number of seconds, it will be rejected with a '400' response.", + "default": 300 + } + }, + "required": [ + "secret_v1" + ] + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Statsd.json b/app/_schemas/ai-gateway/policies/Statsd.json new file mode 100644 index 00000000000..3f1f298209e --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Statsd.json @@ -0,0 +1,283 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "workspace_identifier_default": { + "type": "string", + "enum": [ + "workspace_id", + "workspace_name" + ], + "default": "workspace_id" + }, + "allow_status_codes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of status code ranges that are allowed to be logged in metrics." + }, + "udp_packet_size": { + "type": "number", + "maximum": 65507, + "minimum": 0, + "default": 0 + }, + "prefix": { + "type": "string", + "description": "String to prefix to each metric's name.", + "default": "kong" + }, + "metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "workspace_identifier": { + "type": "string", + "enum": [ + "workspace_id", + "workspace_name" + ], + "description": "Workspace detail." + }, + "name": { + "type": "string", + "enum": [ + "cache_datastore_hits_total", + "cache_datastore_misses_total", + "kong_latency", + "latency", + "request_count", + "request_per_user", + "request_size", + "response_size", + "shdict_usage", + "status_count", + "status_count_per_user", + "status_count_per_user_per_route", + "status_count_per_workspace", + "unique_users", + "upstream_latency" + ], + "description": "StatsD metric’s name." + }, + "stat_type": { + "type": "string", + "enum": [ + "counter", + "gauge", + "histogram", + "meter", + "set", + "timer" + ], + "description": "Determines what sort of event a metric represents." + }, + "sample_rate": { + "type": "number", + "description": "Sampling rate" + }, + "consumer_identifier": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ], + "description": "Authenticated user detail." + }, + "service_identifier": { + "type": "string", + "enum": [ + "service_host", + "service_id", + "service_name", + "service_name_or_host" + ], + "description": "Service detail." + } + }, + "required": [ + "name", + "stat_type" + ] + }, + "description": "List of metrics to be logged." + }, + "hostname_in_prefix": { + "type": "boolean", + "default": false + }, + "consumer_identifier_default": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ], + "default": "custom_id" + }, + "retry_count": { + "type": "integer" + }, + "queue_size": { + "type": "integer" + }, + "flush_timeout": { + "type": "number" + }, + "host": { + "type": "string", + "description": "The IP address or hostname of StatsD server to send data to.", + "default": "localhost" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "The port of StatsD server to send data to.", + "default": 8125 + }, + "service_identifier_default": { + "type": "string", + "enum": [ + "service_host", + "service_id", + "service_name", + "service_name_or_host" + ], + "default": "service_name_or_host" + }, + "tag_style": { + "type": "string", + "enum": [ + "dogstatsd", + "influxdb", + "librato", + "signalfx" + ] + }, + "queue": { + "type": "object", + "properties": { + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + }, + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + }, + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + } + } + }, + "use_tcp": { + "type": "boolean", + "default": false + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/StatsdAdvanced.json b/app/_schemas/ai-gateway/policies/StatsdAdvanced.json new file mode 100644 index 00000000000..b890819ce2f --- /dev/null +++ b/app/_schemas/ai-gateway/policies/StatsdAdvanced.json @@ -0,0 +1,265 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "workspace_identifier_default": { + "type": "string", + "enum": [ + "workspace_id", + "workspace_name" + ], + "description": "The default workspace identifier for metrics. This will take effect when a metric's workspace identifier is omitted. Allowed values are `workspace_id`, `workspace_name`. ", + "default": "workspace_id" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 8125 + }, + "metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "service_identifier": { + "type": "string", + "enum": [ + "service_host", + "service_id", + "service_name", + "service_name_or_host" + ] + }, + "workspace_identifier": { + "type": "string", + "enum": [ + "workspace_id", + "workspace_name" + ] + }, + "name": { + "type": "string", + "enum": [ + "cache_datastore_hits_total", + "cache_datastore_misses_total", + "kong_latency", + "latency", + "request_count", + "request_per_user", + "request_size", + "response_size", + "shdict_usage", + "status_count", + "status_count_per_user", + "status_count_per_user_per_route", + "status_count_per_workspace", + "unique_users", + "upstream_latency" + ] + }, + "stat_type": { + "type": "string", + "enum": [ + "counter", + "gauge", + "histogram", + "meter", + "set", + "timer" + ] + }, + "sample_rate": { + "type": "number" + }, + "consumer_identifier": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ] + } + }, + "required": [ + "name", + "stat_type" + ] + }, + "description": "List of Metrics to be logged." + }, + "service_identifier_default": { + "type": "string", + "enum": [ + "service_host", + "service_id", + "service_name", + "service_name_or_host" + ], + "description": "The default service identifier for metrics. This will take effect when a metric's service identifier is omitted. Allowed values are `service_name_or_host`, `service_id`, `service_name`, `service_host`.", + "default": "service_name_or_host" + }, + "queue": { + "type": "object", + "properties": { + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + }, + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + }, + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + } + } + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "localhost" + }, + "prefix": { + "type": "string", + "description": "String to prefix to each metric's name.", + "default": "kong" + }, + "allow_status_codes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of status code ranges that are allowed to be logged in metrics." + }, + "udp_packet_size": { + "type": "number", + "maximum": 65507, + "minimum": 0, + "description": "Combine UDP packet up to the size configured. If zero (0), don't combine the UDP packet. Must be a number between 0 and 65507 (inclusive).", + "default": 0 + }, + "use_tcp": { + "type": "boolean", + "description": "Use TCP instead of UDP.", + "default": false + }, + "hostname_in_prefix": { + "type": "boolean", + "description": "Include the `hostname` in the `prefix` for each metric name.", + "default": false + }, + "consumer_identifier_default": { + "type": "string", + "enum": [ + "consumer_id", + "custom_id", + "username" + ], + "description": "The default consumer identifier for metrics. This will take effect when a metric's consumer identifier is omitted. Allowed values are `custom_id`, `consumer_id`, `username`.", + "default": "custom_id" + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Syslog.json b/app/_schemas/ai-gateway/policies/Syslog.json new file mode 100644 index 00000000000..61590a75113 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Syslog.json @@ -0,0 +1,155 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + }, + "facility": { + "type": "string", + "enum": [ + "auth", + "authpriv", + "cron", + "daemon", + "ftp", + "kern", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + "lpr", + "mail", + "news", + "syslog", + "user", + "uucp" + ], + "description": "The facility is used by the operating system to decide how to handle each log message.", + "default": "user" + }, + "log_level": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "successful_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "client_errors_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + }, + "server_errors_severity": { + "type": "string", + "enum": [ + "alert", + "crit", + "debug", + "emerg", + "err", + "info", + "notice", + "warning" + ], + "default": "info" + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/TcpLog.json b/app/_schemas/ai-gateway/policies/TcpLog.json new file mode 100644 index 00000000000..85f3f18d6aa --- /dev/null +++ b/app/_schemas/ai-gateway/policies/TcpLog.json @@ -0,0 +1,113 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "keepalive": { + "type": "number", + "description": "An optional value in milliseconds that defines how long an idle connection lives before being closed.", + "default": 60000 + }, + "tls": { + "type": "boolean", + "description": "Indicates whether to perform a TLS handshake against the remote server.", + "default": false + }, + "tls_sni": { + "type": "string", + "description": "An optional string that defines the SNI (Server Name Indication) hostname to send in the TLS handshake." + }, + "ssl_verify": { + "type": "boolean", + "description": "When using TLS, this option enables verification of the certificate presented by the server.", + "default": true + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "A list of key-value pairs, where the key is the name of a log field and the value is a chunk of Lua code, whose return value sets or replaces the log field value." + }, + "host": { + "type": "string", + "description": "The IP address or host name to send data to." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "The port to send data to on the upstream server." + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when sending data to the upstream server.", + "default": 10000 + } + }, + "required": [ + "host", + "port" + ] + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/TlsHandshakeModifier.json b/app/_schemas/ai-gateway/policies/TlsHandshakeModifier.json new file mode 100644 index 00000000000..851963c5b29 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/TlsHandshakeModifier.json @@ -0,0 +1,53 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpcs", + "https", + "tls" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpcs", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "tls_client_certificate": { + "type": "string", + "enum": [ + "REQUEST" + ], + "description": "TLS Client Certificate", + "default": "REQUEST" + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/TlsMetadataHeaders.json b/app/_schemas/ai-gateway/policies/TlsMetadataHeaders.json new file mode 100644 index 00000000000..e319f084400 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/TlsMetadataHeaders.json @@ -0,0 +1,75 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpcs", + "https", + "tls" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "grpcs", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "inject_client_cert_details": { + "type": "boolean", + "description": "Enables TLS client certificate metadata values to be injected into HTTP headers.", + "default": false + }, + "client_cert_header_name": { + "type": "string", + "description": "Define the HTTP header name used for the PEM format URL encoded client certificate.", + "default": "X-Client-Cert" + }, + "client_serial_header_name": { + "type": "string", + "description": "Define the HTTP header name used for the serial number of the client certificate.", + "default": "X-Client-Cert-Serial" + }, + "client_cert_issuer_dn_header_name": { + "type": "string", + "description": "Define the HTTP header name used for the issuer DN of the client certificate.", + "default": "X-Client-Cert-Issuer-DN" + }, + "client_cert_subject_dn_header_name": { + "type": "string", + "description": "Define the HTTP header name used for the subject DN of the client certificate.", + "default": "X-Client-Cert-Subject-DN" + }, + "client_cert_fingerprint_header_name": { + "type": "string", + "description": "Define the HTTP header name used for the SHA1 fingerprint of the client certificate.", + "default": "X-Client-Cert-Fingerprint" + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/UdpLog.json b/app/_schemas/ai-gateway/policies/UdpLog.json new file mode 100644 index 00000000000..605e57125ea --- /dev/null +++ b/app/_schemas/ai-gateway/policies/UdpLog.json @@ -0,0 +1,94 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com." + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive." + }, + "timeout": { + "type": "number", + "description": "An optional timeout in milliseconds when sending data to the upstream server.", + "default": 10000 + }, + "custom_fields_by_lua": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Lua code as a key-value map" + } + }, + "required": [ + "host", + "port" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/UpstreamOauth.json b/app/_schemas/ai-gateway/policies/UpstreamOauth.json new file mode 100644 index 00000000000..444a2ff4b48 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/UpstreamOauth.json @@ -0,0 +1,547 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "cache": { + "type": "object", + "properties": { + "strategy": { + "type": "string", + "enum": [ + "memory", + "redis" + ], + "description": "The method Kong should use to cache tokens issued by the IdP.", + "default": "memory" + }, + "memory": { + "type": "object", + "properties": { + "dictionary_name": { + "type": "string", + "description": "The shared dictionary used by the plugin to cache tokens if `config.cache.strategy` is set to `memory`.", + "default": "kong_db_cache" + } + } + }, + "redis": { + "type": "object", + "properties": { + "cloud_authentication": { + "type": "object", + "properties": { + "aws_role_session_name": { + "type": "string", + "description": "The session name for the temporary credentials when assuming the IAM role.", + "x-encrypted": true, + "x-referenceable": true + }, + "gcp_service_account_json": { + "type": "string", + "description": "GCP Service Account JSON to be used for authentication when `auth_provider` is set to `gcp`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_id": { + "type": "string", + "description": "Azure Client ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_client_secret": { + "type": "string", + "description": "Azure Client Secret to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "auth_provider": { + "type": "string", + "enum": [ + "aws", + "azure", + "gcp" + ], + "description": "Auth providers to be used to authenticate to a Cloud Provider's Redis instance.", + "x-referenceable": true + }, + "aws_region": { + "type": "string", + "description": "The region of the AWS ElastiCache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_secret_access_key": { + "type": "string", + "description": "AWS Secret Access Key to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_assume_role_arn": { + "type": "string", + "description": "The ARN of the IAM role to assume for generating ElastiCache IAM authentication tokens.", + "x-referenceable": true, + "x-encrypted": true + }, + "azure_tenant_id": { + "type": "string", + "description": "Azure Tenant ID to be used for authentication when `auth_provider` is set to `azure`.", + "x-referenceable": true, + "x-encrypted": true + }, + "aws_cache_name": { + "type": "string", + "description": "The name of the AWS Elasticache cluster when `auth_provider` is set to `aws`.", + "x-referenceable": true + }, + "aws_is_serverless": { + "type": "boolean", + "description": "This flag specifies whether the cluster is serverless when auth_provider is set to `aws`.", + "default": true + }, + "aws_access_key_id": { + "type": "string", + "description": "AWS Access Key ID to be used for authentication when `auth_provider` is set to `aws`.", + "x-referenceable": true, + "x-encrypted": true + } + }, + "description": "Cloud auth related configs for connecting to a Cloud Provider's Redis instance." + }, + "sentinel_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Sentinel node addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Sentinel. The minimum length of the array is 1 element." + }, + "ssl": { + "type": "boolean", + "description": "If set to true, uses SSL to connect to Redis.", + "default": false + }, + "cluster_max_redirections": { + "type": "integer", + "description": "Maximum retry attempts for redirection.", + "default": 5 + }, + "username": { + "type": "string", + "description": "Username to use for Redis connections. If undefined, ACL authentication won't be performed. This requires Redis v6.0.0+. To be compatible with Redis v5.x.y, you can set it to `default`.", + "x-referenceable": true + }, + "database": { + "type": "integer", + "description": "Database to use for the Redis connection when using the `redis` strategy", + "default": 0 + }, + "keepalive_pool_size": { + "type": "integer", + "maximum": 2147483646, + "minimum": 1, + "description": "The size limit for every cosocket connection pool associated with every remote server, per worker process. If neither `keepalive_pool_size` nor `keepalive_backlog` is specified, no pool is created. If `keepalive_pool_size` isn't specified but `keepalive_backlog` is specified, then the pool uses the default value. Try to increase (e.g. 512) this value if latency is high or throughput is low.", + "default": 256 + }, + "sentinel_master": { + "type": "string", + "description": "Sentinel master to use for Redis connections. Defining this value implies using Redis Sentinel." + }, + "cluster_nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1" + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379 + } + } + }, + "minLength": 1, + "description": "Cluster addresses to use for Redis connections when the `redis` strategy is defined. Defining this field implies using a Redis Cluster. The minimum length of the array is 1 element." + }, + "ssl_verify": { + "type": "boolean", + "description": "If set to true, verifies the validity of the server SSL certificate. If setting this parameter, also configure `lua_ssl_trusted_certificate` in `kong.conf` to specify the CA (or server) certificate used by your Redis server. You may also need to configure `lua_ssl_verify_depth` accordingly.", + "default": true + }, + "port": { + "type": "integer", + "maximum": 65535, + "minimum": 0, + "description": "An integer representing a port number between 0 and 65535, inclusive.", + "default": 6379, + "x-referenceable": true + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "password": { + "type": "string", + "description": "Password to use for Redis connections. If undefined, no AUTH commands are sent to Redis.", + "x-referenceable": true, + "x-encrypted": true + }, + "sentinel_username": { + "type": "string", + "description": "Sentinel username to authenticate with a Redis Sentinel instance. If undefined, ACL authentication won't be performed. This requires Redis v6.2.0+.", + "x-referenceable": true + }, + "keepalive_backlog": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Limits the total number of opened connections for a pool. If the connection pool is full, connection queues above the limit go into the backlog queue. If the backlog queue is full, subsequent connect operations fail and return `nil`. Queued operations (subject to set timeouts) resume once the number of connections in the pool is less than `keepalive_pool_size`. If latency is high or throughput is low, try increasing this value. Empirically, this value is larger than `keepalive_pool_size`." + }, + "sentinel_role": { + "type": "string", + "enum": [ + "any", + "master", + "slave" + ], + "description": "Sentinel role to use for Redis connections when the `redis` strategy is defined. Defining this value implies using Redis Sentinel." + }, + "server_name": { + "type": "string", + "description": "A string representing an SNI (server name indication) value for TLS.", + "x-referenceable": true + }, + "host": { + "type": "string", + "description": "A string representing a host name, such as example.com.", + "default": "127.0.0.1", + "x-referenceable": true + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sentinel_password": { + "type": "string", + "description": "Sentinel password to authenticate with a Redis Sentinel instance. If undefined, no AUTH commands are sent to Redis Sentinels.", + "x-referenceable": true, + "x-encrypted": true + }, + "connection_is_proxied": { + "type": "boolean", + "description": "If the connection to Redis is proxied (e.g. Envoy), set it `true`. Set the `host` and `port` to point to the proxy address.", + "default": false + } + } + }, + "eagerly_expire": { + "type": "integer", + "description": "The number of seconds to eagerly expire a cached token. By default, a cached token expires 5 seconds before its lifetime as defined in `expires_in`.", + "default": 5 + }, + "default_ttl": { + "type": "number", + "description": "The lifetime of a token without an explicit `expires_in` value.", + "default": 3600 + } + } + }, + "behavior": { + "type": "object", + "properties": { + "purge_token_on_upstream_status_codes": { + "type": "array", + "items": { + "type": "integer", + "maximum": 599, + "minimum": 100 + }, + "description": "An array of status codes which will force an access token to be purged when returned by the upstream. An empty array will disable this functionality.", + "default": [ + 401 + ] + }, + "upstream_access_token_header_name": { + "type": "string", + "description": "The name of the header used to send the access token (obtained from the IdP) to the upstream service.", + "default": "Authorization" + }, + "idp_error_response_status_code": { + "type": "integer", + "maximum": 599, + "minimum": 500, + "description": "The response code to return to the consumer if Kong fails to obtain a token from the IdP.", + "default": 502 + }, + "idp_error_response_content_type": { + "type": "string", + "description": "The Content-Type of the response to return to the consumer if Kong fails to obtain a token from the IdP.", + "default": "application/json; charset=utf-8" + }, + "idp_error_response_message": { + "type": "string", + "description": "The message to embed in the body of the response to return to the consumer if Kong fails to obtain a token from the IdP.", + "default": "Failed to authenticate request to upstream" + }, + "idp_error_response_body_template": { + "type": "string", + "description": "The template to use to create the body of the response to return to the consumer if Kong fails to obtain a token from the IdP.", + "default": "{ \"code\": \"{{status}}\", \"message\": \"{{message}}\" }" + } + } + }, + "client": { + "type": "object", + "properties": { + "auth_method": { + "type": "string", + "enum": [ + "client_secret_basic", + "client_secret_jwt", + "client_secret_post", + "none" + ], + "description": "The authentication method used in client requests to the IdP. Supported values are: `client_secret_basic` to send `client_id` and `client_secret` in the `Authorization: Basic` header, `client_secret_post` to send `client_id` and `client_secret` as part of the request body, or `client_secret_jwt` to send a JWT signed with the `client_secret` using the client assertion as part of the body.", + "default": "client_secret_post" + }, + "http_version": { + "type": "number", + "description": "The HTTP version used for requests made by this plugin. Supported values: `1.1` for HTTP 1.1 and `1.0` for HTTP 1.0.", + "default": 1.1 + }, + "http_proxy": { + "type": "string", + "description": "The proxy to use when making HTTP requests to the IdP." + }, + "http_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `http_proxy`." + }, + "https_proxy_authorization": { + "type": "string", + "description": "The `Proxy-Authorization` header value to be used with `https_proxy`." + }, + "no_proxy": { + "type": "string", + "description": "A comma-separated list of hosts that should not be proxied." + }, + "timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "Network I/O timeout for requests to the IdP in milliseconds.", + "default": 10000 + }, + "client_secret_jwt_alg": { + "type": "string", + "enum": [ + "HS256", + "HS512" + ], + "description": "The algorithm to use with JWT when using `client_secret_jwt` authentication.", + "default": "HS512" + }, + "https_proxy": { + "type": "string", + "description": "The proxy to use when making HTTPS requests to the IdP." + }, + "keep_alive": { + "type": "boolean", + "description": "Whether to use keepalive connections to the IdP.", + "default": true + }, + "ssl_verify": { + "type": "boolean", + "description": "Whether to verify the certificate presented by the IdP when using HTTPS.", + "default": true + } + } + }, + "oauth": { + "type": "object", + "properties": { + "token_endpoint": { + "type": "string", + "description": "The token endpoint URI." + }, + "token_post_args": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra post arguments to be passed in the token endpoint request." + }, + "grant_type": { + "type": "string", + "enum": [ + "client_credentials", + "password" + ], + "description": "The OAuth grant type to be used.", + "default": "client_credentials" + }, + "client_id": { + "type": "string", + "description": "The client ID for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of scopes to request from the IdP when obtaining a new token.", + "default": [ + "openid" + ] + }, + "token_headers": { + "type": "object", + "additionalProperties": { + "type": "string", + "x-referenceable": true + }, + "description": "Extra headers to be passed in the token endpoint request." + }, + "client_secret": { + "type": "string", + "description": "The client secret for the application registration in the IdP.", + "x-referenceable": true, + "x-encrypted": true + }, + "username": { + "type": "string", + "description": "The username to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "password": { + "type": "string", + "description": "The password to use if `config.oauth.grant_type` is set to `password`.", + "x-referenceable": true, + "x-encrypted": true + }, + "audience": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of audiences passed to the IdP when obtaining a new token.", + "default": [] + } + }, + "required": [ + "token_endpoint" + ] + } + }, + "required": [ + "oauth" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "consumer_group": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified consumer group has been authenticated. (Note that some plugins can not be restricted to consumers groups this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer Groups" + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + }, + "required": [ + "config" + ], + "x-supported-partials": [ + { + "name": "redis-ee", + "paths": [ + "config.cache.redis" + ] + } + ] +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/UpstreamTimeout.json b/app/_schemas/ai-gateway/policies/UpstreamTimeout.json new file mode 100644 index 00000000000..8a76f19f6c9 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/UpstreamTimeout.json @@ -0,0 +1,76 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The timeout in milliseconds between two successive write operations for transmitting a request to the upstream server. Must be an integer between 1 and 2^31-2." + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The timeout in milliseconds for establishing a connection to the upstream server. Must be an integer between 1 and 2^31-2." + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "The timeout in milliseconds between two successive read operations for transmitting a request to the upstream server. Must be an integer between 1 and 2^31-2." + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/VaultAuth.json b/app/_schemas/ai-gateway/policies/VaultAuth.json new file mode 100644 index 00000000000..da0262bd302 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/VaultAuth.json @@ -0,0 +1,97 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "Custom type for representing a foreign key with a null value allowed.", + "x-foreign": true + }, + "config": { + "type": "object", + "properties": { + "secret_token_name": { + "type": "string", + "description": "Describes an array of comma-separated parameter names where the plugin looks for a secret token. The client must send the secret in one of those key names, and the plugin will try to read the credential from a header or the querystring parameter with the same name. The key names can only contain [a-z], [A-Z], [0-9], [_], and [-].", + "default": "secret_token" + }, + "vault": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "description": "A reference to an existing `vault` object within the database. `vault` entities define the connection and authentication parameters used to connect to a Vault HTTP(S) API.", + "x-foreign": true + }, + "hide_credentials": { + "type": "boolean", + "description": "An optional boolean value telling the plugin to show or hide the credential from the upstream service. If `true`, the plugin will strip the credential from the request (i.e. the header or querystring containing the key) before proxying it.", + "default": true + }, + "anonymous": { + "type": "string", + "description": "An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure `4xx`. Note that this value must refer to the consumer `id` or `username` attribute, and **not** its `custom_id`." + }, + "tokens_in_body": { + "type": "boolean", + "description": "If enabled, the plugin will read the request body (if said request has one and its MIME type is supported) and try to find the key in it. Supported MIME types are `application/www-form-urlencoded`, `application/json`, and `multipart/form-data`.", + "default": false + }, + "run_on_preflight": { + "type": "boolean", + "description": "A boolean value that indicates whether the plugin should run (and try to authenticate) on `OPTIONS` preflight requests. If set to `false`, then `OPTIONS` requests will always be allowed.", + "default": true + }, + "access_token_name": { + "type": "string", + "description": "Describes an array of comma-separated parameter names where the plugin looks for an access token. The client must send the access token in one of those key names, and the plugin will try to read the credential from a header or the querystring parameter with the same name. The key names can only contain [a-z], [A-Z], [0-9], [_], and [-].", + "default": "access_token" + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/WebsocketSizeLimit.json b/app/_schemas/ai-gateway/policies/WebsocketSizeLimit.json new file mode 100644 index 00000000000..33759c27fc7 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/WebsocketSizeLimit.json @@ -0,0 +1,64 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "ws", + "wss" + ] + }, + "config": { + "type": "object", + "properties": { + "client_max_payload": { + "type": "integer", + "maximum": 33554432, + "minimum": 1 + }, + "upstream_max_payload": { + "type": "integer", + "maximum": 33554432, + "minimum": 1 + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/WebsocketValidator.json b/app/_schemas/ai-gateway/policies/WebsocketValidator.json new file mode 100644 index 00000000000..6a3c8eca835 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/WebsocketValidator.json @@ -0,0 +1,144 @@ +{ + "properties": { + "config": { + "type": "object", + "properties": { + "client": { + "type": "object", + "properties": { + "text": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "draft4" + ], + "description": "The corresponding validation library for `config.upstream.binary.schema`. Currently, only `draft4` is supported." + }, + "schema": { + "type": "string", + "description": "Schema used to validate upstream-originated binary frames. The semantics of this field depend on the validation type set by `config.upstream.binary.type`." + } + }, + "required": [ + "schema", + "type" + ] + }, + "binary": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "draft4" + ], + "description": "The corresponding validation library for `config.upstream.binary.schema`. Currently, only `draft4` is supported." + }, + "schema": { + "type": "string", + "description": "Schema used to validate upstream-originated binary frames. The semantics of this field depend on the validation type set by `config.upstream.binary.type`." + } + }, + "required": [ + "schema", + "type" + ] + } + } + }, + "upstream": { + "type": "object", + "properties": { + "text": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "draft4" + ], + "description": "The corresponding validation library for `config.upstream.binary.schema`. Currently, only `draft4` is supported." + }, + "schema": { + "type": "string", + "description": "Schema used to validate upstream-originated binary frames. The semantics of this field depend on the validation type set by `config.upstream.binary.type`." + } + }, + "required": [ + "schema", + "type" + ] + }, + "binary": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "draft4" + ], + "description": "The corresponding validation library for `config.upstream.binary.schema`. Currently, only `draft4` is supported." + }, + "schema": { + "type": "string", + "description": "Schema used to validate upstream-originated binary frames. The semantics of this field depend on the validation type set by `config.upstream.binary.type`." + } + }, + "required": [ + "schema", + "type" + ] + } + } + } + } + }, + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ws", + "wss" + ] + }, + "description": "A list of the request protocols that will trigger this plugin. The default value, as well as the possible values allowed on this field, may change depending on the plugin type. For example, plugins that only work in stream mode will only support tcp and tls.", + "default": [ + "ws", + "wss" + ] + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/XmlThreatProtection.json b/app/_schemas/ai-gateway/policies/XmlThreatProtection.json new file mode 100644 index 00000000000..ac7dbfeca62 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/XmlThreatProtection.json @@ -0,0 +1,183 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "description": "A set of strings representing HTTP protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "bla_max_amplification": { + "type": "number", + "minimum": 1, + "description": "Sets the maximum allowed amplification. This protects against the Billion Laughs Attack.", + "default": 100 + }, + "max_attributes": { + "type": "integer", + "description": "Maximum number of attributes allowed on a tag, including default ones. Note: If namespace-aware parsing is disabled, then the namespaces definitions are counted as attributes.", + "default": 100 + }, + "comment": { + "type": "integer", + "description": "Maximum size of comments.", + "default": 1024 + }, + "prefix": { + "type": "integer", + "description": "Maximum size of the prefix. This applies to tags and attributes. This value is required if parsing is namespace-aware.", + "default": 1024 + }, + "bla_threshold": { + "type": "integer", + "minimum": 1024, + "description": "Sets the threshold after which the protection starts. This protects against the Billion Laughs Attack.", + "default": 8388608 + }, + "allow_dtd": { + "type": "boolean", + "description": "Indicates whether an XML Document Type Definition (DTD) section is allowed.", + "default": false + }, + "max_namespaces": { + "type": "integer", + "description": "Maximum number of namespaces defined on a tag. This value is required if parsing is namespace-aware.", + "default": 20 + }, + "buffer": { + "type": "integer", + "description": "Maximum size of the unparsed buffer (see below).", + "default": 1048576 + }, + "attribute": { + "type": "integer", + "description": "Maximum size of the attribute value.", + "default": 1048576 + }, + "pitarget": { + "type": "integer", + "description": "Maximum size of processing instruction targets.", + "default": 1024 + }, + "entityname": { + "type": "integer", + "description": "Maximum size of entity names in EntityDecl.", + "default": 1024 + }, + "entity": { + "type": "integer", + "description": "Maximum size of entity values in EntityDecl.", + "default": 1024 + }, + "allowed_content_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Content-Type values with payloads that are allowed, but aren't validated.", + "default": [] + }, + "namespace_aware": { + "type": "boolean", + "description": "If not parsing namespace aware, all prefixes and namespace attributes will be counted as regular attributes and element names, and validated as such.", + "default": true + }, + "text": { + "type": "integer", + "description": "Maximum text inside tags (counted over all adjacent text/CDATA elements combined).", + "default": 1048576 + }, + "pidata": { + "type": "integer", + "description": "Maximum size of processing instruction data.", + "default": 1024 + }, + "entityproperty": { + "type": "integer", + "description": "Maximum size of systemId, publicId, or notationName in EntityDecl.", + "default": 1024 + }, + "namespaceuri": { + "type": "integer", + "description": "Maximum size of the namespace URI. This value is required if parsing is namespace-aware.", + "default": 1024 + }, + "checked_content_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Content-Type values with payloads that must be validated.", + "default": [ + "application/xml" + ] + }, + "max_depth": { + "type": "integer", + "description": "Maximum depth of tags. Child elements such as Text or Comments are not counted as another level.", + "default": 50 + }, + "max_children": { + "type": "integer", + "description": "Maximum number of children allowed (Element, Text, Comment, ProcessingInstruction, CDATASection). Note: Adjacent text and CDATA sections are counted as one. For example, text-cdata-text-cdata is one child.", + "default": 100 + }, + "document": { + "type": "integer", + "description": "Maximum size of the entire document.", + "default": 10485760 + }, + "localname": { + "type": "integer", + "description": "Maximum size of the localname. This applies to tags and attributes.", + "default": 1024 + } + } + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + } + } +} \ No newline at end of file diff --git a/app/_schemas/ai-gateway/policies/Zipkin.json b/app/_schemas/ai-gateway/policies/Zipkin.json new file mode 100644 index 00000000000..675498bc290 --- /dev/null +++ b/app/_schemas/ai-gateway/policies/Zipkin.json @@ -0,0 +1,324 @@ +{ + "properties": { + "protocols": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "tcp", + "tls", + "tls_passthrough", + "udp", + "ws", + "wss" + ], + "description": "A string representing a protocol, such as HTTP or HTTPS." + }, + "description": "A set of strings representing protocols.", + "default": [ + "grpc", + "grpcs", + "http", + "https" + ] + }, + "config": { + "type": "object", + "properties": { + "http_endpoint": { + "type": "string", + "description": "A string representing a URL, such as https://example.com/path/to/resource?q=search." + }, + "traceid_byte_count": { + "type": "integer", + "enum": [ + 8, + 16 + ], + "description": "The length in bytes of each request's Trace ID.", + "default": 16 + }, + "header_type": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "ignore", + "instana", + "jaeger", + "ot", + "preserve", + "w3c" + ], + "description": "All HTTP requests going through the plugin are tagged with a tracing HTTP request. This property codifies what kind of tracing header the plugin expects on incoming requests", + "default": "preserve" + }, + "queue": { + "type": "object", + "properties": { + "concurrency_limit": { + "type": "integer", + "enum": [ + -1, + 1 + ], + "description": "The number of of queue delivery timers. -1 indicates unlimited.", + "default": 1 + }, + "max_batch_size": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be processed at a time.", + "default": 1 + }, + "max_coalescing_delay": { + "type": "number", + "maximum": 3600, + "minimum": 0, + "description": "Maximum number of (fractional) seconds to elapse after the first entry was queued before the queue starts calling the handler.", + "default": 1 + }, + "max_entries": { + "type": "integer", + "maximum": 1000000, + "minimum": 1, + "description": "Maximum number of entries that can be waiting on the queue.", + "default": 10000 + }, + "max_bytes": { + "type": "integer", + "description": "Maximum number of bytes that can be waiting on a queue, requires string content." + }, + "max_retry_time": { + "type": "number", + "description": "Time in seconds before the queue gives up calling a failed handler for a batch.", + "default": 60 + }, + "initial_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Time in seconds before the initial retry is made for a failing batch.", + "default": 0.01 + }, + "max_retry_delay": { + "type": "number", + "maximum": 1000000, + "minimum": 0.001, + "description": "Maximum time in seconds between retries, caps exponential backoff.", + "default": 60 + } + } + }, + "propagation": { + "type": "object", + "properties": { + "clear": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Header names to clear after context extraction. This allows to extract the context from a certain header and then remove it from the request, useful when extraction and injection are performed on different header formats and the original header should not be sent to the upstream. If left empty, no headers are cleared." + }, + "inject": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "preserve", + "w3c" + ] + }, + "description": "Header formats used to inject tracing context. The value `preserve` will use the same header format as the incoming request. If multiple values are specified, all of them will be used during injection. If left empty, Kong will not inject any tracing context information in outgoing requests." + }, + "default_format": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "w3c" + ], + "description": "The default header format to use when extractors did not match any format in the incoming headers and `inject` is configured with the value: `preserve`. This can happen when no tracing header was found in the request, or the incoming tracing header formats were not included in `extract`.", + "default": "b3" + }, + "extract": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "aws", + "b3", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "w3c" + ] + }, + "description": "Header formats used to extract tracing context from incoming requests. If multiple values are specified, the first one found will be used for extraction. If left empty, Kong will not extract any tracing context information from incoming requests and generate a trace with no parent and a new trace ID." + } + }, + "default": { + "default_format": "b3" + } + }, + "local_service_name": { + "type": "string", + "description": "The name of the service as displayed in Zipkin.", + "default": "kong" + }, + "http_span_name": { + "type": "string", + "enum": [ + "method", + "method_path" + ], + "description": "Specify whether to include the HTTP path in the span name.", + "default": "method" + }, + "send_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 5000 + }, + "read_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 5000 + }, + "http_response_header_for_traceid": { + "type": "string" + }, + "phase_duration_flavor": { + "type": "string", + "enum": [ + "annotations", + "tags" + ], + "description": "Specify whether to include the duration of each phase as an annotation or a tag.", + "default": "annotations" + }, + "include_credential": { + "type": "boolean", + "description": "Specify whether the credential of the currently authenticated consumer should be included in metadata sent to the Zipkin server.", + "default": true + }, + "default_header_type": { + "type": "string", + "enum": [ + "aws", + "b3", + "b3-single", + "datadog", + "gcp", + "instana", + "jaeger", + "ot", + "w3c" + ], + "description": "Allows specifying the type of header to be added to requests with no pre-existing tracing headers and when `config.header_type` is set to `\"preserve\"`. When `header_type` is set to any other value, `default_header_type` is ignored.", + "default": "b3" + }, + "connect_timeout": { + "type": "integer", + "maximum": 2147483646, + "minimum": 0, + "description": "An integer representing a timeout in milliseconds. Must be between 0 and 2^31-2.", + "default": 2000 + }, + "sample_ratio": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "How often to sample requests that do not contain trace IDs. Set to `0` to turn sampling off, or to `1` to sample **all** requests. ", + "default": 0.001 + }, + "default_service_name": { + "type": "string", + "description": "Set a default service name to override `unknown-service-name` in the Zipkin spans." + }, + "tags_header": { + "type": "string", + "description": "The Zipkin plugin will add extra headers to the tags associated with any HTTP requests that come with a header named as configured by this property.", + "default": "Zipkin-Tags" + }, + "static_tags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ] + }, + "description": "The tags specified on this property will be added to the generated request traces." + } + } + }, + "consumer": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will activate only for requests where the specified has been authenticated. (Note that some plugins can not be restricted to consumers this way.). Leave unset for the plugin to activate regardless of the authenticated Consumer." + }, + "route": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via the specified route. Leave unset for the plugin to activate regardless of the route being used." + }, + "service": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false, + "description": "If set, the plugin will only activate when receiving requests via one of the routes belonging to the specified Service. Leave unset for the plugin to activate regardless of the Service being matched." + } + } +} \ No newline at end of file diff --git a/app/ai-gateway/ai-audit-log-reference.md b/app/ai-gateway/ai-audit-log-reference.md index bf9a084c71f..d8dd7c52a99 100644 --- a/app/ai-gateway/ai-audit-log-reference.md +++ b/app/ai-gateway/ai-audit-log-reference.md @@ -5,45 +5,44 @@ layout: reference products: - ai-gateway - - gateway tags: - ai - logging min_version: - gateway: '3.6' + ai-gateway: '2.0' breadcrumbs: - /ai-gateway/ -description: "{{site.ai_gateway}} provides a standardized logging format for AI plugins, enabling the emission of analytics events and facilitating the aggregation of AI usage analytics across various providers." +description: "{{site.ai_gateway}} provides a standardized logging format for AI Policies, enabling the emission of analytics events and facilitating the aggregation of AI usage analytics across various providers." related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai - - text: "{{site.base_gateway}} logs" - url: /gateway/logs/ + - text: "{{site.ai_gateway}} logs" + url: /ai-gateway/ai-logs/ works_on: - - on-prem - konnect --- -{{site.ai_gateway}} emits structured analytics logs for [AI plugins](/plugins/?category=ai) through the standard [{{site.base_gateway}} logging infrastructure](/gateway/logs/). This means AI-specific logs are written to [the same locations](/gateway/logs/#where-are-kong-gateway-logs-located) as other Kong logs, such as `/usr/local/kong/logs/error.log`, or to Docker container logs if you're running in a containerized environment. +{{site.ai_gateway}} emits structured analytics logs for [AI Policies](/ai-gateway/policies/) following the same patterns as {{site.base_gateway}}. This means {{site.ai_gateway}} logs are written to [the same locations](/ai-gateway/ai-logs/#where-are-ai-gateway-logs-located) as other Kong logs, such as `/usr/local/kong/logs/error.log`, or to Docker container logs if you're running in a containerized environment. -Like other Kong logs, {{site.ai_gateway}} logs are subject to the [global log level](/gateway/logs/#configure-log-levels) configured via the [`kong.conf`](/gateway/configuration/) file or the Admin API. You can control log verbosity by adjusting the `log_level` setting (for example, `info`, `notice`, `warn`, `error`, `crit`) to determine which log entries are captured. +You can set the [global log level](/ai-gateway/ai-logs/#configure-log-levels) for {{site.ai_gateway}} via the [`kong.conf`](/gateway/configuration/) file or the Admin API. You can control log verbosity by adjusting the `log_level` setting (for example, `info`, `notice`, `warn`, `error`, `crit`) to determine which log entries are captured. -You can also use [logging plugins](/plugins/?category=logging) to route these logs to external systems, such as file systems, log aggregators, or monitoring tools. +When operating {{site.ai_gateway}} alongside {{site.base_gateway}}, logs are stored separately in each product's run time environment. + +You can also use [logging Policies](/ai-gateway/policies/) to route these logs to external systems, such as file systems, log aggregators, or monitoring tools. ## Log details -Each AI plugin returns a set of tokens. Log entries include the following details: +Each {{site.ai_gateway}} policy returns a set of tokens. Log entries include the following details: +### Core logs -### AI Proxy core logs +{{site.ai_gateway}} logs capture detailed information about the request and response payloads, token usage, model details, latency, and cost metrics. They provide a comprehensive view of each AI interaction. -The [AI Proxy](/plugins/ai-proxy/) and [AI Proxy Advanced](/plugins/ai-proxy-advanced/) plugins act as the main gateway for forwarding requests to AI providers. Logs here capture detailed information about the request and response payloads, token usage, model details, latency, and cost metrics. They provide a comprehensive view of each AI interaction. +The core proxy functionality is provided by the [AI Proxy](/plugins/ai-proxy/) and [AI Proxy Advanced](/plugins/ai-proxy-advanced/) which is reflected in the property names. {:.warning} > Logs and metrics for cost and token usage via the [OpenAI Files API](https://developers.openai.com/api/reference/resources/files/methods/list) are not currently supported. @@ -65,40 +64,40 @@ rows: Used for text-based requests (chat, completions, embeddings). - property: "`ai.proxy.usage.prompt_tokens_details`" description: | - {% new_in 3.11 %} A breakdown of prompt tokens (`cached_tokens`, `audio_tokens`). + A breakdown of prompt tokens (`cached_tokens`, `audio_tokens`). - property: "`ai.proxy.usage.completion_tokens`" description: | The number of tokens used for completion. Used for text-based responses (chat, completions). - property: "`ai.proxy.usage.completion_tokens_details`" description: | - {% new_in 3.11 %} A breakdown of completion tokens (`rejected_prediction_tokens`, `reasoning_tokens`, `accepted_prediction_tokens`, `audio_tokens`). + A breakdown of completion tokens (`rejected_prediction_tokens`, `reasoning_tokens`, `accepted_prediction_tokens`, `audio_tokens`). - property: "`ai.proxy.usage.total_tokens`" description: | The total number of tokens used (input + output). Includes prompt/completion tokens for text, and input/output tokens for non-text modalities. - property: "`ai.proxy.usage.input_tokens`" description: | - {% new_in 3.11 %} The total number of input tokens (text + image + audio). + The total number of input tokens (text + image + audio). Used for non-text requests (e.g., image or audio generation). - property: "`ai.proxy.usage.input_tokens_details`" description: | - {% new_in 3.11 %} A breakdown of input tokens by modality (`text_tokens`, `image_tokens`, `audio_tokens_count`). + A breakdown of input tokens by modality (`text_tokens`, `image_tokens`, `audio_tokens_count`). - property: "`ai.proxy.usage.output_tokens`" description: | - {% new_in 3.11 %} The total number of output tokens (text + audio). + The total number of output tokens (text + audio). Used for non-text responses (e.g., image or audio generation). - property: "`ai.proxy.usage.output_tokens_details`" description: | - {% new_in 3.11 %} A breakdown of output tokens by modality (`text_tokens`, `audio_tokens`). + A breakdown of output tokens by modality (`text_tokens`, `audio_tokens`). - property: "`ai.proxy.usage.cost`" description: The total cost of the request. - property: "`ai.proxy.usage.time_per_token`" description: | - {% new_in 3.8 %} Average time to generate an output token (ms). + Average time to generate an output token (ms). - property: "`ai.proxy.usage.time_to_first_token`" description: | - {% new_in 3.12 %} Time to receive the first output token (ms). + Time to receive the first output token (ms). - property: "`ai.proxy.meta.request_model`" description: The model used for the AI request. - property: "`ai.proxy.meta.response_model`" @@ -106,18 +105,18 @@ rows: - property: "`ai.proxy.meta.provider_name`" description: The name of the AI service provider. - property: "`ai.proxy.meta.plugin_id`" - description: Unique identifier of the plugin instance. + description: Unique identifier of the Policy instance. - property: "`ai.proxy.meta.llm_latency`" description: | - {% new_in 3.8 %} Time taken by the LLM provider to generate the full response (ms). + Time taken by the LLM provider to generate the full response (ms). - property: "`ai.proxy.meta.request_mode`" description: | - {% new_in 3.12 %} The request mode. Can be `oneshot`, `stream`, or `realtime`. + The request mode. Can be `oneshot`, `stream`, or `realtime`. {% endtable %} -### AI AWS Guardrails logs {% new_in 3.11 %} +### AI AWS Guardrails logs -If you're using the [AI AWS Guardrails plugin](/plugins/ai-aws-guardrails/), {{site.ai_gateway}} logs include fields under the `ai.proxy.aws-guardrails` object. These fields capture processing latency, the guardrails configuration applied, block reasons, and masking behavior. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI AWS Guardrails Policy](/ai-gateway/policies/ai-aws-guardrails/), {{site.ai_gateway}} logs include fields under the `ai.proxy.aws-guardrails` object. These fields capture processing latency, the guardrails configuration applied, block reasons, and masking behavior. {% table %} columns: @@ -134,7 +133,7 @@ rows: description: "The version of the guardrail applied. Can be a numeric version or `DRAFT`." - property: "`ai.proxy.aws-guardrails.mode`" description: | - {% new_in 3.14 %} The content guarding mode configured for the plugin. Possible values: `INPUT`, `OUTPUT`, `BOTH`. + The content guarding mode configured for the Policy. Possible values: `INPUT`, `OUTPUT`, `BOTH`. - property: "`ai.proxy.aws-guardrails.input_processing_latency`" description: The time, in milliseconds, spent processing the request through the guardrail. - property: "`ai.proxy.aws-guardrails.output_processing_latency`" @@ -149,30 +148,30 @@ rows: description: "`true` if the response content was masked rather than blocked. Only present when `config.allow_masking` is `true`." - property: "`ai.proxy.aws-guardrails.input_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the request. Empty if the request was allowed. + The name of the Policy that blocked the request. Empty if the request was allowed. - property: "`ai.proxy.aws-guardrails.output_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the response. Empty if the response was allowed. + The name of the Policy that blocked the response. Empty if the response was allowed. - property: "`ai.proxy.aws-guardrails.input_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.aws-guardrails.output_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.aws-guardrails.guards_triggered_count`" description: | - {% new_in 3.14 %} A counter that increments each time a block is triggered on either the input or output within a single request. + A counter that increments each time a block is triggered on either the input or output within a single request. - property: "`ai.proxy.aws-guardrails.input_faulty_prompt`" description: | - {% new_in 3.14 %} The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. - property: "`ai.proxy.aws-guardrails.output_faulty_response`" description: | - {% new_in 3.14 %} The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. {% endtable %} -### AI GCP Model Armor logs {% new_in 3.12 %} +### AI GCP Model Armor logs -If you're using the [AI GCP Model Armor plugin](/plugins/ai-gcp-model-armor/), {{site.ai_gateway}} logs include fields under the `ai.proxy.gcp-model-armor` object. These fields capture the template applied, processing latency, and reasons for blocking when content is flagged. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI GCP Model Armor Policy](/ai-gateway/policies/ai-gcp-model-armor/), {{site.ai_gateway}} logs include fields under the `ai.proxy.gcp-model-armor` object. These fields capture the template applied, processing latency, and reasons for blocking when content is flagged. {% table %} columns: @@ -193,33 +192,33 @@ rows: description: "The check type or types that caused the response to be blocked, comma-separated. Empty if the response was allowed." - property: "`ai.proxy.gcp-model-armor.mode`" description: | - {% new_in 3.14 %} The content guarding mode configured for the plugin. Possible values: `INPUT`, `OUTPUT`, `BOTH`. + The content guarding mode configured for the Policy. Possible values: `INPUT`, `OUTPUT`, `BOTH`. - property: "`ai.proxy.gcp-model-armor.input_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the request. Empty if the request was allowed. + The name of the Policy that blocked the request. Empty if the request was allowed. - property: "`ai.proxy.gcp-model-armor.output_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the response. Empty if the response was allowed. + The name of the Policy that blocked the response. Empty if the response was allowed. - property: "`ai.proxy.gcp-model-armor.input_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.gcp-model-armor.output_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.gcp-model-armor.guards_triggered_count`" description: | - {% new_in 3.14 %} A counter that increments each time a block is triggered on either the input or output within a single request. + A counter that increments each time a block is triggered on either the input or output within a single request. - property: "`ai.proxy.gcp-model-armor.input_faulty_prompt`" description: | - {% new_in 3.14 %} The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. - property: "`ai.proxy.gcp-model-armor.output_faulty_response`" description: | - {% new_in 3.14 %} The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. {% endtable %} ### AI Azure Content Safety logs -If you're using the [AI Azure Content Safety plugin](/plugins/ai-azure-content-safety/), {{site.ai_gateway}} writes to two separate log paths. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI Azure Content Safety Policy](/ai-gateway/policies/ai-azure-content-safety/), {{site.ai_gateway}} writes to two separate log paths. The first path records per-category severity data from the Azure Content Safety API. Each entry represents a category that breached its configured rejection threshold. Multiple entries can appear per request depending on which categories were configured and what was detected. @@ -236,7 +235,7 @@ rows: description: "The numeric rejection severity threshold for the category that was breached (for example, `Hate`, `Violence`). Defined by `config.categories[*].rejection_level`. Multiple entries can appear per request." {% endtable %} -The second path records plugin metadata and block reasons under the `ai.proxy.azure-content-safety` object: +The second path records Policy metadata and block reasons under the `ai.proxy.azure-content-safety` object: {% table %} columns: @@ -263,33 +262,33 @@ rows: description: The reason the response was blocked. Empty if the response was allowed. - property: "`ai.proxy.azure-content-safety.mode`" description: | - {% new_in 3.14 %} The content guarding mode configured for the plugin. Possible values: `INPUT`, `OUTPUT`, `BOTH`. + The content guarding mode configured for the Policy. Possible values: `INPUT`, `OUTPUT`, `BOTH`. - property: "`ai.proxy.azure-content-safety.input_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the request. Empty if the request was allowed. + The name of the Policy that blocked the request. Empty if the request was allowed. - property: "`ai.proxy.azure-content-safety.output_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the response. Empty if the response was allowed. + The name of the Policy that blocked the response. Empty if the response was allowed. - property: "`ai.proxy.azure-content-safety.input_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.azure-content-safety.output_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.azure-content-safety.guards_triggered_count`" description: | - {% new_in 3.14 %} A counter that increments each time a block is triggered on either the input or output within a single request. + A counter that increments each time a block is triggered on either the input or output within a single request. - property: "`ai.proxy.azure-content-safety.input_faulty_prompt`" description: | - {% new_in 3.14 %} The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. - property: "`ai.proxy.azure-content-safety.output_faulty_response`" description: | - {% new_in 3.14 %} The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. {% endtable %} -### AI Lakera Guard logs {% new_in 3.13 %} +### AI Lakera Guard logs -If you're using the [AI Lakera Guard plugin](/plugins/ai-lakera-guard/), {{site.ai_gateway}} logs include additional fields under the `ai.proxy.lakera-guard` object. These fields capture processing latency, Lakera-assigned request UUIDs, block reasons, and violation details when requests or responses are blocked. +If you create an [ AI Policy](/ai-gateway/entities/ai-policy/) using the [AI Lakera Guard Policy](/ai-gateway/policies/ai-lakera-guard/), {{site.ai_gateway}} logs include additional fields under the `ai.proxy.lakera-guard` object. These fields capture processing latency, Lakera-assigned request UUIDs, block reasons, and violation details when requests or responses are blocked. {% table %} columns: @@ -304,7 +303,7 @@ rows: description: "The Lakera project identifier used for the inspection. Defaults to `default` if no project ID is configured." - property: "`ai.proxy.lakera-guard.mode`" description: | - {% new_in 3.14 %} The content guarding mode configured for the plugin. Possible values: `INPUT`, `OUTPUT`, `BOTH`. + The content guarding mode configured for the Policy. Possible values: `INPUT`, `OUTPUT`, `BOTH`. - property: "`ai.proxy.lakera-guard.input_processing_latency`" description: The time, in milliseconds, that Lakera took to process the request. - property: "`ai.proxy.lakera-guard.output_processing_latency`" @@ -323,32 +322,32 @@ rows: description: "An array of violation objects present when Lakera blocks a response. The structure matches `input_block_detail`." - property: "`ai.proxy.lakera-guard.input_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the request. Empty if the request was allowed. + The name of the Policy that blocked the request. Empty if the request was allowed. - property: "`ai.proxy.lakera-guard.output_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the response. Empty if the response was allowed. + The name of the Policy that blocked the response. Empty if the response was allowed. - property: "`ai.proxy.lakera-guard.input_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.lakera-guard.output_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.proxy.lakera-guard.guards_triggered_count`" description: | - {% new_in 3.14 %} A counter that increments each time a block is triggered on either the input or output within a single request. + A counter that increments each time a block is triggered on either the input or output within a single request. - property: "`ai.proxy.lakera-guard.input_faulty_prompt`" description: | - {% new_in 3.14 %} The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw request prompt that was blocked. Only present when `config.log_blocked_content` is `true`. - property: "`ai.proxy.lakera-guard.output_faulty_response`" description: | - {% new_in 3.14 %} The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. + The raw response that was blocked. Only present when `config.log_blocked_content` is `true`. {% endtable %} -### AI Custom Guardrail logs {% new_in 3.14 %} +### AI Custom Guardrail logs -If you're using the [AI Custom Guardrail plugin](/plugins/ai-custom-guardrail/), {{site.ai_gateway}} logs include additional fields under the `custom-guardrail` object. These fields record guardrail processing latency, block reasons, and the source and consumer identity associated with any triggered guards. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI Custom Guardrail Policy](/ai-gateway/policies/ai-custom-guardrail/), {{site.ai_gateway}} logs include additional fields under the `custom-guardrail` object. These fields record guardrail processing latency, block reasons, and the source and consumer identity associated with any triggered guards. -The following fields appear in structured AI logs when the AI Custom Guardrail plugin is enabled: +The following fields appear in structured AI logs when the AI Custom Guardrail Policy is enabled: {% table %} columns: @@ -381,12 +380,12 @@ rows: {% endtable %} {:.info} -> The plugin also allows you to define [custom metrics](/plugins/ai-custom-guardrail/#metrics) based on Lua expressions. +> The Policy also allows you to define [custom metrics](/ai-gateway/policies/ai-custom-guardrail/#metrics) based on Lua expressions. -### AI PII Sanitizer logs {% new_in 3.10 %} +### AI PII Sanitizer logs -If you're using the [AI PII Sanitizer plugin](/plugins/ai-sanitizer/), {{site.ai_gateway}} logs include additional fields that provide insight into the detection and redaction of personally identifiable information (PII). These fields track the number of entities identified and sanitized, the time taken to process the payload, and detailed metadata about each sanitized item, including the original value, redacted value, and detected entity type. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI PII Sanitizer Policy](/ai-gateway/policies/ai-sanitizer/), {{site.ai_gateway}} logs include additional fields that provide insight into the detection and redaction of personally identifiable information (PII). These fields track the number of entities identified and sanitized, the time taken to process the payload, and detailed metadata about each sanitized item, including the original value, redacted value, and detected entity type. {% table %} columns: @@ -405,24 +404,24 @@ rows: description: A list of sanitized PII entities, each including the original text, redacted text, and the entity type. - property: "`ai.sanitizer.input_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the request. Empty if the request was allowed. + The name of the Policy that blocked the request. Empty if the request was allowed. - property: "`ai.sanitizer.output_block_source`" description: | - {% new_in 3.14 %} The name of the plugin that blocked the response. Empty if the response was allowed. + The name of the Policy that blocked the response. Empty if the response was allowed. - property: "`ai.sanitizer.input_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose request was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.sanitizer.output_block_consumer_id`" description: | - {% new_in 3.14 %} The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. + The ID of the consumer whose response was blocked, or `unknown` if no consumer identity was resolved. - property: "`ai.sanitizer.guards_triggered_count`" description: | - {% new_in 3.14 %} A counter that increments each time a block is triggered on either the input or output within a single request. + A counter that increments each time a block is triggered on either the input or output within a single request. {% endtable %} -### AI Prompt Compressor logs {% new_in 3.11 %} +### AI Prompt Compressor logs -When the [AI Prompt Compressor plugin](/plugins/ai-prompt-compressor/) is enabled, additional logs record token counts before and after compression, compression ratios, and metadata about the compression method and model used. +When the [AI Prompt Compressor Policy](/ai-gateway/policies/ai-prompt-compressor/) is enabled, additional logs record token counts before and after compression, compression ratios, and metadata about the compression method and model used. {% table %} columns: @@ -449,9 +448,9 @@ rows: description: A summary or message describing the result of compression. {% endtable %} -### AI RAG Injector logs {% new_in 3.10 %} +### AI RAG Injector logs -If you're using the [AI RAG Injector plugin](/plugins/ai-rag-injector/), {{site.ai_gateway}} logs include additional fields that provide detailed information about the retrieval-augmented generation process. These fields track the vector database used, whether relevant context was injected into the prompt, the latency of data fetching, and embedding metadata such as tokens used and the embedding provider and model used. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI RAG Injector Policy](/ai-gateway/policies/ai-rag-injector/), {{site.ai_gateway}} logs include additional fields that provide detailed information about the retrieval-augmented generation process. These fields track the vector database used, whether relevant context was injected into the prompt, the latency of data fetching, and embedding metadata such as tokens used and the embedding provider and model used. {% table %} columns: @@ -478,9 +477,8 @@ rows: description: Model used to generate embeddings. {% endtable %} -### AI Semantic Cache logs {% new_in 3.8 %} - -If you're using the [AI Semantic Cache plugin](/plugins/ai-semantic-cache/), {{site.ai_gateway}} logs include additional fields under the cache object for each plugin entry. These fields provide insight into cache behavior, such as whether a response was served from cache, how long it took to fetch, and which embedding provider and model were used if applicable. +### AI Semantic Cache logs +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI Semantic Cache Policy](/ai-gateway/policies/ai-semantic-cache/), {{site.ai_gateway}} logs include additional fields under the cache object for each Policy entry. These fields provide insight into cache behavior, such as whether a response was served from cache, how long it took to fetch, and which embedding provider and model were used if applicable. {% table %} columns: @@ -491,7 +489,7 @@ columns: rows: - property: "`ai.proxy.cache.cache_status`" description: | - {% new_in 3.8 %} The cache status. This can be `Hit`, `Miss`, `Bypass`, or `Refresh`. + The cache status. This can be `Hit`, `Miss`, `Bypass`, or `Refresh`. - property: "`ai.proxy.cache.fetch_latency`" description: The time, in milliseconds, it took to return a cached response. - property: "`ai.proxy.cache.embeddings_provider`" @@ -506,9 +504,9 @@ rows: > **Note:** When returning a cached response, `time_per_token` and `llm_latency` are omitted. > The cache response can be returned either as a semantic cache or an exact cache. If it's returned as a semantic cache, it will include additional details such as the embeddings provider, embeddings model, and embeddings latency. -### AI LLM as Judge logs {% new_in 3.12 %} +### AI LLM as Judge logs -If you're using the [AI LLM as Judge plugin](/plugins/ai-llm-as-judge/), {{site.ai_gateway}} logs include additional fields under the `ai-llm-as-judge` object. These fields provide insight into evaluation behavior, such as which models were scored, latency, and the numeric accuracy assigned by the judge. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI LLM as Judge Policy](/ai-gateway/policies/ai-llm-as-judge/), {{site.ai_gateway}} logs include additional fields under the `ai-llm-as-judge` object. These fields provide insight into evaluation behavior, such as which models were scored, latency, and the numeric accuracy assigned by the judge. {% table %} columns: @@ -532,14 +530,14 @@ rows: {% endtable %} -### AI MCP logs {% new_in 3.12 %} +### AI MCP logs -If you're using the [AI MCP plugin](/plugins/ai-mcp-proxy/), {{site.ai_gateway}} logs include additional fields under the `ai.mcp` object. These fields provide insight into Model Context Protocol (MCP) traffic, including session IDs, JSON-RPC request/response payloads, latency, tool usage, and {% new_in 3.13 %} access control audit entries. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI MCP Policy](/plugins/ai-mcp-proxy/), {{site.ai_gateway}} logs include additional fields under the `ai.mcp` object. These fields provide insight into Model Context Protocol (MCP) traffic, including session IDs, JSON-RPC request/response payloads, latency, tool usage, and access control audit entries. {:.info} -> **Note:** Unlike other available AI plugins, the AI MCP plugin is not invoked as part of an AI request. -> Instead, it is registered and executed as a regular plugin, allowing it to capture MCP traffic independently of AI request flow. -> Do not configure the AI MCP plugin together with other `ai-*` plugins on the same service or route. +> **Note:** Unlike other available AI Policies, the AI MCP Policy is not invoked as part of an AI request. +> Instead, it is registered and executed as a regular Policy, allowing it to capture MCP traffic independently of AI request flow. +> Do not configure the AI MCP Policy together with other `ai-*` Policies on the same service or route. The MCP log structure groups traffic by **MCP session ID**, with each session containing zero or more recorded JSON-RPC requests: @@ -573,34 +571,34 @@ rows: description: The size of the JSON-RPC response body, in bytes. - property: "`ai.mcp.audit`" description: | - {% new_in 3.13 %} An array of access control audit entries. Each entry records whether access was allowed or denied for a specific MCP primitive or globally. + An array of access control audit entries. Each entry records whether access was allowed or denied for a specific MCP primitive or globally. - property: "`ai.mcp.audit[].primitive_name`" description: | - {% new_in 3.13 %} The name of the MCP primitive (for example, `list_users`). + The name of the MCP primitive (for example, `list_users`). - property: "`ai.mcp.audit[].primitive`" description: | - {% new_in 3.13 %} The type of MCP primitive (for example, `tool`, `resource`, or `prompt`). + The type of MCP primitive (for example, `tool`, `resource`, or `prompt`). - property: "`ai.mcp.audit[].action`" description: | - {% new_in 3.13 %} The access control decision: `allow` or `deny`. + The access control decision: `allow` or `deny`. - property: "`ai.mcp.audit[].consumer.name`" description: | - {% new_in 3.13 %} The name of the consumer making the request. + The name of the consumer making the request. - property: "`ai.mcp.audit[].consumer.id`" description: | - {% new_in 3.13 %} The UUID of the consumer. + The UUID of the consumer. - property: "`ai.mcp.audit[].consumer.identifier`" description: | - {% new_in 3.13 %} The type of consumer identifier (for example, `consumer_group`). + The type of consumer identifier (for example, `consumer_group`). - property: "`ai.mcp.audit[].scope`" description: | - {% new_in 3.13 %} The scope of the access control check. + The scope of the access control check. {% endtable %} -### AI A2A Proxy logs {% new_in 3.14 %} +### AI A2A Proxy logs -If you're using the [AI A2A Proxy plugin](/plugins/ai-a2a-proxy/), {{site.ai_gateway}} logs include additional fields under the `ai.a2a` object when [`config.logging.log_statistics`](/plugins/ai-a2a-proxy/reference/#schema--config-logging-log-statistics) is enabled. These fields provide observability into Agent-to-Agent (A2A) protocol traffic, including operation names, task lifecycle state, latency, streaming metrics, and optional request/response payloads. +If you create an [AI Policy](/ai-gateway/entities/ai-policy/) using the [AI A2A Proxy Policy](/plugins/ai-a2a-proxy/), {{site.ai_gateway}} logs include additional fields under the `ai.a2a` object when [`config.logging.log_statistics`](/plugins/ai-a2a-proxy/reference/#schema--config-logging-log-statistics) is enabled. These fields provide observability into Agent-to-Agent (A2A) protocol traffic, including operation names, task lifecycle state, latency, streaming metrics, and optional request/response payloads. {% include /plugins/ai-a2a-proxy/log-output-fields.md %} diff --git a/app/ai-gateway/ai-logs.md b/app/ai-gateway/ai-logs.md new file mode 100644 index 00000000000..7af5aa4708d --- /dev/null +++ b/app/ai-gateway/ai-logs.md @@ -0,0 +1,248 @@ +--- +title: "{{site.ai_gateway}} logs" +content_type: reference +layout: reference +breadcrumbs: + - /ai-gateway/ +products: + - ai-gateway + +tags: + - logging + - monitoring +min_version: + ai-gateway: '2.0' +description: See where {{site.ai_gateway}} logs are located, the different log levels, and how to configure logs and log levels. +search_aliases: + - logging +related_resources: + - text: "Secure {{site.ai_gateway}}" + url: /gateway/security/ + - text: "{{site.ai_gateway}} audit logs" + url: /gateway/audit-logs/ + - text: "{{site.konnect_short_name}} logs" + url: /dedicated-cloud-gateways/konnect-logs/ + - text: "{{site.konnect_short_name}} platform audit logs" + url: /konnect-platform/audit-logs/ + - text: Logging Policies + url: /ai-gateway/policies/?category=logging + - text: Add Correlation IDs to {{site.ai_gateway}} logs + url: /how-to/add-correlation-ids-to-gateway-logs/ + +works_on: + - konnect +--- + +Logging in {{site.ai_gateway}} allows you to see information, warnings, and errors about requests that are proxied by {{site.ai_gateway}}. + +The information in this reference doc helps you understand and modify {{site.ai_gateway}} logs. You can also set Policies with [logging Policies](/ai-gateway/policies/?category=logging) to extend these capabilities by logging additional information or sending logs to another application. + +## Where are {{site.ai_gateway}} logs located? + +By default, you can view {{site.ai_gateway}} logs at `/usr/local/kong/logs/error.log`. If you are running {{site.ai_gateway}} in Docker, you can also view them from your Docker container. + +## Log levels + +By default, logs are set to the recommended `notice` level. If logs are too busy, you can increase the level to something like `warn`. + + +{% table %} +columns: + - title: Level + key: level + - title: Description + key: description +rows: + - level: "`debug`" + description: "Provides debug information about the Policy’s run loop and each individual Policy or other components. This should only be used during debugging. If this is enabled for extended periods of time, it can result in excess disk space consumption." + - level: "`info` and `notice`" + description: "Provides information about normal behavior, most of which can be ignored." + - level: "`warn`" + description: "Logs any abnormal behavior that doesn't result in dropped transactions but requires further investigation." + - level: "`error`" + description: "Used for logging errors that result in a request being dropped. For example, getting a `500` error. The rate of these logs must be monitored." + - level: "`crit`" + description: "Used when {{site.ai_gateway}} is working under critical conditions, affecting several clients. `crit` is the highest severity log level." +{% endtable %} + + +## Configure log levels + +You can change log levels dynamically, without restarting {{site.ai_gateway}}, using the Admin API. Alternatively, you can configure log levels using the `log_level` parameter in the [`kong.conf` file](/gateway/configuration/), but this requires you to [restart {{site.ai_gateway}}](/how-to/restart-kong-gateway-container/). + + +{% table %} +columns: + - title: Use case + key: usecase + - title: How to configure + key: config +rows: + - usecase: "View current log level1" + config: "[`/debug/node/log-level/`](/api/gateway/admin-ee/#/operations/get-debug-node-log-level/)" + - usecase: "Modify the log level for an individual {{site.ai_gateway}} node" + config: "[`/debug/node/log-level/{logLevel}`](/api/gateway/admin-ee/#/operations/get-debug-node-log-level-log_level/)" + - usecase: "Change the log level of the {{site.ai_gateway}} cluster" + config: "[`/debug/cluster/log-level/{loglevel}`](/api/gateway/admin-ee/#/operations/update-debug-cluster-log-level/)" + - usecase: "Keep the log level of new nodes added to the cluster in sync with other nodes in the cluster" + config: | + Change the [`log_level`](/gateway/configuration/#log-level) entry in `kong.conf` to `KONG_LOG_LEVEL`, and start every new node with the `KONG_LOG_LEVEL` env variable set. + - usecase: "Change the log level of all Control Plane {{site.ai_gateway}} nodes" + config: "[`/debug/cluster/control-planes-nodes/log-level/{loglevel}`](/api/gateway/admin-ee/#/operations/create-debug-cluster-control-planes-nodes-log-level)" +{% endtable %} + + +{:.info} +> 1: You can't change the log level of the Data Plane or DB-less nodes. + + +## Find specific client requests in logs + +The `X-Kong-Request-Id` header contains a unique identifier for each client request. You can use this header to match specific requests to their corresponding error logs. + +If {{site.ai_gateway}} returns an error by calling the PDK `kong.response.error`, the request ID will also be included in the response body generated by {{site.ai_gateway}}. In addition, any generated {{site.ai_gateway}} error log contains the same request ID with the format `request_id: xxx`. This can help with debugging because you can search for the header when the debug output is too long to fit in the response header. + +This feature can be customized for upstreams and downstreams using the `headers` and `headers_upstream` configuration options in [`kong.conf`](/gateway/configuration/): + + +{% kong_config_table %} +config: + - name: headers + - name: headers_upstream +{% endkong_config_table %} + + +## Customize what {{site.ai_gateway}} logs + +You may need to customize what {{site.ai_gateway}} logs. For instance, you may want to: +* Protect private information +* Comply with GDPR or other data protection regulations +* Remove instances of a specific piece of data from your logs, such as an email address + +These changes can be made to {{site.ai_gateway}}'s Nginx template and only affect the output of the Nginx access logs. This doesn't have any effect on {{site.ai_gateway}}'s [logging Policies](/ai-gateway/policies/?category=logging). + +Let's look at an example where you want to remove any instances of an email address from your {{site.ai_gateway}} logs. The email addresses may come through in different formats, for example `/servicename/v2/verify/alice@example.com` or `/v3/verify?alice@example.com`. To keep all of these formats from being added to the logs, you need to use a custom Nginx template. + +Make a copy of {{site.ai_gateway}}'s Nginx template, then edit it to add or remove the data you need. The following template shows an example configuration for removing email addresses from logs: + +```nginx +# --------------------- +# custom_nginx.template +# --------------------- + +worker_processes ${{NGINX_WORKER_PROCESSES}}; # can be set by kong.conf +daemon ${{NGINX_DAEMON}}; # can be set by kong.conf + +pid pids/nginx.pid; # this setting is mandatory +error_log stderr ${{LOG_LEVEL}}; # can be set by kong.conf + + + +events { + use epoll; # custom setting + multi_accept on; +} + +http { + + + map $request_uri $keeplog { + ~.+\@.+\..+ 0; + ~/v1/invitation/ 0; + ~/reset/v1/customer/password/token 0; + ~/v2/verify 0; + + default 1; + } + log_format show_everything '$remote_addr - $remote_user [$time_local] ' + '$request_uri $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; + + include 'nginx-kong.conf'; +} +``` + +For this example, we're using the following: + +* `map $request_uri $keeplog`: Maps a new variable called `keeplog`, which is dependent on values appearing in the `$request_uri`. Each line in the example starts with a `~` because this is what tells Nginx to use a regex when evaluating the line. This example looks for the following: + - The first line uses a regex to look for any email address in the `x@y.z` format + - The second line looks for any part of the URI that contains `/servicename/v2/verify` + - The third line looks at any part of the URI that contains `/v3/verify` + + Because all of these patterns have a value of something other than `0`, if a request has any of those elements, it will not be added to the log. +* `log_format`: Sets the log format for what {{site.ai_gateway}} keeps in the logs. The contents of the log can be customized for your needs. For the purpose of this example, you can assign the new logs with the name `show_everything` and set everything to the {{site.ai_gateway}} default standards. To see the full list of options, refer to the [Nginx core module variables reference](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables). + +Once you've adjusted the Nginx template for your environment, you need to tell {{site.ai_gateway}} to use the newly created log, `show_everything`. + +To do this, alter the {{site.ai_gateway}} variable `proxy_access_log` by either editing `etc/kong/kong.conf` or using the environmental variable `KONG_PROXY_ACCESS_LOG` adjust the default location: + +```sh +proxy_access_log=logs/access.log show_everything if=$keeplog +``` + +Restart {{site.ai_gateway}} to apply changes with the `kong restart` command. + +Now, any request made with an email address in it will no longer be logged. + +## {{site.ai_gateway}} logs + +{{site.ai_gateway}} collects logs for the [{{site.ai_gateway}} Policies](/ai-gateway/policies/). This allows you to aggregate AI usage analytics across various providers. + +Each log entry includes the following details: + + +{% table %} +columns: + - title: Property + key: property + - title: Description + key: description +rows: + - property: "`ai.$POLICY_NAME.payload.request`" + description: The request payload. + - property: "`ai.$POLICY_NAME.payload.response`" + description: The response payload. + - property: "`ai.$POLICY_NAME.usage.prompt_token`" + description: The number of tokens used for prompting. + - property: "`ai.$POLICY_NAME.usage.completion_token`" + description: The number of tokens used for completion. + - property: "`ai.$POLICY_NAME.usage.total_tokens`" + description: The total number of tokens used. + - property: "`ai.$POLICY_NAME.usage.cost`" + description: The total cost of the request (input and output cost). + - property: "`ai.$POLICY_NAME.usage.time_per_token`" + description: | + The average time to generate an output token, in milliseconds. + - property: "`ai.$POLICY_NAME.meta.request_model`" + description: The model used for the AI request. + - property: "`ai.$POLICY_NAME.meta.provider_name`" + description: The name of the AI service provider. + - property: "`ai.$POLICY_NAME.meta.response_model`" + description: The model used for the AI response. + - property: "`ai.$POLICY_NAME.meta.plugin_id`" + description: The unique identifier of the Policy. + - property: "`ai.$POLICY_NAME.meta.llm_latency`" + description: | + The time, in milliseconds, it took the LLM provider to generate the full response. + - property: "`ai.$POLICY_NAME.cache.cache_status`" + description: | + The cache status. This can be `Hit`, `Miss`, `Bypass` or `Refresh`. + - property: "`ai.$POLICY_NAME.cache.fetch_latency`" + description: | + The time, in milliseconds, it took to return a cache response. + - property: "`ai.$POLICY_NAME.cache.embeddings_provider`" + description: | + For semantic caching, the provider used to generate the embeddings. + - property: "`ai.$POLICY_NAME.cache.embeddings_model`" + description: | + For semantic caching, the model used to generate the embeddings. + - property: "`ai.$POLICY_NAME.cache.embeddings_latency`" + description: | + For semantic caching, the time taken to generate the embeddings. +{% endtable %} + + + diff --git a/app/ai-gateway/ai-otel-metrics.md b/app/ai-gateway/ai-otel-metrics.md index 091c997b7fa..2258359b72d 100644 --- a/app/ai-gateway/ai-otel-metrics.md +++ b/app/ai-gateway/ai-otel-metrics.md @@ -5,7 +5,6 @@ layout: reference products: - ai-gateway - - gateway breadcrumbs: - /ai-gateway/ @@ -18,11 +17,9 @@ tags: plugins: - opentelemetry - - ai-proxy - - ai-proxy-advanced min_version: - gateway: '3.14' + ai-gateway: '2.0' tech_preview: true toc_depth: 2 @@ -34,29 +31,22 @@ related_resources: url: /ai-gateway/llm-open-telemetry/ - text: "Monitor AI LLM metrics (Prometheus)" url: /ai-gateway/monitor-ai-llm-metrics/ - - text: "Proxy A2A agents through {{site.ai_gateway}}" - url: /how-to/proxy-a2a-agents/ - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai - - text: OpenTelemetry plugin - url: /plugins/opentelemetry/ + - text: OpenTelemetry Policy + url: /ai-gateway/policies/opentelemetry/ - text: Full OpenTelemetry metrics reference url: /gateway/otel-metrics/ - text: "{{site.base_gateway}} tracing guide" url: /gateway/tracing/ works_on: - - on-prem - konnect --- -{% new_in 3.14 %} {{site.ai_gateway}} can export OpenTelemetry (OTLP) metrics for generative AI, MCP, and A2A traffic through the [OpenTelemetry plugin](/plugins/opentelemetry/). These metrics are aggregated time-series data points (counters, histograms) pushed to a configured OTLP metrics endpoint on a regular interval. They are separate from the per-request [Gen AI span attributes](/ai-gateway/llm-open-telemetry/) emitted on traces. +{{site.ai_gateway}} can export OpenTelemetry (OTLP) metrics for generative AI, MCP, and A2A traffic through an [OpenTelemetry AI Policy](/ai-gateway/policies/opentelemetry/). These metrics are aggregated time-series data points (counters, histograms) pushed to a configured OTLP metrics endpoint on a regular interval. They are separate from the per-request [Gen AI span attributes](/ai-gateway/llm-open-telemetry/) emitted on traces. -For a step-by-step setup using an OpenTelemetry Collector, see [Collect metrics, logs, and traces with the OpenTelemetry plugin](/how-to/collect-metrics-logs-and-traces-with-opentelemetry/). To visualize Gen AI traces in Jaeger, see [Set up Jaeger with Gen AI OpenTelemetry](/how-to/set-up-jaeger-with-gen-ai-otel/). - -Use these metrics to: +You can use these metrics to: * Track LLM request latency and upstream provider processing time * Monitor token consumption across providers, models, and consumers @@ -67,409 +57,65 @@ Use these metrics to: ## Prerequisites -To collect AI OTel metrics, enable the following settings: +To collect AI OTLP metrics, enable the following settings: {% table %} columns: - title: Setting key: setting - - title: Plugin - key: plugin + - title: Policy + key: policy - title: Required for key: required_for rows: - setting: "`config.metrics.enable_ai_metrics`: `true`" - plugin: "[OpenTelemetry](/plugins/opentelemetry/reference/)" + policy: "[OpenTelemetry](/ai-gateway/policies/opentelemetry/reference/)" required_for: "All AI metrics" - setting: "`config.metrics.endpoint`" - plugin: "[OpenTelemetry](/plugins/opentelemetry/reference/)" + policy: "[OpenTelemetry](/ai-gateway/policies/opentelemetry/reference/)" required_for: "All AI metrics (set to a valid OTLP-compatible metrics endpoint)" - setting: "`config.logging.log_statistics`: `true`" - plugin: "[AI Proxy](/plugins/ai-proxy/reference/) or [AI Proxy Advanced](/plugins/ai-proxy-advanced/reference/)" - required_for: "[Gen AI metrics](#gen-ai-metrics-otel-semantic-conventions)" + policy: "[AI Proxy](/plugins/ai-proxy/reference/) or [AI Proxy Advanced](/plugins/ai-proxy-advanced/reference/)" + required_for: "[Gen AI metrics](#gen-ai-metrics-otlp-semantic-conventions)" - setting: "`config.logging.log_statistics`: `true`" - plugin: "[AI MCP Proxy](/plugins/ai-mcp-proxy/reference/)" + policy: "[AI MCP Proxy](/plugins/ai-mcp-proxy/reference/)" required_for: "[MCP metrics](#mcp-metrics)" - setting: "`config.logging.log_statistics`: `true`" - plugin: "[AI A2A Proxy](/plugins/ai-a2a-proxy/reference/)" + policy: "[AI A2A Proxy](/plugins/ai-a2a-proxy/reference/)" required_for: "[A2A metrics](#a2a-metrics)" {% endtable %} Some metrics have additional requirements: -* `gen_ai.server.request.duration` and `mcp.client.operation.duration` require `config.metrics.enable_latency_metrics` set to `true` in the [OpenTelemetry plugin](/plugins/opentelemetry/reference/). -* The `error.type` attribute on duration metrics requires `config.metrics.enable_request_metrics` set to `true` in the [OpenTelemetry plugin](/plugins/opentelemetry/reference/). +* `gen_ai.server.request.duration` and `mcp.client.operation.duration` require `config.metrics.enable_latency_metrics` set to `true` in the [OpenTelemetry AI Policy](/ai-gateway/policies/opentelemetry/reference/). +* The `error.type` attribute on duration metrics requires `config.metrics.enable_request_metrics` set to `true` in the [OpenTelemetry AI Policy](/ai-gateway/policies/opentelemetry/reference/). -## Gen AI metrics (OTel semantic conventions) +## Gen AI metrics (OTLP semantic conventions) These metrics follow the [OpenTelemetry Gen AI semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/). They capture request duration, upstream latency, token usage, and streaming performance. ### Metric reference -{% include plugins/otel/metric_tables.md metric_prefixes="gen_ai." %} + +{% include md/ai-gateway/v2/policies/metric_tables.md metric_prefixes="gen_ai." %} ## Kong Gen AI metrics These metrics use the `kong.gen_ai.*` namespace and capture Kong-specific AI observability data, including cost tracking, cache and RAG latency, and AWS Guardrails processing time. -### kong.gen_ai.llm.cost - -Cost of AI requests. To populate this metric, define `model.options.input_cost` and `model.options.output_cost` in the [AI Proxy](/plugins/ai-proxy/reference/#schema--config-model-options-input-cost) or [AI Proxy Advanced](/plugins/ai-proxy-advanced/reference/#schema--config-targets-model-options-input-cost) plugin configuration. - -* **Type**: Counter -* **Unit**: `{cost}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`gen_ai.provider.name`" - desc: "Name of the Gen AI provider." - - attr: "`gen_ai.request.model`" - desc: "Model name targeted by the request." - - attr: "`gen_ai.response.model`" - desc: "Model name reported by the provider in the response." - - attr: "`gen_ai.operation.name`" - desc: "Operation requested, such as `chat` or `embeddings`." - - attr: "`kong.gen_ai.cache.status`" - desc: "Cache status: `hit` or empty if not cached." - - attr: "`kong.gen_ai.vector_db`" - desc: "Vector database used for caching, such as `redis`." - - attr: "`kong.gen_ai.embeddings.provider`" - desc: "Embeddings provider used for caching." - - attr: "`kong.gen_ai.embeddings.model`" - desc: "Embeddings model used for caching." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.auth.consumer.name`" - desc: "Name of the authenticated Consumer." - - attr: "`kong.gen_ai.request.mode`" - desc: "Request mode: `oneshot`, `stream`, or `realtime`." -{% endtable %} - - -### kong.gen_ai.cache.fetch.latency - -Time to fetch a response from the semantic cache. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.llm.cost`](#konggen_aillmcost). - -### kong.gen_ai.cache.embeddings.latency +To populate `kong.gen_ai.llm.cost`, define `model.options.input_cost` and `model.options.output_cost` in your model configuration. -Time to generate embeddings during cache operations. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.llm.cost`](#konggen_aillmcost). - -### kong.gen_ai.rag.fetch.latency - -Time to fetch data from a RAG (Retrieval-Augmented Generation) source. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.llm.cost`](#konggen_aillmcost). - -### kong.gen_ai.rag.embeddings.latency - -Time to generate embeddings for RAG operations. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.llm.cost`](#konggen_aillmcost). - -### kong.gen_ai.aws.guardrails.latency - -Time for AWS Guardrails to process a request. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.gen_ai.aws.guardrails.id`" - desc: "ID of the AWS Guardrails configuration." - - attr: "`kong.gen_ai.aws.guardrails.version`" - desc: "Version of the AWS Guardrails configuration." - - attr: "`kong.gen_ai.aws.guardrails.mode`" - desc: "Mode of the AWS Guardrails evaluation." - - attr: "`kong.gen_ai.aws.guardrails.region`" - desc: "AWS region of the Guardrails service." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.auth.consumer.name`" - desc: "Name of the authenticated Consumer." -{% endtable %} - +{% include md/ai-gateway/v2/policies/metric_tables.md metric_prefixes="kong.gen_ai." %} ## MCP metrics These metrics provide observability into MCP (Model Context Protocol) server interactions, including latency, response sizes, errors, and ACL decisions. -### mcp.client.operation.duration - -Duration of the MCP request as observed by the sender. Only available when the [AI MCP Proxy plugin](/plugins/ai-mcp-proxy/) is in passthrough-listener mode (the upstream is an MCP server). Requires `enable_latency_metrics` set to `true`. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`mcp.method.name`" - desc: "MCP method name, such as `tools/call`." - - attr: "`gen_ai.tool.name`" - desc: "Name of the tool invoked." - - attr: "`error.type`" - desc: "JSON-RPC error code, if the request failed." - - attr: "`gen_ai.operation.name`" - desc: "Operation name, such as `execute_tool` for `tools/call`." -{% endtable %} - - -### mcp.server.operation.duration - -Duration of the MCP request as observed by the receiver. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`mcp.client.operation.duration`](#mcpclientoperationduration). - -### kong.gen_ai.mcp.response.size - -Size of the MCP response body. - -* **Type**: Histogram -* **Unit**: `By` (bytes) - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`mcp.method.name`" - desc: "MCP method name, such as `tools/call`." - - attr: "`gen_ai.tool.name`" - desc: "Name of the tool invoked." -{% endtable %} - - -### kong.gen_ai.mcp.request.error.count - -Number of MCP request errors. - -* **Type**: Counter -* **Unit**: `{error}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`mcp.method.name`" - desc: "MCP method name, such as `tools/call`." - - attr: "`gen_ai.tool.name`" - desc: "Name of the tool invoked." - - attr: "`error.type`" - desc: "JSON-RPC error code." -{% endtable %} - - -### kong.gen_ai.mcp.acl.allowed - -Number of MCP requests allowed by ACL rules. - -* **Type**: Counter -* **Unit**: `{request}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.gen_ai.mcp.primitive`" - desc: "MCP primitive type, such as `tool`." - - attr: "`kong.gen_ai.mcp.primitive_name`" - desc: "Name of the MCP primitive." -{% endtable %} - - -### kong.gen_ai.mcp.acl.denied - -Number of MCP requests denied by ACL rules. - -* **Type**: Counter -* **Unit**: `{request}` - -**Attributes:** Same as [`kong.gen_ai.mcp.acl.allowed`](#konggen_aimcpaclallowed). +{% include md/ai-gateway/v2/policies/metric_tables.md metric_prefixes="mcp.,kong.gen_ai.mcp." %} ## A2A metrics -These metrics provide observability into [A2A (Agent-to-Agent)](/plugins/ai-a2a-proxy/) traffic, including request volume, latency, response sizes, and task state transitions. - -### kong.gen_ai.a2a.request.count - -Total number of A2A requests. - -* **Type**: Counter -* **Unit**: `{request}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.gen_ai.a2a.method`" - desc: "A2A method name." - - attr: "`kong.gen_ai.a2a.binding`" - desc: "A2A binding type." -{% endtable %} - - -### kong.gen_ai.a2a.request.duration - -Duration of an A2A request. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.a2a.request.count`](#konggen_aia2arequestcount). - -### kong.gen_ai.a2a.response.size - -Size of the A2A response body. - -* **Type**: Histogram -* **Unit**: `By` (bytes) - -**Attributes:** Same as [`kong.gen_ai.a2a.request.count`](#konggen_aia2arequestcount). +These metrics provide observability into [A2A (Agent-to-Agent)](/ai-gateway/entities/ai-agent/) traffic, including request volume, latency, response sizes, and task state transitions. -### kong.gen_ai.a2a.ttfb - -Time to first byte for A2A streaming responses. - -* **Type**: Histogram -* **Unit**: `s` (seconds) - -**Attributes:** Same as [`kong.gen_ai.a2a.request.count`](#konggen_aia2arequestcount). - -### kong.gen_ai.a2a.request.error.count - -Number of A2A request errors. - -* **Type**: Counter -* **Unit**: `{error}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.gen_ai.a2a.method`" - desc: "A2A method name." - - attr: "`kong.gen_ai.a2a.binding`" - desc: "A2A binding type." - - attr: "`kong.gen_ai.a2a.error.type`" - desc: "Type of the A2A error." -{% endtable %} - - -### kong.gen_ai.a2a.task.state.count - -Number of A2A task state transitions. - -* **Type**: Counter -* **Unit**: `{state}` - - -{% table %} -columns: - - title: Attribute - key: attr - - title: Description - key: desc -rows: - - attr: "`kong.service.name`" - desc: "Name of the Gateway Service." - - attr: "`kong.route.name`" - desc: "Name of the Route." - - attr: "`kong.workspace.name`" - desc: "Name of the Workspace." - - attr: "`kong.gen_ai.a2a.task.state`" - desc: "Task state, such as `completed`, `failed`, or `in_progress`." -{% endtable %} - +{% include md/ai-gateway/v2/policies/metric_tables.md metric_prefixes="kong.gen_ai.a2a." %} diff --git a/app/ai-gateway/ai-providers/anthropic.md b/app/ai-gateway/ai-providers/anthropic.md index e5a5e7c1b58..baaee6711c1 100644 --- a/app/ai-gateway/ai-providers/anthropic.md +++ b/app/ai-gateway/ai-providers/anthropic.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Anthropic tutorials - url: /how-to/?tags=anthropic - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ diff --git a/app/ai-gateway/ai-providers/azure.md b/app/ai-gateway/ai-providers/azure.md index b85487fb0e9..2c793e9c9d9 100644 --- a/app/ai-gateway/ai-providers/azure.md +++ b/app/ai-gateway/ai-providers/azure.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Azure OpenAI tutorials - url: /how-to/?tags=azure&tags=ai - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -45,7 +43,7 @@ faqs: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/bedrock.md b/app/ai-gateway/ai-providers/bedrock.md index 4fb187e91e2..78425ebdd96 100644 --- a/app/ai-gateway/ai-providers/bedrock.md +++ b/app/ai-gateway/ai-providers/bedrock.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Amazon Bedrock tutorials - url: /how-to/?tags=bedrock - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -58,7 +56,7 @@ faqs: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/cerebras.md b/app/ai-gateway/ai-providers/cerebras.md index 7a34599d7f0..fbdd36b2db8 100644 --- a/app/ai-gateway/ai-providers/cerebras.md +++ b/app/ai-gateway/ai-providers/cerebras.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Cerebras tutorials - url: /how-to/?tags=cerebras - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -40,7 +38,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/cohere.md b/app/ai-gateway/ai-providers/cohere.md index a995202d238..05e89982f2c 100644 --- a/app/ai-gateway/ai-providers/cohere.md +++ b/app/ai-gateway/ai-providers/cohere.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Cohere tutorials - url: /how-to/?tags=cohere - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -48,7 +46,7 @@ faqs: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/dashscope.md b/app/ai-gateway/ai-providers/dashscope.md index ea17138e6a7..836ffb96d75 100644 --- a/app/ai-gateway/ai-providers/dashscope.md +++ b/app/ai-gateway/ai-providers/dashscope.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Dashscope tutorials - url: /how-to/?tags=dashscope - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -41,7 +39,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/databricks.md b/app/ai-gateway/ai-providers/databricks.md index d263a16beeb..b0244e7a056 100644 --- a/app/ai-gateway/ai-providers/databricks.md +++ b/app/ai-gateway/ai-providers/databricks.md @@ -16,11 +16,7 @@ products: - ai-gateway tools: - - admin-api - konnect-api - - deck - - kic - - terraform tags: - ai @@ -31,8 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ diff --git a/app/ai-gateway/ai-providers/deepseek.md b/app/ai-gateway/ai-providers/deepseek.md index 96d8d89a860..cc833234c3a 100644 --- a/app/ai-gateway/ai-providers/deepseek.md +++ b/app/ai-gateway/ai-providers/deepseek.md @@ -27,8 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -39,7 +39,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/gemini.md b/app/ai-gateway/ai-providers/gemini.md index 0e05b3e4bb7..c6b417acd3d 100644 --- a/app/ai-gateway/ai-providers/gemini.md +++ b/app/ai-gateway/ai-providers/gemini.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Gemini tutorials - url: /how-to/?tags=gemini - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -56,7 +54,7 @@ faqs: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/huggingface.md b/app/ai-gateway/ai-providers/huggingface.md index 28ecb13699d..d52336bf13b 100644 --- a/app/ai-gateway/ai-providers/huggingface.md +++ b/app/ai-gateway/ai-providers/huggingface.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Hugging Face tutorials - url: /how-to/?tags=huggingface - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -43,7 +41,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/kimi.md b/app/ai-gateway/ai-providers/kimi.md index f8be6460f4a..e2be890a4f9 100644 --- a/app/ai-gateway/ai-providers/kimi.md +++ b/app/ai-gateway/ai-providers/kimi.md @@ -33,7 +33,7 @@ related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -44,7 +44,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/) as follows: +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/) as follows: {% konnect_api_request %} diff --git a/app/ai-gateway/ai-providers/llama.md b/app/ai-gateway/ai-providers/llama.md index a3931281d8a..e57a87fee22 100644 --- a/app/ai-gateway/ai-providers/llama.md +++ b/app/ai-gateway/ai-providers/llama.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Llama tutorials - url: /how-to/?tags=llama - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -41,7 +39,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/mistral.md b/app/ai-gateway/ai-providers/mistral.md index 5a159ec926e..4aede715949 100644 --- a/app/ai-gateway/ai-providers/mistral.md +++ b/app/ai-gateway/ai-providers/mistral.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Mistral tutorials - url: /how-to/?tags=mistral - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -41,7 +39,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/ollama.md b/app/ai-gateway/ai-providers/ollama.md index 98f716c5d85..44cdcdb935e 100644 --- a/app/ai-gateway/ai-providers/ollama.md +++ b/app/ai-gateway/ai-providers/ollama.md @@ -27,8 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ diff --git a/app/ai-gateway/ai-providers/openai.md b/app/ai-gateway/ai-providers/openai.md index 72c540f6b11..620a0f48a3e 100644 --- a/app/ai-gateway/ai-providers/openai.md +++ b/app/ai-gateway/ai-providers/openai.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: OpenAI tutorials - url: /how-to/?tags=openai - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -41,7 +39,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/vercel.md b/app/ai-gateway/ai-providers/vercel.md index be249914b53..c1720e8a6c1 100644 --- a/app/ai-gateway/ai-providers/vercel.md +++ b/app/ai-gateway/ai-providers/vercel.md @@ -28,7 +28,7 @@ related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - text: "{{site.ai_gateway}} Policies" - url: /plugins/?category=ai + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ --- @@ -38,7 +38,7 @@ related_resources: ## Configure a {{ provider.name }} provider -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Note that, {{ site.vercel }} hosts [models](https://vercel.com/ai-gateway/models) from other providers so in this example we use `openai/gpt-5.5`. diff --git a/app/ai-gateway/ai-providers/vertex.md b/app/ai-gateway/ai-providers/vertex.md index 1e096c5014f..e7e1d5f9180 100644 --- a/app/ai-gateway/ai-providers/vertex.md +++ b/app/ai-gateway/ai-providers/vertex.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Vertex AI tutorials - url: /how-to/?tags=vertex-ai - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -42,7 +40,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/ai-providers/vllm.md b/app/ai-gateway/ai-providers/vllm.md index 46f2d49fd57..b5b97e6a734 100644 --- a/app/ai-gateway/ai-providers/vllm.md +++ b/app/ai-gateway/ai-providers/vllm.md @@ -29,11 +29,9 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: vLLM tutorials - url: /how-to/?tags=vllm - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai - - text: AI providers + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ + - text: AI Providers url: /ai-gateway/ai-providers/ --- diff --git a/app/ai-gateway/ai-providers/xai.md b/app/ai-gateway/ai-providers/xai.md index f52dcd80e22..89d4edc0fba 100644 --- a/app/ai-gateway/ai-providers/xai.md +++ b/app/ai-gateway/ai-providers/xai.md @@ -27,10 +27,8 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: xAI tutorials - url: /how-to/?tags=xai - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai + - text: "{{site.ai_gateway}} Policies" + url: /ai-gateway/policies/ - text: AI Providers url: /ai-gateway/ai-providers/ @@ -43,7 +41,7 @@ related_resources: ## Configure {{ provider.name }} -To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [Provider](/ai-gateway/entities/ai-provider/). You can then access supported [Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. +To use {{ provider.name }} with {{site.ai_gateway}}, configure a new [AI Provider](/ai-gateway/entities/ai-provider/). You can then access supported [AI Models](/ai-gateway/entities/ai-model/) from {{ provider.name }}. Here's a minimal configuration for chat completions: diff --git a/app/ai-gateway/llm-open-telemetry.md b/app/ai-gateway/llm-open-telemetry.md index f67cc37c9ed..824a998f127 100644 --- a/app/ai-gateway/llm-open-telemetry.md +++ b/app/ai-gateway/llm-open-telemetry.md @@ -7,7 +7,6 @@ toc_depth: 4 products: - ai-gateway - - gateway breadcrumbs: - /ai-gateway/ @@ -17,13 +16,8 @@ tags: - monitoring - tracing -plugins: - - opentelemetry - - ai-proxy - - ai-proxy-advanced - min_version: - gateway: '3.13' + ai-gateway: '2.0' tech_preview: true @@ -34,29 +28,22 @@ related_resources: url: /ai-gateway/ai-otel-metrics/ - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: "{{site.ai_gateway}} plugins" - url: /plugins/?category=ai - - text: OpenTelemetry plugin - url: /plugins/opentelemetry/ - - text: Zipkin plugin - url: /plugins/zipkin/ + - text: OpenTelemetry Policy + url: /ai-gateway/policies/opentelemetry/ + - text: Zipkin Policy + url: /ai-gateway/policies/zipkin/ - text: "{{site.base_gateway}} tracing guide" url: /gateway/tracing/ - - text: Set up Jaeger with Gen AI OpenTelemetry - url: /how-to/set-up-jaeger-with-gen-ai-otel/ - - text: Validate Gen AI tool calls with Jaeger and OpenTelemetry - url: /how-to/set-up-jaeger-with-gen-ai-otel-for-tool-calls/ works_on: - - on-prem - konnect --- -{% new_in 3.13 %} {{site.ai_gateway}} supports [OpenTelemetry](https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#genai-attributes) instrumentation for generative AI traffic. When the OpenTelemetry (OTEL) plugin is enabled in {{site.ai_gateway}}, a set of **Gen AI-specific attributes** are emitted on tracing spans. These attributes complement the core tracing instrumentations described in the [{{site.base_gateway}} tracing guide](/gateway/tracing), giving insight into the Gen AI request lifecycle (inputs, model, and outputs), usage, and tool/agent interactions. +{{site.ai_gateway}} supports [OpenTelemetry](https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#genai-attributes) instrumentation for generative AI traffic. When an OpenTelemetry (OTEL) Policy is enabled in {{site.ai_gateway}}, a set of **Gen AI-specific attributes** are emitted on tracing spans. These attributes provide insight into the Gen AI request lifecycle (inputs, model, and outputs), usage, and tool or agent interactions. -{% new_in 3.14 %} [A2A agent traffic](#a2a-span-attributes) is also instrumented via the [AI A2A Proxy plugin](/plugins/ai-a2a-proxy/). +You can also capture [A2A agent traffic](#a2a-span-attributes) by enabling statistics logging on [AI Agents](/ai-gateway/entities/ai-agent/#logging-and-observability). -You can export these attributes via a supported backend such as [Jaeger](/how-to/set-up-jaeger-with-otel/) configured through Kong's [OpenTelemetry plugin](/plugins/opentelemetry) or the [Zipkin plugin](/plugins/zipkin) to: +You can export these attributes via a supported backend to: * Inspect which model or provider handled a request * Track conversation/session identifiers across requests @@ -65,19 +52,17 @@ You can export these attributes via a supported backend such as [Jaeger](/how-to * Measure tool-call behavior (which tools were invoked, and their metadata) * Monitor token usage (input vs. output) for cost or performance analysis -The span data is sent to the configured OTEL endpoint through the existing tracing plugins. Use the OpenTelemetry plugin or Zipkin plugin to export these spans to backends such as Jaeger. +The span data is sent to the configured OTEL endpoint through the [Kong tracing](/gateway/tracing/). Use a Policy configured with OpenTelemetry or Zipkin to export these spans to backends such as Jaeger. {:.info} > This page covers **span attributes** (per-request tracing data). {{site.ai_gateway}} also supports **OTLP metrics** (aggregated counters and histograms for latency, token usage, cost, and error rates). See the [Gen AI OpenTelemetry metrics reference](/ai-gateway/ai-otel-metrics/) for details. -{% include plugins/otel/collecting-otel-data.md %} - {:.warning} > Some Gen AI span attributes can include sensitive request or response payload data. In particular, `gen_ai.input.messages` and `gen_ai.output.messages` may contain prompts, model outputs, PII, secrets, or credentials. Review your tracing, retention, access-control, and redaction requirements before enabling or exporting payload-related tracing data. ## Span attribute reference -{% include plugins/otel/span_attribute_tables.md %} +{% include md/ai-gateway/v2/policies/span_attribute_tables.md %} diff --git a/app/ai-gateway/load-balancing.md b/app/ai-gateway/load-balancing.md index 790f9c4a019..eee22fde282 100644 --- a/app/ai-gateway/load-balancing.md +++ b/app/ai-gateway/load-balancing.md @@ -10,7 +10,6 @@ works_on: - konnect products: - - gateway - ai-gateway tools: diff --git a/app/ai-gateway/monitor-ai-llm-metrics.md b/app/ai-gateway/monitor-ai-llm-metrics.md index edc81982dc6..660934d8c31 100644 --- a/app/ai-gateway/monitor-ai-llm-metrics.md +++ b/app/ai-gateway/monitor-ai-llm-metrics.md @@ -23,23 +23,23 @@ related_resources: url: /api/gateway/status/ - text: Admin API url: /api/gateway/admin-ee/ - - text: Visualize AI metrics with Grafana - url: /how-to/visualize-llm-metrics-with-grafana/ +# - text: Visualize AI metrics with Grafana +# url: /how-to/visualize-llm-metrics-with-grafana/ works_on: - konnect --- -{{site.ai_gateway}} calls LLM-based services according to the settings of your [Providers](/ai-gateway/entities/ai-provider/) and [Models](/ai-gateway/entities/ai-model/). You can use the built in logging and a [Prometheus](/plugins/prometheus/) Policy to aggregate the LLM provider responses to count the number of tokens sent through {{site.ai_gateway}}. If you have defined input and output costs in the models, you can also calculate aggregate costs. You can also track whether the requests have been cached by {{site.ai_gateway}}, saving the cost of contacting the LLM providers, which improves performance. +{{site.ai_gateway}} calls LLM-based services according to the settings of your [Providers](/ai-gateway/entities/ai-provider/) and [Models](/ai-gateway/entities/ai-model/). You can use the built in logging and a [Prometheus](/ai-gateway/policies/prometheus/) Policy to aggregate the LLM provider responses to count the number of tokens sent through {{site.ai_gateway}}. If you have defined input and output costs in the models, you can also calculate aggregate costs. You can also track whether the requests have been cached by {{site.ai_gateway}}, saving the cost of contacting the LLM providers, which improves performance. -In addition to LLM usage, {{site.ai_gateway}} can also log MCP server traffic. [MCP logging](/ai-gateway/entities/ai-mcp-server/#logging-and-audits) provides visibility into latency, response sizes, and error rates when AI plugins invoke external MCP tools and servers. +In addition to LLM usage, {{site.ai_gateway}} can also log MCP server traffic. [MCP logging](/ai-gateway/entities/ai-mcp-server/#logging-and-audits) provides visibility into latency, response sizes, and error rates when AI Policies invoke external MCP tools and servers. -Create a [Prometheus Policy](/plugins/prometheus/) to expose metrics in the [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus server. +Create a [Prometheus Policy](/ai-gateway/policies/prometheus/) to expose metrics in the [Prometheus](https://prometheus.io/docs/introduction/overview/) exposition format, which can be scraped by a Prometheus server. -The [Prometheus Policy](/plugins/prometheus/) records and exposes metrics at the node level. Your Prometheus server will need to discover all Kong nodes via a service discovery mechanism, +The [Prometheus Policy](/ai-gateway/policies/prometheus/) records and exposes metrics at the node level. Your Prometheus server will need to discover all Kong nodes via a service discovery mechanism, and consume data from each node's Prometheus `/metrics` endpoint. -AI metrics exported by the Prometheus plugin can be graphed in Grafana using [{{site.ai_gateway}} Dashboard](https://grafana.com/grafana/dashboards/21162-kong-cx-ai/). +AI metrics exported by the Prometheus Policy can be graphed in Grafana using [{{site.ai_gateway}} Dashboard](https://grafana.com/grafana/dashboards/21162-kong-cx-ai/). ## Available metrics @@ -51,7 +51,7 @@ The following sections describe the AI metrics that are available. AI metrics are disabled by default as it may create high number of metrics and may cause performance issues. To enable them: -* Set `config.ai_metrics` to `true` in the [Prometheus Policy configuration](/plugins/prometheus/reference/). +* Set `config.ai_metrics` to `true` in the [Prometheus Policy configuration](/ai-gateway/policies/prometheus/reference/). * Set `config.logging.log_statistics` to `true` in the [Model](/ai-gateway/entities/ai-model/). ### LLM traffic metrics overview diff --git a/app/ai-gateway/policies/index.html b/app/ai-gateway/policies/index.html new file mode 100644 index 00000000000..c2e3a48d47a --- /dev/null +++ b/app/ai-gateway/policies/index.html @@ -0,0 +1,70 @@ +--- +title: Kong AI Gateway Policies +layout: default +hub: true +no_edit_link: true +products: + - ai-gateway +breadcrumbs: + - /ai-gateway/ + +works_on: + - konnect + +description: An overview of policies that work with {{site.ai_gateway_name}}. +--- +{%- assign categories = site.data.plugin_categories | sort: "text" -%} +{%- assign policies = site.data.ai_gateway_policies | where_exp: "policy", "policy.published != false" -%} +{%- assign third_party_premium = policies | where: "third_party", true | where: "premium_partner", true -%} +{%- assign third_party_other = policies | where: "third_party", true | where_exp: "policy", "policy.premium_partner != true" -%} +{%- assign third_party_policies = third_party_premium | concat: third_party_other -%} + +{% if page.output_format == 'markdown'%} +{% for cat in categories %} +{%- assign policies_for_category = policies | where_exp: "policy", "policy.categories contains cat.slug" | sort: +"name" -%} +{% if policies_for_category.size > 0 %} +## {{ cat.text }} + +{% for policy in policies_for_category %} +### {{policy.name | liquify}} +Description: {{policy.description | liquify}} +Documentation: {{policy.overview_url}} +{% endfor %}{% endif %}{% endfor %} + +{% if third_party_policies.size > 0 %} +## 3rd Party Policies + +{% for policy in third_party_policies %} +### {{policy.name | liquify}} +Description: {{policy.description | liquify}} +Documentation: {{policy.overview_url}} +{% endfor %}{% endif %} +{% else %} +
+
+
+
+
+

Kong AI Gateway Policies Hub

{% include + components/llm_dropdown.html url=page.url %} +
+ Extend Kong AI Gateway with powerful policies and easy integrations +
+
+ +
+
+ {% include policies/index/filters.html functionality=true support_by=false trusted_content=true %} + +
+ {% include policies/index/search_input.html %} + + {% include policies/index/plugin_cards.html categories=categories plugins=policies third_party_plugins=third_party_policies %} +
+
+
+{% endif %} \ No newline at end of file diff --git a/app/ai-gateway/semantic-similarity.md b/app/ai-gateway/semantic-similarity.md index 4209c67b1d5..836ad748655 100644 --- a/app/ai-gateway/semantic-similarity.md +++ b/app/ai-gateway/semantic-similarity.md @@ -22,9 +22,9 @@ min_version: related_resources: - text: "{{site.ai_gateway}}" url: /ai-gateway/ - - text: Policy entity + - text: AI Policy entity url: /ai-gateway/entities/ai-policy/ - - text: "{{site.ai_gateway}} Model entity" + - text: "AI Model entity" url: /ai-gateway/entities/ai-model/ - text: Semantic processing and vector similarity search with Kong and Redis url: https://konghq.com/blog/engineering/semantic-processing-and-vector-similarity-search-with-kong-and-redis @@ -45,25 +45,25 @@ For example, in the figure 1, “king” and “emperor” are semantically more ## Semantic similarity in {{site.ai_gateway}} -Based on meaning rather than exact matches, {{site.ai_gateway}} can perform intelligent request routing, caching, and content filtering using semantic similarity queries. A [Model](/ai-gateway/entities/ai-model/) can leverage semantic similarity in two ways: +Based on meaning rather than exact matches, {{site.ai_gateway}} can perform intelligent request routing, caching, and content filtering using semantic similarity queries. An [AI Model](/ai-gateway/entities/ai-model/) can leverage semantic similarity in two ways: 1. **Semantic load balancing**: Route requests to upstream providers based on how semantically similar the prompt is to each provider's capabilities, using the `semantic` load balancing algorithm. -2. **Semantic Policies**: Attach Policies like AI Semantic Cache or AI Semantic Prompt Guard to add similarity-based caching, retrieval-augmented generation (RAG), and guardrails. +2. **Semantic Policies**: Attach AI Policies like [AI Semantic Cache](/ai-gateway/policies/ai-semantic-cache/) or [AI Semantic Prompt Guard](/ai-gateway/policies/ai-semantic-prompt-guard/) to add similarity-based caching, retrieval-augmented generation (RAG), and guardrails. ### Vector databases To store and compare embeddings efficiently, {{site.ai_gateway}} semantic features rely on vector databases. These specialized datastores index high-dimensional embeddings and enable **fast similarity search** based on distance metrics like cosine similarity or Euclidean distance. -A Model Entity’s [semantic load balancer](/ai-gateway/entities/ai-model/#algorithms) stores vector representations of each target model’s semantic description at configuration time, and uses the vector database to compare incoming prompts against those stored vectors. +An AI Model entity’s [semantic load balancer](/ai-gateway/entities/ai-model/#algorithms) stores vector representations of each target model’s semantic description at configuration time, and uses the vector database to compare incoming prompts against those stored vectors. -Semantic policies also use vector databases to perform similarity searches at request time. The selected database stores the embeddings generated by the Model or Policies (either at config time or runtime), and determines the accuracy and performance of semantic operations. +Semantic policies also use vector databases to perform similarity searches at request time. The selected database stores the embeddings generated by the AI Model or AI Policies (either at config time or runtime), and determines the accuracy and performance of semantic operations. {% include md/ai-gateway/v2/ai-vector-db.md %} ### What is compared for similarity? -Each policy applies similarity search slightly differently depending on its goal. These comparisons determine whether the policy routes, blocks, reuses, or enriches a prompt based on meaning rather than syntax. +Each AI Policy applies similarity search slightly differently depending on its goal. These comparisons determine whether the AI Policy routes, blocks, reuses, or enriches a prompt based on meaning rather than syntax. -The following table describes how each {{site.ai_gateway}} policy compares embeddings: +The following table describes how each {{site.ai_gateway}} Policy compares embeddings: {% table %} columns: @@ -74,10 +74,10 @@ columns: - title: Compared against key: stored rows: - - feature: "Model semantic load balancing" + - feature: "AI Model semantic load balancing" incoming: "Incoming prompts" stored: "Stored embeddings of each target model's semantic description" - - feature: "AI Semantic Cache policy" + - feature: "AI Semantic Cache Policy" incoming: "Incoming prompts" stored: "Cached prompt keys" - feature: "AI RAG Injector policy" @@ -92,7 +92,7 @@ rows: Semantic similarity is used differently depending on the feature: -**Model semantic load balancing** (`semantic` algorithm): +**AI Model semantic load balancing** (`semantic` algorithm): - Generates embeddings for each target model's semantic description at configuration time and stores them in the vector database. - At request time, embeds the incoming prompt using the same embedding model and compares it against the stored target embeddings. - Routes requests to the target whose description is most semantically similar to the prompt, using the distance metric (cosine or Euclidean) configured for the Model. @@ -100,9 +100,9 @@ Semantic similarity is used differently depending on the feature: **Semantic Policies**: - Each semantic Policy uses similarity search slightly differently based on its goal. -- AI Semantic Cache compares prompts against cached prompt keys to find reusable responses. -- AI RAG Injector compares prompts against vectorized document chunks to retrieve relevant context. -- AI Semantic Prompt Guard and AI Semantic Response Guard compare content against vectorised allow and deny lists to detect misuse patterns semantically. +- [AI Semantic Cache](/ai-gateway/policies/ai-semantic-cache/) compares prompts against cached prompt keys to find reusable responses. +- [AI RAG Injector](/ai-gateway/policies/ai-rag-injector/) compares prompts against vectorized document chunks to retrieve relevant context. +- [AI Semantic Prompt Guard](/ai-gateway/policies/ai-semantic-prompt-guard/) and [AI Semantic Response Guard](/ai-gateway/policies/ai-semantic-response-guard/) compare content against vectorized allow and deny lists to detect misuse patterns semantically. ## Dimensionality @@ -266,7 +266,7 @@ The threshold defines how permissive the matching is. **Higher threshold values * For **Euclidean distance**, the threshold is normalized to a 0–1 range and sets the maximum allowable distance between embedding vectors. A value of `0` requires exact matches (zero distance). A value of `1` permits the broadest possible matches. Typical configurations use `0.1–0.2` for strict matching and `0.5–0.8` for broader matching. -In both cases, if the [{{site.base_gateway}} logs](/gateway/logs/) indicate "no target can be found under threshold X," increase the threshold value to allow more matches. +In both cases, if the [{{site.ai_gateway}} logs](/ai-gateway/ai-logs/) indicate "no target can be found under threshold X," increase the threshold value to allow more matches. The optimal threshold depends on the selected distance metric, the embedding model's dimensionality, and the variation in your data. Tuning may be required for best results. diff --git a/app/ai-gateway/streaming.md b/app/ai-gateway/streaming.md index a7005b5c93c..be605d20b59 100644 --- a/app/ai-gateway/streaming.md +++ b/app/ai-gateway/streaming.md @@ -4,33 +4,27 @@ content_type: reference layout: reference works_on: - - on-prem - konnect products: - - gateway - ai-gateway breadcrumbs: - /ai-gateway/ tags: - ai - streaming - - ai-proxy - -plugins: - - ai-proxy - - ai-proxy-advanced - + min_version: - gateway: '3.7' + ai-gateway: '2.0' -description: This guide walks you through setting up the AI Proxy and AI Proxy Advanced plugin with streaming. +description: This guide walks you through setting up AI Models with streaming. --- ## What is request streaming? -In an LLM (Large Language Model) inference request, {{site.base_gateway}} uses the upstream provider's REST API to generate the next chat message from the caller. -Normally, this request is processed and completely buffered by the LLM before being sent back to {{site.base_gateway}} and then to the caller in a single large JSON block. This process can be time-consuming, depending on the `max_tokens`, other request parameters, and the complexity of the request sent to the LLM model. +In an LLM (Large Language Model) inference request, {{site.ai_gateway}} uses the upstream provider's REST API to generate the next chat message from the caller. + +Normally, this request is processed and completely buffered by the LLM before being sent back to {{site.ai_gateway}} and then to the caller in a single large JSON block. This process can be time-consuming, depending on the `max_tokens`, other request parameters, and the complexity of the request sent to the LLM model. To avoid making the user wait for their chat response with a loading animation, most models can stream each word (or sets of words and tokens) back to the client. This allows the chat response to be rendered in real time. @@ -55,23 +49,22 @@ for chunk in stream: print(chunk.choices[0].delta.content, end="", flush=True) ``` -The client won't have to wait for the entire response. Instead, tokens will appear as they come in. +A client configured to use streaming won't have to wait for the entire response. Instead, tokens will appear as they come in. -## How AI Proxy streaming works +## How {{site.ai_gateway}} streaming works In streaming mode, a client can set `"stream": true` in their request, and the LLM server will stream each part of the response text (usually token-by-token) as a server-sent event. -{{site.base_gateway}} captures each batch of events and translates them into the {{site.base_gateway}} inference format. This ensures that all providers are compatible with the same framework including OpenAI-compatible SDKs or similar. +{{site.ai_gateway}} captures each batch of events and translates them into the {{site.ai_gateway}} inference format. This ensures that all providers are compatible with the same framework including OpenAI-compatible SDKs or similar. In a standard LLM transaction, requests proxied directly to the LLM look like this: {% mermaid %} sequenceDiagram actor Client - participant {{site.base_gateway}} - Note right of {{site.base_gateway}}: AI Proxy Advanced plugin - Client->>+{{site.base_gateway}}: - destroy {{site.base_gateway}} - {{site.base_gateway}}->>+Cloud LLM: Sends proxy request information + participant {{site.ai_gateway}} + Client->>+{{site.ai_gateway}}: + destroy {{site.ai_gateway}} + {{site.ai_gateway}}->>+Cloud LLM: Sends proxy request information Cloud LLM->>+Client: Sends chunk to client {% endmermaid %} @@ -80,8 +73,7 @@ When streaming is requested, requests proxied directly to the LLM look like this {% mermaid %} flowchart LR A(client) - B({{site.base_gateway}} Gateway with - AI Proxy Advanced plugin) + B({{site.ai_gateway}}) C(Cloud LLM) D[[transform frame]] E[[read frame]] @@ -118,16 +110,16 @@ It also estimates tokens for LLM services that decided to not stream back the to ## Streaming limitations -Keep the following limitations in mind when you configure streaming for the {{site.ai_gateway}} plugin: +Keep the following limitations in mind when you configure streaming for the {{site.ai_gateway}}: * Multiple AI features shouldn’t be expected to be applied and work simultaneously. -* You can't use the [Response Transformer plugin](/plugins/response-transformer/) or any other response phase plugin when streaming is configured. -* The [AI Request Transformer plugin](/plugins/ai-request-transformer/) plugin **will** work, but the [AI Response Transformer plugin](/plugins/ai-response-transformer/) **will not**. This is because {{site.base_gateway}} can't check every single response token against a separate system. +* You can't add AI Policies that use the [Response Transformer](/plugins/response-transformer/) or otherwise trigger in the response phase when streaming is configured. +* The [AI Request Transformer Policy](/plugins/ai-request-transformer/) **will** work, but the [AI Response Transformer Policy](/plugins/ai-response-transformer/) **will not**. This is because {{site.ai_gateway}} can't check every single response token against a separate system. * Streaming currently doesn't work with the HTTP/2 protocol. You must disable this in your [`proxy_listen`](/gateway/configuration/#proxy-listen) configuration. ## Configuration -The AI Proxy and AI Proxy Advanced plugins already support request streaming; all you have to do is request {{site.base_gateway}} to stream the response tokens back to you. +{{site.ai_gateway}} already supports request streaming; all you have to do is add streaming to your request. The following is an example `llm/v1/completions` route streaming request: @@ -140,7 +132,7 @@ The following is an example `llm/v1/completions` route streaming request: You should receive each batch of tokens as HTTP chunks, each containing one or many server-sent events. -### Token usage in streaming responses {% new_in 3.13 %} +### Token usage in streaming responses You can receive token usage statistics in an SSE streaming response. Set the following parameter in the request JSON: @@ -154,7 +146,6 @@ You can receive token usage statistics in an SSE streaming response. Set the fol When you set this parameter, the `usage` object appears in the final SSE frame, before the `[DONE]` terminator. This object contains token count statistics for the request. - The following example shows how to request and process token usage statistics in a streaming response: ```python @@ -187,7 +178,7 @@ for chunk in stream: ### Response streaming configuration parameters -In the AI Proxy and AI Proxy Advanced plugin configuration, you can set an optional field `config.response_streaming` to one of three values: +In the [AI Model](/ai-gateway/entities/ai-model/) configuration, you can set an optional field `config.response_streaming` to one of three values: {% table %} columns: diff --git a/app/event-gateway/policies/index.html b/app/event-gateway/policies/index.html index f1db2e51157..ed8c2ff658d 100644 --- a/app/event-gateway/policies/index.html +++ b/app/event-gateway/policies/index.html @@ -96,25 +96,7 @@
-
-
-
- - - - -
-
- -
- -
-
+ {% include policies/index/search_input.html %}
{% for cat in categories %} diff --git a/app/plugins.html b/app/plugins.html index f69ce7d5203..9be266bed8a 100644 --- a/app/plugins.html +++ b/app/plugins.html @@ -57,128 +57,12 @@
-
- - -
+ {% include policies/index/filters.html functionality=true tier=true deployment_platforms=true support_by=true trusted_content=true %}
-
-
-
- - - - -
-
+ {% include policies/index/search_input.html %} -
- -
-
- -
- {% for cat in categories %} - {% assign plugins_for_category = plugins | where_exp: "plugin", "plugin.categories contains cat.slug" | sort: - "name" %} - {% if plugins_for_category.size > 0 %} -
-

{{ cat.text }}

- -
- {% for plugin in plugins_for_category %} - {% include cards/plugin.html plugin=plugin %} - {% endfor %} -
-
- {% endif %} - {% endfor %} - - {% if third_party_plugins.size > 0 %} -
-

3rd Party Plugins

- -
- {% for plugin in third_party_plugins %} - {% include cards/plugin.html plugin=plugin %} - {% endfor %} -
-
- {% endif %} -
+ {% include policies/index/plugin_cards.html categories=categories plugins=plugins third_party_plugins=third_party_plugins %}
diff --git a/jekyll-dev.yml b/jekyll-dev.yml index ab101eed21a..39464d2d3be 100644 --- a/jekyll-dev.yml +++ b/jekyll-dev.yml @@ -8,6 +8,7 @@ skip: indices: true # skip indices mesh_policy: true # skip mesh policies generation, except for overviews event_gateway_policy: true # skip event gateway policies generation, except for overviews + ai_gateway_policy: true # skip aigw policies generation explorer: true # skip explorer auto_generated: true # skip auto_generated references, i.e. app/_referneces mesh: true # skip kuma to mesh generation diff --git a/jekyll.yml b/jekyll.yml index 798085d893a..0bcc845bc83 100644 --- a/jekyll.yml +++ b/jekyll.yml @@ -130,6 +130,21 @@ reference_metadata: - on-prem - konnect +ai_gateway_policies: + metadata: + keep: + - title + - name + - description + - tags + - icon + - categories + - search_aliases + - publisher + - third_party + - premium_partner + - support_url + insomnia_run: https://insomnia.rest/run/ # product name vars @@ -192,8 +207,6 @@ skills_repo_slug: kong/ai-marketplace skills_repo_path: app/.repos/ai-marketplace -plugin_schemas_path: app/_schemas/gateway/plugins - mesh_policy_schemas_path: app/.repos/kuma/app/assets/ sitemap: diff --git a/spec/app/_plugins/drops/plugins/aigw_policy_schema_spec.rb b/spec/app/_plugins/drops/plugins/aigw_policy_schema_spec.rb new file mode 100644 index 00000000000..2e8f6777d89 --- /dev/null +++ b/spec/app/_plugins/drops/plugins/aigw_policy_schema_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'json' +require_relative '../../../../spec_helper' + +RSpec.describe Jekyll::Drops::Plugins::AIGWPolicySchema do + let(:slug) { 'openid-connect' } + let(:config_schema) { { 'type' => 'object', 'properties' => { 'issuer' => { 'type' => 'string' } } } } + let(:schema_json) { JSON.dump({ 'properties' => { 'config' => config_schema, 'protocols' => {} } }) } + + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', + { 'openidconnect.json' => '/fake/OpenidConnect.json' }) + allow(File).to receive(:read).with('/fake/OpenidConnect.json').and_return(schema_json) + end + + subject(:drop) { described_class.new(slug:) } + + describe '#as_json' do + it 'wraps config properties under properties.config' do + expect(drop.as_json).to eq({ 'properties' => { 'config' => config_schema } }) + end + + it 'excludes non-config top-level schema properties' do + expect(drop.as_json.dig('properties')).not_to have_key('protocols') + end + + it 'memoizes the result, reading the file only once' do + 2.times { drop.as_json } + expect(File).to have_received(:read).with('/fake/OpenidConnect.json').once + end + end + + describe 'slug-to-filename conversion' do + context 'with a single-word slug' do + let(:slug) { 'cors' } + + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', + { 'cors.json' => '/fake/Cors.json' }) + allow(File).to receive(:read).with('/fake/Cors.json').and_return(schema_json) + end + + it { expect(drop.as_json).to eq({ 'properties' => { 'config' => config_schema } }) } + end + + context 'with a four-segment slug' do + let(:slug) { 'ai-rate-limiting-advanced' } + + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', + { 'airatelimitingadvanced.json' => '/fake/AiRateLimitingAdvanced.json' }) + allow(File).to receive(:read).with('/fake/AiRateLimitingAdvanced.json').and_return(schema_json) + end + + it { expect(drop.as_json).to eq({ 'properties' => { 'config' => config_schema } }) } + end + end + + describe 'case-insensitive file lookup' do + context 'when the file on disk uses all-caps (ACL.json) but slug produces Acl' do + let(:slug) { 'acl' } + + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', + { 'acl.json' => '/fake/ACL.json' }) + allow(File).to receive(:read).with('/fake/ACL.json').and_return(schema_json) + end + + it 'finds and reads the file' do + expect(drop.as_json).to eq({ 'properties' => { 'config' => config_schema } }) + end + end + end + + describe 'missing schema file' do + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', {}) + end + + it 'raises ArgumentError mentioning the slug' do + expect { drop.as_json }.to raise_error(ArgumentError, /openid-connect/) + end + end +end diff --git a/spec/app/_plugins/drops/plugins/schema_spec.rb b/spec/app/_plugins/drops/plugins/schema_spec.rb new file mode 100644 index 00000000000..5cf5d2d2b2a --- /dev/null +++ b/spec/app/_plugins/drops/plugins/schema_spec.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +require 'json' +require_relative '../../../../spec_helper' + +RSpec.describe Jekyll::Drops::Plugins::Schema do + let(:plugin_slug) { 'acl' } + let(:release_number) { '3.9' } + let(:schema_dir) { File.join(described_class::SCHEMAS_BASE, release_number) } + + let(:protocols) { %w[http https] } + let(:required_fields) { %w[allow] } + let(:schema_json) do + JSON.dump( + 'properties' => { + 'protocols' => { 'items' => { 'enum' => protocols } }, + 'config' => { 'required' => required_fields, 'properties' => { 'allow' => { 'type' => 'array' } } } + } + ) + end + + let(:release) { instance_double(Jekyll::Drops::Release, number: release_number) } + let(:plugin) do + instance_double(Jekyll::PluginPages::Plugin, + slug: plugin_slug, third_party?: false, releases: [release]) + end + + subject(:schema) { described_class.new(release:, plugin:) } + + context 'with mocked FILE_INDEX' do + before do + stub_const('Jekyll::Drops::Plugins::Schema::FILE_INDEX', + { schema_dir => { 'acl.json' => "#{schema_dir}/ACL.json" } }) + allow(File).to receive(:read).with("#{schema_dir}/ACL.json").and_return(schema_json) + end + + describe '.all' do + it 'returns one Schema instance per release' do + result = described_class.all(plugin:) + expect(result.size).to eq(1) + expect(result.first).to be_a(described_class) + end + + it 'assigns the correct release to each instance' do + expect(described_class.all(plugin:).first.release).to eq(release) + end + end + + describe '#as_json' do + it 'returns the full parsed schema hash' do + expect(schema.as_json).to eq(JSON.parse(schema_json)) + end + end + + describe '#compatible_protocols' do + it { expect(schema.compatible_protocols).to eq(protocols) } + end + + describe '#required_fields' do + it { expect(schema.required_fields).to eq(required_fields) } + end + + describe 'case-insensitive file lookup' do + context 'when the file on disk uses all-caps (ACL.json) but slug produces Acl' do + it 'resolves to the correctly-cased path' do + expect(File).to receive(:read).with("#{schema_dir}/ACL.json").and_return(schema_json) + schema.as_json + end + end + end + + describe 'missing schema file' do + before do + stub_const('Jekyll::Drops::Plugins::Schema::FILE_INDEX', + { schema_dir => {} }) + end + + it 'raises ArgumentError mentioning the plugin slug and release' do + expect { schema.as_json }.to raise_error(ArgumentError, /acl.*3\.9|3\.9.*acl/i) + end + end + + describe 'third-party plugin' do + let(:plugin_folder) { '/plugins/my-plugin' } + let(:plugin) do + instance_double(Jekyll::PluginPages::Plugin, + slug: 'my-plugin', third_party?: true, + folder: plugin_folder, releases: [release]) + end + + context 'when schema.json exists' do + before do + allow(File).to receive(:exist?).with("#{plugin_folder}/schema.json").and_return(true) + allow(File).to receive(:read).with("#{plugin_folder}/schema.json").and_return(schema_json) + end + + it { expect(schema.as_json).to eq(JSON.parse(schema_json)) } + end + + context 'when schema.json is missing' do + before do + allow(File).to receive(:exist?).with("#{plugin_folder}/schema.json").and_return(false) + end + + it 'raises ArgumentError mentioning the plugin slug' do + expect { schema.as_json }.to raise_error(ArgumentError, /my-plugin/) + end + end + end + end + + describe 'FILE_INDEX lazy loading' do + let(:test_dir) { File.join(described_class::SCHEMAS_BASE, '__spec__') } + + before do + allow(Dir).to receive(:glob) + .with("#{test_dir}/*.json") + .and_return(["#{test_dir}/ACL.json", "#{test_dir}/BasicAuth.json"]) + end + + after { described_class::FILE_INDEX.delete(test_dir) } + + it 'builds a lowercase-keyed index for the directory on first access' do + expect(described_class::FILE_INDEX[test_dir]).to eq( + 'acl.json' => "#{test_dir}/ACL.json", + 'basicauth.json' => "#{test_dir}/BasicAuth.json" + ) + end + + it 'memoizes the index — Dir.glob is called only once for repeated accesses' do + 3.times { described_class::FILE_INDEX[test_dir] } + expect(Dir).to have_received(:glob).with("#{test_dir}/*.json").once + end + + it 'keeps separate caches for different version directories' do + other_dir = File.join(described_class::SCHEMAS_BASE, '__spec_other__') + allow(Dir).to receive(:glob).with("#{other_dir}/*.json").and_return([]) + described_class::FILE_INDEX[test_dir] + described_class::FILE_INDEX[other_dir] + expect(Dir).to have_received(:glob).twice + described_class::FILE_INDEX.delete(other_dir) + end + end +end diff --git a/spec/app/_plugins/generators/ai_gateway_policy/pages/base_spec.rb b/spec/app/_plugins/generators/ai_gateway_policy/pages/base_spec.rb new file mode 100644 index 00000000000..74b77aec70d --- /dev/null +++ b/spec/app/_plugins/generators/ai_gateway_policy/pages/base_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require_relative '../../../../../spec_helper' + +RSpec.describe Jekyll::AIGatewayPolicyPages::Pages::Base do + let(:policy) do + instance_double( + Jekyll::AIGatewayPolicyPages::Policy, + schema: { 'properties' => { 'config' => {} } }, + icon: 'my-policy.png' + ) + end + + let(:page) { described_class.new(policy:, file: '/app/_ai_gateway_policies/my-policy/index.md') } + + describe '.base_url' do + it { expect(described_class.base_url).to eq('/ai-gateway/policies/') } + end + + describe '#breadcrumbs' do + it { expect(page.breadcrumbs).to eq(['/ai-gateway/', '/ai-gateway/policies/']) } + end + + describe '#icon' do + context 'when policy has an icon' do + it { expect(page.icon).to eq('/assets/icons/plugins/my-policy.png') } + end + + context 'when policy has no icon' do + before { allow(policy).to receive(:icon).and_return(nil) } + + it { expect(page.icon).to be_nil } + end + end +end diff --git a/spec/app/_plugins/generators/ai_gateway_policy/pages/overview_spec.rb b/spec/app/_plugins/generators/ai_gateway_policy/pages/overview_spec.rb new file mode 100644 index 00000000000..27b51554fbc --- /dev/null +++ b/spec/app/_plugins/generators/ai_gateway_policy/pages/overview_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require_relative '../../../../../spec_helper' + +RSpec.describe Jekyll::AIGatewayPolicyPages::Pages::Overview do + let(:policy) do + instance_double( + Jekyll::AIGatewayPolicyPages::Policy, + slug: 'my-policy', + metadata: { 'title' => 'KONG', 'scopes' => %w[ai-model global] }, + overview_page_class: described_class, + reference_page_class: Jekyll::AIGatewayPolicyPages::Pages::Reference, + examples: [], + latest_release_in_range: '1.0', + publish?: true, + schema: { 'properties' => { 'config' => {} } }, + icon: nil, + unreleased?: false, + min_release: nil + ) + end + + let(:file) { 'app/_ai_gateway_policies/my-policy/index.md' } + let(:page) { described_class.new(policy:, file:) } + + describe '.url' do + context 'when the policy is released' do + it { expect(described_class.url(policy)).to eq('/ai-gateway/policies/my-policy/') } + end + + context 'when the policy is unreleased' do + before do + allow(policy).to receive(:unreleased?).and_return(true) + allow(policy).to receive(:min_release).and_return('2.0') + end + + it { expect(described_class.url(policy)).to eq('/ai-gateway/policies/my-policy/2.0/') } + end + end + + describe '#layout' do + it { expect(page.layout).to eq('policies/with_aside') } + end + + describe '#content' do + it 'returns the body of the index.md file' do + allow(File).to receive(:read).with(file).and_return("---\ntitle: KONG\n---\nSome content") + expect(page.content).to eq('Some content') + end + end + + describe '#data' do + subject(:data) { page.data } + + before do + allow(File).to receive(:read).with(file).and_return("---\ntitle: KONG\n---\n") + end + + it { expect(data['title']).to eq('KONG Policy') } + it { expect(data['overview?']).to be(true) } + it { expect(data['has_overview?']).to be(false) } + it { expect(data['overview_url']).to eq('/ai-gateway/policies/my-policy/') } + it { expect(data['schema']).to eq({ 'properties' => { 'config' => {} } }) } + it { expect(data['scopes']).to eq(%w[ai-model global]) } + end +end diff --git a/spec/app/_plugins/generators/ai_gateway_policy/pages/reference_spec.rb b/spec/app/_plugins/generators/ai_gateway_policy/pages/reference_spec.rb new file mode 100644 index 00000000000..5680c6b7b4f --- /dev/null +++ b/spec/app/_plugins/generators/ai_gateway_policy/pages/reference_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require_relative '../../../../../spec_helper' + +RSpec.describe Jekyll::AIGatewayPolicyPages::Pages::Reference do + let(:policy) do + instance_double( + Jekyll::AIGatewayPolicyPages::Policy, + slug: 'my-policy', + metadata: { 'title' => 'KONG', 'faqs' => [], 'scopes' => %w[ai-model global] }, + overview_page_class: Jekyll::AIGatewayPolicyPages::Pages::Overview, + reference_page_class: described_class, + examples: [], + latest_release_in_range: '1.0', + publish?: true, + schema: { 'properties' => { 'config' => {} } }, + icon: nil, + unreleased?: false, + min_release: nil + ) + end + + let(:page) { described_class.new(policy:, file: '/app/_ai_gateway_policies/my-policy/reference.md') } + + describe '.url' do + context 'when the policy is released' do + it { expect(described_class.url(policy)).to eq('/ai-gateway/policies/my-policy/reference/') } + end + + context 'when the policy is unreleased' do + before do + allow(policy).to receive(:unreleased?).and_return(true) + allow(policy).to receive(:min_release).and_return('2.0') + end + + it { expect(described_class.url(policy)).to eq('/ai-gateway/policies/my-policy/reference/2.0/') } + end + end + + describe '#layout' do + it { expect(page.layout).to eq('ai_gateway_policies/reference') } + end + + describe '#markdown_content' do + it { expect(page.markdown_content).to eq(described_class::MARKDOWN_CONTENT) } + end + + describe '#data' do + subject(:data) { page.data } + + it { expect(data['title']).to eq('KONG Policy') } + it { expect(data['has_overview?']).to be(false) } + it { expect(data['reference_type']).to eq('base') } + it { expect(data['content_type']).to eq('reference') } + it { expect(data['reference?']).to be(true) } + it { expect(data['toc']).to be(false) } + it { expect(data['versioned']).to be(false) } + it { expect(data['schema']).to eq({ 'properties' => { 'config' => {} } }) } + it { expect(data['overview_url']).to eq('/ai-gateway/policies/my-policy/') } + it { expect(data).not_to have_key('faqs') } + it { expect(data['scopes']).to eq(%w[ai-model global]) } + end +end diff --git a/spec/app/_plugins/generators/ai_gateway_policy/policy_spec.rb b/spec/app/_plugins/generators/ai_gateway_policy/policy_spec.rb new file mode 100644 index 00000000000..02ef40d2795 --- /dev/null +++ b/spec/app/_plugins/generators/ai_gateway_policy/policy_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require_relative '../../../../spec_helper' + +RSpec.describe Jekyll::AIGatewayPolicyPages::Policy do + let(:folder) { '/app/_ai_gateway_policies/my-policy' } + let(:slug) { 'my-policy' } + + let(:plugin_metadata) do + { 'title' => 'My Policy', 'name' => 'my-policy', 'description' => 'A policy', 'icon' => 'my-policy.svg' } + end + let(:plugin_drop) { double('PluginDrop', metadata: plugin_metadata) } + + let(:config_schema) { { 'type' => 'object', 'properties' => {} } } + let(:schema_json) { JSON.dump({ 'properties' => { 'config' => config_schema } }) } + + let(:api_plugin_page) do + instance_double(Jekyll::PluginPages::Pages::Overview, data: { 'plugin' => plugin_drop }) + end + + let(:site_config) { { 'ai_gateway_policies' => { 'metadata' => { 'keep' => %w[title name description icon] } } } } + let(:scopes_data) { [{ 'name' => slug, 'scopes' => %w[models consumers global] }] } + let(:site) do + instance_double( + Jekyll::Site, + data: { + 'kong_plugins' => { slug => api_plugin_page }, + 'policies' => { 'ai-gateway' => { 'scopes' => scopes_data } } + }, + config: site_config + ) + end + + let(:release_info) do + instance_double( + Jekyll::ReleaseInfo::Product, + releases: [], + latest_available_release: nil, + latest_release_in_range: nil, + unreleased?: false, + min_release: nil + ) + end + + before do + stub_const('Jekyll::Drops::Plugins::AIGWPolicySchema::FILE_INDEX', + { 'mypolicy.json' => '/fake/MyPolicy.json' }) + allow(Jekyll).to receive(:sites).and_return([site]) + allow(Jekyll::ReleaseInfo::Product).to receive(:new).and_return(release_info) + allow(File).to receive(:read).and_call_original + allow(File).to receive(:read).with(File.join(folder, 'index.md')) + .and_return("---\nproducts:\n - ai-gateway\n---\n") + allow(File).to receive(:read).with('/fake/MyPolicy.json').and_return(schema_json) + end + + subject(:policy) { described_class.new(folder:, slug:) } + + describe '#schema' do + it { expect(policy.schema).to be_a(Jekyll::Drops::Plugins::AIGWPolicySchema) } + + it 'returns a Schema whose as_json wraps the config properties from the schema file' do + expect(policy.schema.as_json).to eq({ 'properties' => { 'config' => config_schema } }) + end + end + + describe '#examples' do + it { expect(policy.examples).to eq([]) } + end + + describe '#metadata' do + subject(:metadata) { policy.metadata } + + it 'includes plugin metadata sliced by the configured keep keys' do + expect(metadata).to include('title' => 'My Policy', 'name' => 'my-policy', + 'description' => 'A policy', 'icon' => 'my-policy.svg') + end + + it 'does not include plugin metadata keys outside the keep list' do + plugin_metadata['unlisted_key'] = 'should not appear' + expect(metadata).not_to have_key('unlisted_key') + end + + it 'includes the schema as an AIGWPolicySchema object backed by the schema file' do + expect(metadata['schema']).to be_a(Jekyll::Drops::Plugins::AIGWPolicySchema) + expect(metadata['schema'].as_json).to eq({ 'properties' => { 'config' => config_schema } }) + end + + it 'merges frontmatter from index.md via super' do + expect(metadata['products']).to eq(['ai-gateway']) + end + + it 'includes the scopes for the matching slug' do + expect(metadata['scopes']).to eq(%w[ai-model ai-consumer global]) + end + + context 'when no scopes entry matches the slug' do + let(:scopes_data) { [{ 'name' => 'other-policy', 'scopes' => %w[ai-model] }] } + + it { expect(metadata['scopes']).to eq([]) } + end + + context 'when scopes data is absent' do + let(:scopes_data) { nil } + + it { expect(metadata['scopes']).to eq([]) } + end + end +end diff --git a/spec/app/_plugins/generators/data/llm_metadata_spec.rb b/spec/app/_plugins/generators/data/llm_metadata_spec.rb index 94d0c4fc8d7..0c93c5132cd 100644 --- a/spec/app/_plugins/generators/data/llm_metadata_spec.rb +++ b/spec/app/_plugins/generators/data/llm_metadata_spec.rb @@ -133,6 +133,17 @@ it { expect(parsed.keys).not_to include('works_on') } end + context 'when the page is an AI Gateway policy' do + let(:page_url) { '/ai-gateway/policies/my-policy/' } + let(:page_data) { base_page_data.merge('content_type' => 'policy', 'scopes' => %w[ai-model ai-consumer global]) } + + it { expect(parsed['scopes']).to eq(%w[ai-model ai-consumer global]) } + end + + context 'when scopes are absent' do + it { expect(parsed.keys).not_to include('scopes') } + end + context 'when tiers are present' do let(:page_data) { base_page_data.merge('tiers' => { 'gateway' => 'enterprise' }) } it { expect(parsed['tiers']).to eq({ 'Kong Gateway' => 'Enterprise' }) } diff --git a/spec/app/_plugins/generators/data/title/base_spec.rb b/spec/app/_plugins/generators/data/title/base_spec.rb index a4db9bb6299..eb5a5d521df 100644 --- a/spec/app/_plugins/generators/data/title/base_spec.rb +++ b/spec/app/_plugins/generators/data/title/base_spec.rb @@ -30,6 +30,11 @@ it { expect(subject).to be_a(Jekyll::Data::Title::Policy) } end + context 'when URL starts with /ai-gateway/policies/' do + let(:page_url) { '/ai-gateway/policies/some-policy/' } + it { expect(subject).to be_a(Jekyll::Data::Title::Policy) } + end + context 'when content_type is reference' do let(:page_url) { '/gateway/reference/cli/' } let(:page_data) { { 'content_type' => 'reference' } } diff --git a/spec/app/_plugins/generators/release_map_loader_spec.rb b/spec/app/_plugins/generators/release_map_loader_spec.rb index f8a185c9614..800021e6212 100644 --- a/spec/app/_plugins/generators/release_map_loader_spec.rb +++ b/spec/app/_plugins/generators/release_map_loader_spec.rb @@ -12,7 +12,7 @@ 'releases' => [{ 'release' => '2.0', 'latest' => true }, { 'release' => '1.0' }] } } } end - let(:site) { instance_double(Jekyll::Site, pages: pages, documents: documents, data:) } + let(:site) { instance_double(Jekyll::Site, pages: pages, documents: documents, data:, config: {}) } let(:pages) { [] } let(:documents) { [] } diff --git a/spec/app/_plugins/hooks/site_post_write_spec.rb b/spec/app/_plugins/hooks/site_post_write_spec.rb new file mode 100644 index 00000000000..8b61f1205ef --- /dev/null +++ b/spec/app/_plugins/hooks/site_post_write_spec.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe LlmsTxtWriter do + let(:site_data) do + { + 'products' => { + 'gateway' => { 'name' => 'Kong Gateway' }, + 'ai-gateway' => { 'name' => 'AI Gateway' }, + 'konnect' => { 'name' => 'Konnect' } + }, + 'tools' => { 'deck' => { 'name' => 'decK' } } + } + end + let(:all_pages) { [] } + + let(:site) do + instance_double(Jekyll::Site, dest: '/fake/dest', data: site_data).tap do |s| + allow(s).to receive(:config).and_return( + 'markdown_pages_to_render' => all_pages, + 'liquid' => { 'strict_filters' => false, 'strict_variables' => false } + ) + allow(s).to receive(:site_payload).and_return( + 'site' => { 'links' => { 'web' => 'https://developer.konghq.com' } } + ) + end + end + + let(:writer) { described_class.new(site) } + + describe '#pages' do + context 'when a page has canonical? == false' do + let(:all_pages) do + [ + build_page(url: '/visible/', data: {}), + build_page(url: '/not-canonical/', data: { 'canonical?' => false }) + ] + end + + it 'excludes that page' do + expect(writer.pages.map(&:url)).to contain_exactly('/visible/') + end + end + + context 'when canonical? is nil' do + let(:all_pages) { [build_page(url: '/nil-canonical/', data: { 'canonical?' => nil })] } + + it 'includes the page' do + expect(writer.pages.map(&:url)).to include('/nil-canonical/') + end + end + + context 'with multiple pages in unsorted order' do + let(:all_pages) { [build_page(url: '/b/'), build_page(url: '/a/')] } + + it 'returns pages sorted by URL' do + expect(writer.pages.map(&:url)).to eq(['/a/', '/b/']) + end + end + end + + describe '#api_pages' do + let(:by_content_type) { build_page(url: '/api/konnect/dev-portal/v2/', data: { 'content_type' => 'api' }) } + let(:by_layout) { build_page(url: '/api/konnect/dev-portal/v2/errors/', data: { 'layout' => 'api/errors' }) } + let(:other) { build_page(url: '/other/', data: { 'content_type' => 'reference' }) } + let(:all_pages) { [by_content_type, by_layout, other] } + + it 'selects pages with content_type api' do + expect(writer.api_pages).to include(by_content_type) + end + + it 'selects pages with layout api/errors' do + expect(writer.api_pages).to include(by_layout) + end + + it 'excludes other pages' do + expect(writer.api_pages).not_to include(other) + end + end + + describe '#plugin_pages' do + let(:gateway_plugin) { build_page(url: '/plugins/acme/', data: { 'plugin?' => true, 'products' => ['gateway'] }) } + let(:aigw_policy) do + build_page(url: '/ai-gateway/policies/acme/', data: { 'plugin?' => true, 'products' => ['ai-gateway'] }) + end + let(:non_plugin) { build_page(url: '/gateway/', data: { 'products' => ['gateway'] }) } + let(:all_pages) { [gateway_plugin, aigw_policy, non_plugin] } + + it 'selects only gateway plugins' do + expect(writer.plugin_pages).to contain_exactly(gateway_plugin) + end + end + + describe '#ai_gateway_policy_pages' do + let(:aigw_only) do + build_page(url: '/ai-gateway/policies/acme/', data: { 'plugin?' => true, 'products' => ['ai-gateway'] }) + end + let(:aigw_and_gw) do + build_page(url: '/plugins/ai-proxy/', data: { 'plugin?' => true, 'products' => %w[gateway ai-gateway] }) + end + let(:gateway_only) { build_page(url: '/plugins/acme/', data: { 'plugin?' => true, 'products' => ['gateway'] }) } + let(:all_pages) { [aigw_only, aigw_and_gw, gateway_only] } + + it 'selects only pages whose products is exactly ["ai-gateway"]' do + expect(writer.ai_gateway_policy_pages).to contain_exactly(aigw_only) + end + end + + describe '#how_to_pages' do + let(:how_to) { build_page(url: '/how-to/get-started/', data: { 'content_type' => 'how_to' }) } + let(:other) { build_page(url: '/other/', data: { 'content_type' => 'reference' }) } + let(:all_pages) { [how_to, other] } + + it { expect(writer.how_to_pages).to contain_exactly(how_to) } + end + + describe '#cookbook_pages' do + let(:cookbook) { build_page(url: '/cookbooks/mock/', data: { 'content_type' => 'cookbook' }) } + let(:other) { build_page(url: '/other/', data: { 'content_type' => 'reference' }) } + let(:all_pages) { [cookbook, other] } + + it { expect(writer.cookbook_pages).to contain_exactly(cookbook) } + end + + describe '#docs' do + context 'with pages from different products' do + let(:gw_page) { build_page(url: '/gateway/foo/', data: { 'products' => ['gateway'] }) } + let(:konnect_page) { build_page(url: '/konnect/bar/', data: { 'products' => ['konnect'] }) } + let(:aigw_page) { build_page(url: '/ai-gateway/baz/', data: { 'products' => ['ai-gateway'] }) } + + let(:all_pages) { [gw_page, konnect_page, aigw_page] } + + it 'groups pages by product and sorts groups alphabetically by resolved name' do + expect(writer.docs.map { |g| g['name'] }).to eq(['AI Gateway', 'Kong Gateway', 'Konnect']) + end + end + + context 'when a page has a tool but no product' do + let(:page) { build_page(url: '/deck/foo/', data: { 'tools' => ['deck'] }) } + let(:all_pages) { [page] } + + it 'groups the page under the resolved tool name' do + group = writer.docs.find { |g| g['name'] == 'decK' } + expect(group&.dig('pages')).to include(page) + end + end + + context 'when a page has no product or tool' do + let(:page) { build_page(url: '/misc/', data: {}) } + let(:all_pages) { [page] } + + it 'places the page in an Other group sorted last' do + expect(writer.docs.last['name']).to eq('Other') + expect(writer.docs.last['pages']).to include(page) + end + end + end + + describe '#resolve_name' do + it { expect(writer.resolve_name('gateway')).to eq('Kong Gateway') } + it { expect(writer.resolve_name('deck')).to eq('decK') } + end +end diff --git a/spec/integration/llms_txt_writer_spec.rb b/spec/integration/llms_txt_writer_spec.rb new file mode 100644 index 00000000000..e392117fe47 --- /dev/null +++ b/spec/integration/llms_txt_writer_spec.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe LlmsTxtWriter, 'template rendering' do + let(:web_base) { 'https://developer.konghq.com' } + let(:all_pages) { [] } + let(:site_data) do + { + 'products' => { + 'gateway' => { 'name' => 'Kong Gateway' }, + 'ai-gateway' => { 'name' => 'AI Gateway' } + }, + 'tools' => {} + } + end + + let(:site) do + instance_double(Jekyll::Site, dest: '/fake/dest', data: site_data).tap do |s| + allow(s).to receive(:config).and_return( + 'markdown_pages_to_render' => all_pages, + 'liquid' => { 'strict_filters' => false, 'strict_variables' => false } + ) + allow(s).to receive(:site_payload).and_return( + 'site' => { 'links' => { 'web' => web_base } } + ) + end + end + + let(:rendered) do + captured = nil + allow(File).to receive(:write).with(File.join('/fake/dest', 'llms.txt'), anything) do |_, content| + captured = content + end + described_class.process(site) + captured + end + + # Returns the body of a named ## section, up to (but not including) the next ##. + def section(output, name) + output[/^## #{Regexp.escape(name)}\n(.*?)(?=^## |\z)/m, 1] || '' + end + + context 'with an API page' do + let(:all_pages) do + [build_page(url: '/api/foo/', llm_title: 'Foo API', description: 'Foo API description', + data: { 'content_type' => 'api' })] + end + + it 'renders the page inside the API Reference section' do + expect(section(rendered, 'API Reference')).to include( + '[Foo API](https://developer.konghq.com/api/foo/): Foo API description' + ) + end + end + + context 'with a how-to page' do + let(:all_pages) do + [build_page(url: '/how-to/foo/', llm_title: 'How to Foo', description: 'Do foo.', + data: { 'content_type' => 'how_to' })] + end + + it 'renders the page inside the How-To Guides section' do + expect(section(rendered, 'How-To Guides')).to include( + '[How to Foo](https://developer.konghq.com/how-to/foo/): Do foo.' + ) + end + end + + context 'with a cookbook page' do + let(:all_pages) do + [build_page(url: '/cookbook/bar/', llm_title: 'Bar Cookbook', description: 'Bar recipe.', + data: { 'content_type' => 'cookbook' })] + end + + it 'renders the page inside the Cookbooks section' do + expect(section(rendered, 'Cookbooks')).to include( + '[Bar Cookbook](https://developer.konghq.com/cookbook/bar/): Bar recipe.' + ) + end + end + + context 'with a gateway plugin page' do + let(:all_pages) do + [build_page(url: '/plugins/my-plugin/', llm_title: 'My Plugin', description: 'A plugin.', + data: { 'plugin?' => true, 'products' => ['gateway'] })] + end + + it 'renders the page inside the API Gateway Plugins section' do + expect(section(rendered, 'API Gateway Plugins')).to include( + '[My Plugin](https://developer.konghq.com/plugins/my-plugin/): A plugin.' + ) + end + end + + context 'with an AI Gateway policy page' do + let(:all_pages) do + [build_page(url: '/ai-gateway/policies/my-policy/', llm_title: 'My Policy', description: 'A policy.', + data: { 'plugin?' => true, 'products' => ['ai-gateway'] })] + end + + it 'renders the page inside the AI Gateway Policies section' do + expect(section(rendered, 'AI Gateway Policies')).to include( + '[My Policy](https://developer.konghq.com/ai-gateway/policies/my-policy/): A policy.' + ) + end + end + + context 'with a regular doc page' do + let(:all_pages) do + [build_page(url: '/gateway/install/', llm_title: 'Install Gateway', description: 'Install it.', + data: { 'products' => ['gateway'] })] + end + + it 'renders the page inside the product section' do + expect(section(rendered, 'Kong Gateway')).to include( + '[Install Gateway](https://developer.konghq.com/gateway/install/)' + ) + end + end + + context 'with a non-canonical page alongside a canonical one' do + let(:all_pages) do + [ + build_page(url: '/a/', llm_title: 'Visible', description: 'Shown.', + data: { 'content_type' => 'how_to' }), + build_page(url: '/b/', llm_title: 'Hidden', description: 'Not shown.', + data: { 'content_type' => 'how_to', 'canonical?' => false }) + ] + end + + it 'includes the canonical page and omits the non-canonical one' do + how_to = section(rendered, 'How-To Guides') + expect(how_to).to include('Visible') + expect(how_to).not_to include('Hidden') + end + end + + context 'with a doc page that has no description' do + let(:all_pages) do + [build_page(url: '/gateway/foo/', llm_title: 'No Desc', description: nil, + data: { 'products' => ['gateway'] })] + end + + it 'renders the link without a colon separator' do + gw = section(rendered, 'Kong Gateway') + expect(gw).to include('[No Desc](https://developer.konghq.com/gateway/foo/)') + expect(gw).not_to include('[No Desc](https://developer.konghq.com/gateway/foo/):') + end + end +end diff --git a/spec/support/page_double.rb b/spec/support/page_double.rb new file mode 100644 index 00000000000..ce86464488f --- /dev/null +++ b/spec/support/page_double.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +def build_page(url:, llm_title: nil, description: nil, data: {}) + title = llm_title || url + desc = description + liquid_hash = { 'llm_title' => title, 'url' => url, 'description' => desc } + + Object.new.tap do |p| + p.define_singleton_method(:url) { url } + p.define_singleton_method(:data) { data } + p.define_singleton_method(:[]) { |key| liquid_hash[key] } + p.define_singleton_method(:to_liquid) { liquid_hash } + end +end diff --git a/tools/aigw-policy-scopes/README.md b/tools/aigw-policy-scopes/README.md new file mode 100644 index 00000000000..1deb56241ca --- /dev/null +++ b/tools/aigw-policy-scopes/README.md @@ -0,0 +1,44 @@ +# aigw-policy-scopes + +Fetches the available policies (and their scopes) for an AI Gateway instance from the Konnect API and writes them to `app/_data/policies/ai-gateway/scopes.json` so the site can render them. + +## Usage + +```bash +node tools/aigw-policy-scopes/fetch-scopes.js \ + --konnect-token \ + --aigw-id \ + [--domain com] +``` + +Or via the npm script: + +```bash +cd tools/aigw-policy-scopes +npm run fetch-scopes -- --konnect-token --aigw-id +``` + +### Arguments + +| Flag | Env var | Required | Default | Description | +|------|---------|----------|---------|-------------| +| `--konnect-token` | `KONNECT_TOKEN` | yes | — | Konnect personal access token (sent as `Authorization: Bearer`). | +| `--aigw-id` | `AIGW_ID` | yes | — | The AI Gateway instance ID. | +| `--domain` | `KONNECT_DOMAIN` | no | `com` | The Konnect TLD (`com`, `tech`, etc.). The host is built as `us.api.konghq.`. | + +## What it does + +1. Calls `GET https://us.api.konghq./v1/ai-gateways//available-policies`. +2. Extracts the `data` array from the response. +3. Writes it (pretty-printed JSON) to `app/_data/policies/ai-gateway/scopes.json`, creating the directory if needed. + +The resulting file looks like: + +```json +[ + { + "name": "ace", + "scopes": ["models", "mcp-servers", "agents", "consumers", "consumer-groups", "global"] + } +] +``` diff --git a/tools/aigw-policy-scopes/fetch-scopes.js b/tools/aigw-policy-scopes/fetch-scopes.js new file mode 100644 index 00000000000..8792fc5ce25 --- /dev/null +++ b/tools/aigw-policy-scopes/fetch-scopes.js @@ -0,0 +1,69 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +function parseArgs(argv) { + const args = {}; + for (let i = 2; i < argv.length; i++) { + const arg = argv[i]; + if (arg.startsWith('--')) { + const key = arg.slice(2); + const eq = key.indexOf('='); + if (eq !== -1) { + args[key.slice(0, eq)] = key.slice(eq + 1); + } else { + args[key] = argv[++i]; + } + } + } + return args; +} + +(async () => { + const args = parseArgs(process.argv); + const konnectToken = args['konnect-token'] || process.env.KONNECT_TOKEN; + const aigwId = args['aigw-id'] || process.env.AIGW_ID; + const domain = args['domain'] || process.env.KONNECT_DOMAIN || 'com'; + + if (!konnectToken) { + console.error('Error: --konnect-token is required (or set KONNECT_TOKEN)'); + process.exit(1); + } + if (!aigwId) { + console.error('Error: --aigw-id is required (or set AIGW_ID)'); + process.exit(1); + } + + const url = `https://us.api.konghq.${domain}/v1/ai-gateways/${aigwId}/available-policies`; + + try { + const response = await fetch(url, { + method: 'GET', + headers: { + 'Accept': 'application/json, application/problem+json', + 'Authorization': `Bearer ${konnectToken}`, + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + const body = await response.text(); + throw new Error(`API error ${response.status} ${response.statusText}: ${body}`); + } + + const payload = await response.json(); + const data = Array.isArray(payload?.data) ? payload.data : []; + + const outputPath = path.resolve(__dirname, '../../app/_data/policies/ai-gateway/scopes.json'); + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + fs.writeFileSync(outputPath, JSON.stringify(data, null, 2) + '\n', 'utf8'); + + console.log(`Wrote ${data.length} policies to ${path.relative(process.cwd(), outputPath)}`); + } catch (error) { + console.error(`Error: ${error.message}`); + process.exit(1); + } +})(); diff --git a/tools/aigw-policy-scopes/package-lock.json b/tools/aigw-policy-scopes/package-lock.json new file mode 100644 index 00000000000..e2ebb78dd7c --- /dev/null +++ b/tools/aigw-policy-scopes/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "aigw-policy-scopes", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aigw-policy-scopes", + "version": "1.0.0", + "license": "MIT" + } + } +} diff --git a/tools/aigw-policy-scopes/package.json b/tools/aigw-policy-scopes/package.json new file mode 100644 index 00000000000..39271481422 --- /dev/null +++ b/tools/aigw-policy-scopes/package.json @@ -0,0 +1,10 @@ +{ + "name": "aigw-policy-scopes", + "version": "1.0.0", + "description": "Fetch AI Gateway available policy scopes from Konnect and save to app/_data/policies/ai-gateway/scopes.json", + "type": "module", + "scripts": { + "fetch-scopes": "node fetch-scopes.js" + }, + "license": "MIT" +} diff --git a/tools/automated-tests/config/expected_failures.yaml b/tools/automated-tests/config/expected_failures.yaml index 670fdf9275c..cebb83a6a6f 100644 --- a/tools/automated-tests/config/expected_failures.yaml +++ b/tools/automated-tests/config/expected_failures.yaml @@ -1,50 +1,50 @@ -input/instructions/how-to/set-up-ai-proxy-advanced-with-anthropic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-with-anthropic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/transform-a-client-request-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." -input/instructions/how-to/transform-a-response-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 201, got: 400." -input/instructions/how-to/set-up-ai-proxy-with-openai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-advanced-with-openai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/mcp/secure-mcp-traffic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/compress-llm-prompts/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code undefined, got: 400." -input/instructions/how-to/protect-sensitive-information-output-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/protect-sensitive-information-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/how-to/use-ai-semantic-prompt-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/ai-gateway/get-started/on-prem/gateway.yaml: "Expected: request http://localhost:8000/chat to have status code 200, got: 401." -input/instructions/how-to/create-a-complex-ai-chat-history/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/send-asynchronous-llm-requests/on-prem/gateway.yaml: "Expected: request http://localhost:8000/files to have status code 200, got: 400." -input/instructions/how-to/set-up-ai-proxy-advanced-with-ollama/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/set-up-ai-proxy-with-ollama/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/use-ai-prompt-template-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/use-ai-prompt-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/use-azure-ai-content-safety/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." -input/instructions/how-to/use-ai-semantic-response-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/use-custom-function-for-ai-rate-limiting/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/use-semantic-load-balancing/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/how-to/use-ai-aws-guardrails-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/how-to/use-ai-rag-injector-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8001/ai-rag-injector/b924e3e8-7893-4706-aacb-e75793a1d2e9/ingest_chunk to have status code 200, got: 500." -input/instructions/how-to/use-ai-gcp-model-armor-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." -input/instructions/how-to/compare-llm-models-accuracy/on-prem/gateway.yaml: "Expected: request 1 to have status code 200, got: 401." -input/instructions/how-to/use-agno-with-ai-proxy/on-prem/gateway.yaml: "Expected: command to have return code 0, got: 1" -input/instructions/how-to/use-langchain-with-ai-proxy/on-prem/gateway.yaml: "Expected: command to have return code 0, got: 1" -input/instructions/how-to/azure-batches/on-prem/gateway.yaml: "Expected: request http://localhost:8000/files to have status code 201, got: 400." -input/instructions/how-to/set-up-ai-proxy-for-image-generation-with-grok/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 201, got: 400." -input/instructions/how-to/set-up-ai-proxy-advanced-with-cerebras/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-advanced-with-aws-bedrock/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 403." -input/instructions/how-to/set-up-ai-proxy-advanced-with-cohere/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-advanced-with-huggingface/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-with-aws-bedrock/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 403." -input/instructions/how-to/set-up-ai-proxy-with-cerebras/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-with-cohere/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-with-huggingface/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-advanced-with-vertex-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/how-to/set-up-ai-proxy-with-vertex-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." -input/instructions/how-to/set-up-ai-proxy-with-gemini/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." -input/instructions/how-to/set-up-ai-proxy-advanced-with-gemini/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." -input/instructions/how-to/use-ai-custom-guardrail-with-mistral/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." -input/instructions/how-to/set-up-ai-proxy-with-ollama-qwen/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/set-up-ai-proxy-advanced-with-ollama-qwen/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/set-up-ai-proxy-with-databricks/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/set-up-ai-proxy-advanced-with-databricks/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." -input/instructions/how-to/set-up-ai-proxy-with-deepseek/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/set-up-ai-proxy-advanced-with-deepseek/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." -input/instructions/how-to/route-requests-by-model-alias/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-anthropic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-anthropic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/transform-a-client-request-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." +input/instructions/ai-gateway/v1/how-to/transform-a-response-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 201, got: 400." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-openai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-openai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/mcp/secure-mcp-traffic/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/compress-llm-prompts/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code undefined, got: 400." +input/instructions/ai-gateway/v1/how-to/protect-sensitive-information-output-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/protect-sensitive-information-with-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/use-ai-semantic-prompt-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/get-started/on-prem/gateway.yaml: 'Expected: request http://localhost:8000/chat to have status code 200, got: 401.' +input/instructions/ai-gateway/v1/how-to/create-a-complex-ai-chat-history/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/send-asynchronous-llm-requests/on-prem/gateway.yaml: "Expected: request http://localhost:8000/files to have status code 200, got: 400." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-ollama/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-ollama/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/use-ai-prompt-template-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/use-ai-prompt-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/use-azure-ai-content-safety/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." +input/instructions/ai-gateway/v1/how-to/use-ai-semantic-response-guard-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/use-custom-function-for-ai-rate-limiting/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/use-semantic-load-balancing/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/use-ai-aws-guardrails-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/use-ai-rag-injector-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8001/ai-rag-injector/b924e3e8-7893-4706-aacb-e75793a1d2e9/ingest_chunk to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/use-ai-gcp-model-armor-plugin/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." +input/instructions/ai-gateway/v1/how-to/compare-llm-models-accuracy/on-prem/gateway.yaml: "Expected: request 1 to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/use-agno-with-ai-proxy/on-prem/gateway.yaml: "Expected: command to have return code 0, got: 1" +input/instructions/ai-gateway/v1/how-to/use-langchain-with-ai-proxy/on-prem/gateway.yaml: "Expected: command to have return code 0, got: 1" +input/instructions/ai-gateway/v1/how-to/azure-batches/on-prem/gateway.yaml: "Expected: request http://localhost:8000/files to have status code 201, got: 400." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-for-image-generation-with-grok/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 201, got: 400." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-cerebras/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-aws-bedrock/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 403." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-cohere/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-huggingface/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-aws-bedrock/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 403." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-cerebras/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-cohere/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-huggingface/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-vertex-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-vertex-ai/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 500." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-gemini/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-gemini/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 400." +input/instructions/ai-gateway/v1/how-to/use-ai-custom-guardrail-with-mistral/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 400, got: 500." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-ollama-qwen/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-ollama-qwen/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-databricks/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-databricks/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 503." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-with-deepseek/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/set-up-ai-proxy-advanced-with-deepseek/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." +input/instructions/ai-gateway/v1/how-to/route-requests-by-model-alias/on-prem/gateway.yaml: "Expected: request http://localhost:8000/anything to have status code 200, got: 401." diff --git a/tools/automated-tests/instructions/extractor.js b/tools/automated-tests/instructions/extractor.js index f4e14391d22..ca312f9ca95 100644 --- a/tools/automated-tests/instructions/extractor.js +++ b/tools/automated-tests/instructions/extractor.js @@ -182,10 +182,12 @@ function deriveProduct(setup, products) { // String value if (setupEntry === "konnect") { // For konnect, determine the product from the products list - if (products.includes("ai-gateway")) { + // Special case for ai-gateway v1 + if (products.includes("ai-gateway") && products.includes("gateway")) { + return "gateway"; + } else if (products.includes("ai-gateway")) { return "ai-gateway"; - } - if (products.includes("event-gateway")) { + } else if (products.includes("event-gateway")) { return "event-gateway"; } return "gateway"; diff --git a/tools/frontmatter-validator/index.js b/tools/frontmatter-validator/index.js index efda96331be..229dd36dc03 100644 --- a/tools/frontmatter-validator/index.js +++ b/tools/frontmatter-validator/index.js @@ -27,6 +27,7 @@ async function validateFrontmatters() { "app/_layouts/**", "app/_includes/**", "app/_kong_plugins/**/changelog.md", + "app/_ai_gateway_policies/*/index.md", "app/_kong_plugins/**/reference.md", "app/_api/**/*.md", "app/_references/**/*.md",