zuplo 7.2.3 → 7.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ai-gateway/integrations/ai-sdk.mdx +3 -2
- package/docs/ai-gateway/integrations/claude-code.mdx +3 -2
- package/docs/ai-gateway/integrations/codex.mdx +7 -5
- package/docs/ai-gateway/integrations/goose.mdx +4 -3
- package/docs/ai-gateway/integrations/langchain.mdx +3 -3
- package/docs/ai-gateway/integrations/openai.mdx +3 -3
- package/docs/ai-gateway/policies/overview.mdx +3 -17
- package/docs/ai-gateway/universal-api.mdx +4 -3
- package/docs/caching/custom-caching-policy.mdx +1 -1
- package/docs/caching/gateway-caching.mdx +3 -3
- package/docs/caching/overview.mdx +10 -10
- package/docs/dedicated/akamai/ai-powered-applications.mdx +2 -2
- package/docs/dev-portal/zudoku/configuration/search.md +5 -0
- package/docs/dev-portal/zudoku/openapi-extensions/x-mcp-server.md +30 -0
- package/docs/policies/_index.md +12 -7
- package/docs/policies/ai-gateway-auth-v2-inbound/doc.md +168 -0
- package/docs/policies/ai-gateway-auth-v2-inbound/intro.md +10 -0
- package/docs/policies/ai-gateway-auth-v2-inbound/schema.json +74 -0
- package/docs/policies/ai-gateway-configuration-executor-v2-inbound/doc.md +442 -0
- package/docs/policies/ai-gateway-configuration-executor-v2-inbound/intro.md +14 -0
- package/docs/policies/ai-gateway-configuration-executor-v2-inbound/schema.json +60 -0
- package/docs/policies/ai-gateway-configuration-loader-v2-inbound/doc.md +105 -0
- package/docs/policies/ai-gateway-configuration-loader-v2-inbound/intro.md +6 -0
- package/docs/policies/ai-gateway-configuration-loader-v2-inbound/schema.json +60 -0
- package/docs/policies/ai-gateway-dlp-inbound/doc.md +127 -0
- package/docs/policies/ai-gateway-dlp-inbound/intro.md +5 -0
- package/docs/policies/ai-gateway-dlp-inbound/schema.json +4050 -0
- package/docs/policies/ai-gateway-fallback-model-v2-inbound/doc.md +10 -2
- package/docs/policies/ai-gateway-fallback-model-v2-inbound/intro.md +2 -2
- package/docs/policies/ai-gateway-fallback-model-v2-inbound/schema.json +22 -8
- package/docs/policies/ai-gateway-metering-v2-inbound/doc.md +19 -16
- package/docs/policies/ai-gateway-metering-v2-inbound/intro.md +9 -0
- package/docs/policies/ai-gateway-metering-v2-inbound/schema.json +20 -24
- package/docs/policies/ai-gateway-model-filtering-v2-inbound/doc.md +6 -5
- package/docs/policies/ai-gateway-model-filtering-v2-inbound/intro.md +2 -2
- package/docs/policies/ai-gateway-model-filtering-v2-inbound/schema.json +17 -3
- package/docs/policies/ai-gateway-semantic-cache-v2-inbound/doc.md +72 -0
- package/docs/policies/ai-gateway-semantic-cache-v2-inbound/intro.md +9 -0
- package/docs/policies/ai-gateway-semantic-cache-v2-inbound/schema.json +120 -0
- package/docs/policies/akamai-ai-firewall-v2-inbound/doc.md +87 -0
- package/docs/policies/akamai-ai-firewall-v2-inbound/intro.md +10 -0
- package/docs/policies/{akamai-ai-firewall → akamai-ai-firewall-v2-inbound}/schema.json +36 -9
- package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +1 -0
- package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +1 -0
- package/docs/policies/amberflo-metering-inbound/schema.json +1 -0
- package/docs/policies/api-key-inbound/schema.json +1 -0
- package/docs/policies/audit-log-inbound/schema.json +1 -0
- package/docs/policies/auth0-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/authzen-inbound/schema.json +1 -0
- package/docs/policies/axiomatics-authz-inbound/schema.json +1 -0
- package/docs/policies/basic-auth-inbound/schema.json +1 -0
- package/docs/policies/bot-detection-inbound/schema.json +1 -0
- package/docs/policies/brownout-inbound/schema.json +1 -0
- package/docs/policies/caching-inbound/schema.json +1 -0
- package/docs/policies/cdn-cache-control-outbound/schema.json +1 -0
- package/docs/policies/change-method-inbound/schema.json +1 -0
- package/docs/policies/clear-headers-inbound/schema.json +1 -0
- package/docs/policies/clear-headers-outbound/schema.json +1 -0
- package/docs/policies/clerk-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/cognito-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/comet-opik-tracing-v2-inbound/doc.md +78 -0
- package/docs/policies/comet-opik-tracing-v2-inbound/intro.md +10 -0
- package/docs/policies/{comet-opik-tracing-inbound → comet-opik-tracing-v2-inbound}/schema.json +40 -5
- package/docs/policies/complex-rate-limit-inbound/schema.json +1 -0
- package/docs/policies/composite-inbound/schema.json +1 -0
- package/docs/policies/composite-outbound/schema.json +1 -0
- package/docs/policies/curity-phantom-token-inbound/schema.json +1 -0
- package/docs/policies/data-loss-prevention-inbound/doc.md +22 -6
- package/docs/policies/data-loss-prevention-inbound/schema.json +10 -1
- package/docs/policies/data-loss-prevention-outbound/doc.md +23 -6
- package/docs/policies/data-loss-prevention-outbound/schema.json +10 -1
- package/docs/policies/firebase-jwt-inbound/schema.json +1 -0
- package/docs/policies/formdata-to-json-inbound/schema.json +1 -0
- package/docs/policies/galileo-tracing-v2-inbound/doc.md +72 -0
- package/docs/policies/galileo-tracing-v2-inbound/intro.md +8 -0
- package/docs/policies/{galileo-tracing-inbound → galileo-tracing-v2-inbound}/schema.json +40 -5
- package/docs/policies/geo-filter-inbound/schema.json +1 -0
- package/docs/policies/graphql-analytics-outbound/schema.json +1 -0
- package/docs/policies/graphql-cache-inbound/schema.json +1 -0
- package/docs/policies/graphql-complexity-limit-inbound/schema.json +1 -0
- package/docs/policies/graphql-disable-introspection-inbound/schema.json +1 -0
- package/docs/policies/graphql-introspection-filter-outbound/schema.json +1 -0
- package/docs/policies/http-deprecation-outbound/schema.json +1 -0
- package/docs/policies/ip-address-restriction-inbound/schema.json +1 -0
- package/docs/policies/jwt-scopes-inbound/schema.json +1 -0
- package/docs/policies/ldap-auth-inbound/schema.json +1 -0
- package/docs/policies/mcp-auth0-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-capability-filter-inbound/schema.json +1 -0
- package/docs/policies/mcp-clerk-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-cognito-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-entra-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-google-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-logto-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-okta-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-ping-oauth-inbound/schema.json +1 -0
- package/docs/policies/mcp-token-exchange-inbound/schema.json +1 -0
- package/docs/policies/mcp-workos-oauth-inbound/schema.json +1 -0
- package/docs/policies/mock-api-inbound/schema.json +1 -0
- package/docs/policies/moesif-inbound/schema.json +1 -0
- package/docs/policies/monetization-inbound/schema.json +1 -0
- package/docs/policies/mtls-auth-inbound/schema.json +1 -0
- package/docs/policies/okta-fga-authz-inbound/schema.json +1 -0
- package/docs/policies/okta-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/open-id-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/openfga-authz-inbound/schema.json +1 -0
- package/docs/policies/openmeter-inbound/schema.json +1 -0
- package/docs/policies/prompt-injection-outbound/schema.json +1 -0
- package/docs/policies/propel-auth-jwt-inbound/schema.json +1 -0
- package/docs/policies/query-param-to-header-inbound/schema.json +1 -0
- package/docs/policies/quota-inbound/schema.json +1 -0
- package/docs/policies/rate-limit-inbound/schema.json +1 -0
- package/docs/policies/readme-metrics-inbound/schema.json +1 -0
- package/docs/policies/remove-headers-inbound/schema.json +1 -0
- package/docs/policies/remove-headers-outbound/schema.json +1 -0
- package/docs/policies/remove-query-params-inbound/schema.json +1 -0
- package/docs/policies/replace-string-outbound/schema.json +1 -0
- package/docs/policies/request-size-limit-inbound/schema.json +1 -0
- package/docs/policies/request-validation-inbound/schema.json +1 -0
- package/docs/policies/require-origin-inbound/schema.json +1 -0
- package/docs/policies/require-user-claims-inbound/schema.json +1 -0
- package/docs/policies/secret-masking-outbound/schema.json +1 -0
- package/docs/policies/semantic-cache-inbound/schema.json +3 -2
- package/docs/policies/set-body-inbound/schema.json +1 -0
- package/docs/policies/set-headers-inbound/schema.json +1 -0
- package/docs/policies/set-headers-outbound/schema.json +1 -0
- package/docs/policies/set-query-params-inbound/schema.json +1 -0
- package/docs/policies/set-status-outbound/schema.json +1 -0
- package/docs/policies/set-upstream-api-key-inbound/schema.json +1 -0
- package/docs/policies/sleep-inbound/schema.json +1 -0
- package/docs/policies/stripe-webhook-verification-inbound/schema.json +1 -0
- package/docs/policies/supabase-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/traffic-splitting-inbound/schema.json +1 -0
- package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-aws-service-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-gcp-jwt-inbound/schema.json +1 -0
- package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +1 -0
- package/docs/policies/upstream-oauth-client-credentials-inbound/schema.json +1 -0
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +1 -0
- package/docs/policies/validate-json-schema-inbound/schema.json +1 -0
- package/docs/policies/web-bot-auth-inbound/schema.json +1 -0
- package/docs/policies/xml-to-json-outbound/schema.json +1 -0
- package/package.json +5 -5
- package/docs/ai-gateway/policies/akamai-ai-firewall.mdx +0 -122
- package/docs/ai-gateway/policies/authentication.mdx +0 -43
- package/docs/ai-gateway/policies/comet-opik-tracing.mdx +0 -177
- package/docs/ai-gateway/policies/fallback-model.mdx +0 -40
- package/docs/ai-gateway/policies/galileo-tracing.mdx +0 -161
- package/docs/ai-gateway/policies/metering.mdx +0 -47
- package/docs/ai-gateway/policies/model-filtering.mdx +0 -49
- package/docs/ai-gateway/policies/semantic-cache.mdx +0 -48
|
@@ -44,8 +44,9 @@ the app you have configured in Zuplo.
|
|
|
44
44
|
Models are referenced as `providerName/model`, where `providerName` is the
|
|
45
45
|
provider name configured in your gateway. By default an app can reach any model
|
|
46
46
|
offered by the providers configured for the Zuplo project. To limit it to a
|
|
47
|
-
curated set, add the
|
|
48
|
-
|
|
47
|
+
curated set, add the
|
|
48
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
49
|
+
policy to the app—it applies separate rules to completions (`generateText`,
|
|
49
50
|
`streamText`) and embeddings (`embed`), and rejects a capability it doesn't
|
|
50
51
|
configure.
|
|
51
52
|
|
|
@@ -69,5 +69,6 @@ ANTHROPIC_MODEL=anthropic/claude-sonnet-4-5-20250929
|
|
|
69
69
|
ANTHROPIC_SMALL_FAST_MODEL=anthropic/claude-haiku-4-5
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
The app's
|
|
73
|
-
|
|
72
|
+
The app's
|
|
73
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
74
|
+
policy controls which models the app may use.
|
|
@@ -83,14 +83,16 @@ codex --config model_provider="zuplo"
|
|
|
83
83
|
|
|
84
84
|
### Choosing a model
|
|
85
85
|
|
|
86
|
-
The app's
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
The app's
|
|
87
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
88
|
+
policy controls which models the app may use. Codex names the model as
|
|
89
|
+
`providerName/model`, where `providerName` is the provider name configured in
|
|
90
|
+
your gateway:
|
|
89
91
|
|
|
90
92
|
```bash
|
|
91
93
|
codex --config model_provider="zuplo" --model "openai/gpt-5"
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
A request with no model, or a model without that prefix, gets a `400`. Adding
|
|
95
|
-
[Model Filtering](
|
|
96
|
-
supplies a default, letting requests omit the model.
|
|
97
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx) with
|
|
98
|
+
an allow list also supplies a default, letting requests omit the model.
|
|
@@ -65,9 +65,10 @@ configuration approaches depending on which version you choose.
|
|
|
65
65
|
|
|
66
66
|
:::note
|
|
67
67
|
|
|
68
|
-
The app's
|
|
69
|
-
|
|
70
|
-
policy
|
|
68
|
+
The app's
|
|
69
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
70
|
+
policy controls which models the app may use, so the model you enter here must
|
|
71
|
+
be one that policy allows.
|
|
71
72
|
|
|
72
73
|
:::
|
|
73
74
|
|
|
@@ -77,6 +77,6 @@ Always name the model as `providerName/model`, where `providerName` is the
|
|
|
77
77
|
provider name configured in your gateway. The gateway needs the prefix to know
|
|
78
78
|
which provider to route to, and a request with no model, or a model without that
|
|
79
79
|
prefix, gets a `400`. Adding the
|
|
80
|
-
[Model Filtering](
|
|
81
|
-
certain models, and an allow list also supplies a
|
|
82
|
-
the model.
|
|
80
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
81
|
+
policy restricts an app to certain models, and an allow list also supplies a
|
|
82
|
+
default so requests may omit the model.
|
|
@@ -45,9 +45,9 @@ Always name the model as `providerName/model`, where `providerName` is the
|
|
|
45
45
|
provider name configured in your gateway. The gateway needs the prefix to know
|
|
46
46
|
which provider to route to, and a request with no model, or a model without that
|
|
47
47
|
prefix, gets a `400`. Adding the
|
|
48
|
-
[Model Filtering](
|
|
49
|
-
certain models, and an allow list also supplies a
|
|
50
|
-
the model.
|
|
48
|
+
[Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
|
|
49
|
+
policy restricts an app to certain models, and an allow list also supplies a
|
|
50
|
+
default so requests may omit the model.
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
53
|
import OpenAI from "openai";
|
|
@@ -4,25 +4,11 @@ sidebar_label: Overview
|
|
|
4
4
|
description: Every policy an AI Gateway app can run, and what each one does.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
import policies from "../../../policies.ui.json";
|
|
8
|
+
|
|
7
9
|
The gateway's `config/policies.json` declares which policies apps may use, and
|
|
8
10
|
each app picks from that menu in the order it wants. See
|
|
9
11
|
[Policy Chains](../policy-chains.mdx) for how a chain executes and how options
|
|
10
12
|
and secrets are inherited.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
14
|
-
| [API key authentication](./authentication.mdx) | Requires an app API key and resolves the calling app from it |
|
|
15
|
-
| [Model Filtering](./model-filtering.mdx) | Restricts the app to an allow list or block list of models, and supplies the default model |
|
|
16
|
-
| [Fallback Model](./fallback-model.mdx) | Adds a backup model for provider errors and timeouts, and a cheaper model for when a budget runs out |
|
|
17
|
-
| [Budgets and Costs](./metering.mdx) | Records usage and enforces the app's budgets for spend, tokens, and requests |
|
|
18
|
-
| [Semantic cache](./semantic-cache.mdx) | Returns a cached response when a new prompt is close enough to one already seen |
|
|
19
|
-
| [Akamai AI Firewall](./akamai-ai-firewall.mdx) | Scans prompts and completions with your Akamai configuration and blocks what it denies |
|
|
20
|
-
| [Comet Opik tracing](./comet-opik-tracing.mdx) | Sends a trace of each request and response to Comet Opik |
|
|
21
|
-
| [Galileo tracing](./galileo-tracing.mdx) | Sends a trace of each request and response to Galileo |
|
|
22
|
-
| [Configuration Executor](../policy-chains.mdx#configuration-executor) | Loads the app's configuration and runs its chain—this is what makes app chains work |
|
|
23
|
-
|
|
24
|
-
The Configuration Executor and its companion Configuration Loader sit on the
|
|
25
|
-
gateway's route rather than in an app's chain. API key authentication runs in an
|
|
26
|
-
app's chain and protects that app alone. Any
|
|
27
|
-
[custom policy](../custom-policies.mdx) you declare joins the menu alongside
|
|
28
|
-
these.
|
|
14
|
+
<PolicyOverview policies={policies} products={["ai-gateway"]} />
|
|
@@ -54,9 +54,10 @@ console.log(response.choices[0].message.content);
|
|
|
54
54
|
|
|
55
55
|
:::tip
|
|
56
56
|
|
|
57
|
-
If the app's
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
If the app's
|
|
58
|
+
[Model Filtering](../policies/ai-gateway-model-filtering-v2-inbound.mdx) policy
|
|
59
|
+
has an allow list, a request that omits `model` uses the first model in the
|
|
60
|
+
list—so clients that can't set a model still work.
|
|
60
61
|
|
|
61
62
|
:::
|
|
62
63
|
|
|
@@ -26,7 +26,7 @@ your row before writing anything.
|
|
|
26
26
|
| A different TTL per route, or per response | The [`cacheConfig` function](./dynamic-cache-rules.mdx) |
|
|
27
27
|
| Purge tags for targeted CDN invalidation | The CDN policy's `tags` option |
|
|
28
28
|
| Cache GraphQL query results by query and variables | [`graphql-cache-inbound`](../policies/graphql-cache-inbound.mdx) |
|
|
29
|
-
| Cache LLM completions by prompt similarity | [`semantic-cache-inbound`](../policies/semantic-cache-inbound.mdx)
|
|
29
|
+
| Cache LLM completions by prompt similarity | [`ai-gateway-semantic-cache-v2-inbound`](../policies/ai-gateway-semantic-cache-v2-inbound.mdx) |
|
|
30
30
|
| Store an arbitrary JSON value with a TTL from your own code | [`ZoneCache`](../programmable-api/zone-cache.mdx) |
|
|
31
31
|
|
|
32
32
|
## When custom code is the right answer
|
|
@@ -298,9 +298,9 @@ the traffic they are built for:
|
|
|
298
298
|
- [GraphQL Cache](../policies/graphql-cache-inbound.mdx) normalizes a GraphQL
|
|
299
299
|
document and its variables before hashing, so two semantically identical
|
|
300
300
|
queries share an entry even when their bodies differ.
|
|
301
|
-
- [Semantic Cache](../policies/semantic-cache-inbound.mdx) matches
|
|
302
|
-
meaning rather than exact text, which is what makes caching viable
|
|
303
|
-
an LLM.
|
|
301
|
+
- [Semantic Cache](../policies/ai-gateway-semantic-cache-v2-inbound.mdx) matches
|
|
302
|
+
requests by meaning rather than exact text, which is what makes caching viable
|
|
303
|
+
in front of an LLM.
|
|
304
304
|
|
|
305
305
|
To cache a fragment of a response rather than all of it, or to drive the cache
|
|
306
306
|
from your own code, see
|
|
@@ -83,16 +83,16 @@ three above it in Zuplo.
|
|
|
83
83
|
Find the row that matches the endpoint in front of you. The rows are ordered
|
|
84
84
|
roughly by how much a hit saves.
|
|
85
85
|
|
|
86
|
-
| Situation | Layer | Mechanism
|
|
87
|
-
| ---------------------------------------------------------------------------------------------- | ---------------------- |
|
|
88
|
-
| A public catalog endpoint that returns the same body to everyone | CDN edge | `cdn-cache-control-outbound` with an `edge` and a `client` TTL
|
|
89
|
-
| An authenticated endpoint whose body is identical for every caller | CDN edge | `cdn-cache-control-outbound` with `client.visibility: "private"` so only the CDN stores it
|
|
90
|
-
| A mostly shared response with a small caller-specific slice | Programmable | Cache the shared fragment with the Cache API or `ZoneCache`, fetch only the dynamic part
|
|
91
|
-
| A response whose cacheability depends on what it contains (empty results, error bodies, flags) | CDN edge, per response | A `cacheConfig` function that returns TTLs and purge tags for the response in hand
|
|
92
|
-
| Caching rules no built-in policy expresses (a JWT-claim key, a size limit, an upstream TTL) | Programmable | A custom inbound and outbound policy pair built on the Cache API
|
|
93
|
-
| Identical responses served to many callers, with no CDN in front of the gateway | Gateway | `caching-inbound` with an `expirationSecondsTtl`
|
|
94
|
-
| A GraphQL query repeated across callers, where the cache key is the query and its variables | Gateway | `graphql-cache-inbound`
|
|
95
|
-
| An LLM prompt worded differently each time but asking the same question | Gateway | `semantic-cache-inbound`, which matches on prompt similarity rather than an exact key
|
|
86
|
+
| Situation | Layer | Mechanism | Where to read |
|
|
87
|
+
| ---------------------------------------------------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
88
|
+
| A public catalog endpoint that returns the same body to everyone | CDN edge | `cdn-cache-control-outbound` with an `edge` and a `client` TTL | [Cache at the CDN](./cdn-caching.mdx) |
|
|
89
|
+
| An authenticated endpoint whose body is identical for every caller | CDN edge | `cdn-cache-control-outbound` with `client.visibility: "private"` so only the CDN stores it | [Cache at the CDN](./cdn-caching.mdx) |
|
|
90
|
+
| A mostly shared response with a small caller-specific slice | Programmable | Cache the shared fragment with the Cache API or `ZoneCache`, fetch only the dynamic part | [Cache part of a response](./partial-response-caching.mdx) |
|
|
91
|
+
| A response whose cacheability depends on what it contains (empty results, error bodies, flags) | CDN edge, per response | A `cacheConfig` function that returns TTLs and purge tags for the response in hand | [Per-response cache rules](./dynamic-cache-rules.mdx) |
|
|
92
|
+
| Caching rules no built-in policy expresses (a JWT-claim key, a size limit, an upstream TTL) | Programmable | A custom inbound and outbound policy pair built on the Cache API | [Build a custom caching policy](./custom-caching-policy.mdx) |
|
|
93
|
+
| Identical responses served to many callers, with no CDN in front of the gateway | Gateway | `caching-inbound` with an `expirationSecondsTtl` | [Cache at the gateway](./gateway-caching.mdx) |
|
|
94
|
+
| A GraphQL query repeated across callers, where the cache key is the query and its variables | Gateway | `graphql-cache-inbound` | [GraphQL Cache policy](../policies/graphql-cache-inbound.mdx) |
|
|
95
|
+
| An LLM prompt worded differently each time but asking the same question | Gateway | `ai-gateway-semantic-cache-v2-inbound`, which matches on prompt similarity rather than an exact key | [Semantic Cache policy](../policies/ai-gateway-semantic-cache-v2-inbound.mdx) |
|
|
96
96
|
|
|
97
97
|
The intuitive answer is wrong in these cases:
|
|
98
98
|
|
|
@@ -146,7 +146,7 @@ For more information, see the
|
|
|
146
146
|
|
|
147
147
|
## AI Firewall Protection
|
|
148
148
|
|
|
149
|
-
The [Akamai AI Firewall](../../
|
|
149
|
+
The [Akamai AI Firewall](../../policies/akamai-ai-firewall-v2-inbound.mdx)
|
|
150
150
|
provides enterprise-grade security for AI interactions:
|
|
151
151
|
|
|
152
152
|
- **Prompt injection defense** - Detects and blocks attempts to manipulate the
|
|
@@ -217,7 +217,7 @@ Deployment options include:
|
|
|
217
217
|
Akamai Connected Cloud
|
|
218
218
|
- [MCP Server Handler](../../handlers/mcp-server.mdx) - Technical documentation
|
|
219
219
|
for MCP server configuration
|
|
220
|
-
- [Akamai AI Firewall](../../
|
|
220
|
+
- [Akamai AI Firewall](../../policies/akamai-ai-firewall-v2-inbound.mdx) - AI
|
|
221
221
|
security policy configuration
|
|
222
222
|
- [Zuplo AI Gateway](../../ai-gateway/introduction.mdx) - Introduction to AI
|
|
223
223
|
Gateway capabilities
|
|
@@ -181,6 +181,11 @@ You can also pass
|
|
|
181
181
|
Zudoku's defaults and passed through to Inkeep as-is, so any option Inkeep supports can be used —
|
|
182
182
|
including ones added after this Dev Portal version was released.
|
|
183
183
|
|
|
184
|
+
Dev Portal owns the search modal's open state, so `modalSettings.isOpen` is managed for you. The
|
|
185
|
+
<kbd>⌘</kbd>+<kbd>K</kbd> / <kbd>Ctrl</kbd>+<kbd>K</kbd> shortcut is handled by Zudoku's search
|
|
186
|
+
button as well, which is why Inkeep's own `shortcutKey` is disabled by default. Setting it adds an
|
|
187
|
+
additional shortcut rather than replacing it.
|
|
188
|
+
|
|
184
189
|
For example, to categorize results into tabs based on their URL:
|
|
185
190
|
|
|
186
191
|
```typescript
|
|
@@ -32,6 +32,7 @@ When using the object form, the following properties are available:
|
|
|
32
32
|
| --------- | --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
33
33
|
| `name` | `string` | No | Display name used in the generated client configuration snippets. Falls back to the operation `summary`, then `"mcp-server"` |
|
|
34
34
|
| `version` | `string` | No | Version metadata |
|
|
35
|
+
| `url` | `string` | No | Overrides the endpoint URL shown in the card and install snippets. See [MCP URL resolution](#mcp-url-resolution) |
|
|
35
36
|
| `tools` | `[Tool Object]` | No | Array of tools provided by the MCP server |
|
|
36
37
|
|
|
37
38
|
Each item in the `tools` array:
|
|
@@ -47,6 +48,35 @@ The displayed MCP URL is constructed from the **server URL** of the API and the
|
|
|
47
48
|
operation. The server URL comes from the OpenAPI `servers` array (or the operation-level `servers`
|
|
48
49
|
override if present).
|
|
49
50
|
|
|
51
|
+
### Overriding the URL
|
|
52
|
+
|
|
53
|
+
Set `url` on `x-mcp-server` when the MCP server is not reachable under the documented API server —
|
|
54
|
+
for example when it runs on its own hostname:
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
servers:
|
|
58
|
+
- url: https://api.example.com
|
|
59
|
+
paths:
|
|
60
|
+
/mcp:
|
|
61
|
+
post:
|
|
62
|
+
summary: My MCP Server
|
|
63
|
+
x-mcp-server:
|
|
64
|
+
name: my-mcp-server
|
|
65
|
+
url: https://mcp.example.com/mcp
|
|
66
|
+
responses:
|
|
67
|
+
"200":
|
|
68
|
+
description: MCP response
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The card and every install snippet then use `https://mcp.example.com/mcp` instead of
|
|
72
|
+
`https://api.example.com/mcp`.
|
|
73
|
+
|
|
74
|
+
An absolute `url` (one with a scheme, such as `https://`) replaces the endpoint entirely and is used
|
|
75
|
+
verbatim — it also takes precedence over the server picked in the server dropdown, since it names a
|
|
76
|
+
host of its own. A value without a scheme is treated as a path on the server URL instead, so
|
|
77
|
+
`url: /v2/mcp` resolves to `https://api.example.com/v2/mcp` and still follows server selection.
|
|
78
|
+
Blank values are ignored and the URL falls back to the server URL plus the operation path.
|
|
79
|
+
|
|
50
80
|
## Examples
|
|
51
81
|
|
|
52
82
|
### Boolean shorthand
|
package/docs/policies/_index.md
CHANGED
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
| --- | --- | --- | --- |
|
|
5
5
|
| set-query-params-inbound | Add or Set Query Parameters | Adds or sets query parameters on the incoming request. | api-gateway |
|
|
6
6
|
| set-headers-inbound | Add or Set Request Headers | Adds or sets headers on the incoming request. | api-gateway |
|
|
7
|
-
| ai-gateway-
|
|
8
|
-
| ai-gateway-
|
|
9
|
-
| ai-gateway-
|
|
10
|
-
|
|
|
7
|
+
| ai-gateway-auth-v2-inbound | AI Gateway Authentication | Authenticates requests to an AI Gateway endpoint with application API keys. Add this policy to an application's `inboundPolicyChain` to require a key for that app only, or place it on the route before the configuration executor to require a key for every application on the route. The policies that follow can read the authenticated application from `request.user` (`sub` is the application name, `data` its metadata), and the application's AI Gateway configuration takes effect for the request. Use `authHeader` and `authScheme` when clients send their app key somewhere other than the default `Authorization: Bearer` header. When the matched route captures an `app_id` path parameter (platform catch-all `/:app_id/(.*)`), this policy also requires `configuration.id === request.params.app_id` and returns 403 on mismatch. | ai-gateway |
|
|
8
|
+
| ai-gateway-configuration-executor-v2-inbound | AI Gateway Configuration Executor | Loads the app configuration for the request (when auth or the configuration loader has not already) and runs the inbound policy chain from that configuration. Place this policy on AI Gateway routes after optional authentication and optional `ai-gateway-configuration-loader-v2-inbound`. When either of those already populated the app-configuration channel, this policy reuses it. Otherwise it loads the configuration with the route's `app_id` path parameter. Applications select from policies pre-declared by the gateway. Applications without a `inboundPolicyChain`, or with an empty chain, run no application-selected policies. Entry options replace the declaration's options as a complete object; omit them to inherit the declaration, including environment-backed credentials. Each occurrence receives a private deep copy of its entry options, so a policy mutating its options cannot corrupt the cached app configuration. | ai-gateway |
|
|
9
|
+
| ai-gateway-configuration-loader-v2-inbound | AI Gateway Configuration Loader | Loads the AI Gateway app configuration for the request into the request-scoped channel and does nothing else. Place this policy on AI Gateway routes before `ai-gateway-configuration-executor-v2-inbound` when you want configuration loading separated from chain execution. When `ai-gateway-auth-v2-inbound` already populated the channel, this policy reuses it. Otherwise it loads the configuration with the route's `app_id` path parameter. If this policy is omitted, the configuration executor still loads configuration itself before running the application chain. | ai-gateway |
|
|
10
|
+
| ai-gateway-fallback-model-v2-inbound | AI Gateway Fallback Model | Adds failure and quota fallbacks to an existing AI Gateway model selection. Place this policy after AI Gateway Model Filtering. It never creates a model selection, so a misplaced policy cannot bypass filtering. | ai-gateway |
|
|
11
|
+
| ai-gateway-metering-v2-inbound | AI Gateway Metering | Meters AI Gateway usage and enforces app and ancestor usage limits. Limits configured on parent teams or the bucket root are enforced through a server-side hierarchical check. The authentication policy must run before this policy so the app configuration id is available for meter storage and analytics. | ai-gateway |
|
|
12
|
+
| ai-gateway-model-filtering-v2-inbound | AI Gateway Model Filtering | Matches AI Gateway requests against curated allow lists or open block lists, then stores the winning model reference for the route handler. | ai-gateway |
|
|
13
|
+
| ai-gateway-semantic-cache-v2-inbound | AI Gateway Semantic Cache | AI Gateway Semantic Cache policy. This inbound policy looks up the semantic cache on entry and, on a miss, registers a response-sending hook to write the upstream response back into the cache. Caching parameters (semanticTolerance, expirationSecondsTtl, namespace, recentMessageCount) come from the policy options, and presence in the route's chain is what enables it. An id from the authenticated app configuration always provides the cache namespace so application-supplied options cannot cross tenant partitions. The cache key covers the system prompt plus the last `recentMessageCount` messages (default 1) — applied when storing and when matching — so multi-turn conversations can hit entries cached from earlier, shorter ones. Cache outcomes are reported on the response via the RFC 9211 `Cache-Status` header under the cache name `zp-aigw-sem-cache` (hit: `zp-aigw-sem-cache; hit; detail="similarity=0.93"`; miss: `zp-aigw-sem-cache; fwd=miss; stored`). Responses also include the `x-ai-gateway-cache: HIT\|MISS` and `x-ai-gateway-cache-similarity` headers. | ai-gateway |
|
|
14
|
+
| akamai-ai-firewall-v2-inbound | Akamai AI Firewall | Akamai AI Firewall Inbound Policy | ai-gateway |
|
|
11
15
|
| akamai-firewall-for-ai-outbound | Akamai Firewall for AI | Inspects each upstream response with Akamai's Firewall for AI detect API and replaces the response with a `403 Forbidden` if Akamai returns a `deny` rule. Useful behind AI-powered APIs to filter unsafe completions, sensitive data exposure, and toxic content before they reach the client. The body, headers, URL, and query string sent to Akamai are configurable; by default only the response body is captured. Bodies are read from a clone so the client still receives the original. | api-gateway |
|
|
12
16
|
| akamai-firewall-for-ai-inbound | Akamai Firewall for AI | Inspects each incoming request with Akamai's Firewall for AI detect API and blocks the request if Akamai returns a `deny` rule. Useful in front of AI-powered APIs to filter prompt injection, jailbreaks, and other unsafe inputs before they reach the model. The body, headers, URL, and query string sent to Akamai are configurable; by default only the request body is captured. Bodies are read from a clone so the upstream handler still sees the original. | api-gateway |
|
|
13
17
|
| amberflo-metering-inbound | Amberflo Metering / Billing | Amberflo is a usage metering and billing service. This policy allows you to send metering calls for each API to their meter ingest endpoint. | api-gateway |
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
| clear-headers-inbound | Clear Request Headers | Removes all headers from the incoming request except for those in the exclude list. | api-gateway |
|
|
27
31
|
| clear-headers-outbound | Clear Response Headers | Removes all headers from the response except for those in the exclude list. | api-gateway |
|
|
28
32
|
| clerk-jwt-auth-inbound | Clerk JWT Auth | Authenticate users using Clerk issued JWT tokens. | api-gateway |
|
|
29
|
-
| comet-opik-tracing-inbound | Comet Opik Tracing | Comet Opik Tracing Inbound Policy | ai-gateway |
|
|
33
|
+
| comet-opik-tracing-v2-inbound | Comet Opik Tracing | Comet Opik Tracing Inbound Policy | ai-gateway |
|
|
30
34
|
| complex-rate-limit-inbound | Complex Rate Limiting | The Complex Rate Limiting policy is an advanced rate limiting policy that let's you set rate limits based on custom counters (not just requests) | api-gateway |
|
|
31
35
|
| composite-inbound | Composite Inbound (Group Policies) | Creates a composite, or group policy - composed of other inbound policies. For reuse across routes. | api-gateway |
|
|
32
36
|
| composite-outbound | Composite Outbound (Group Policies) | Creates a composite, or group policy - composed of other outbound policies. For reuse across routes. | api-gateway |
|
|
@@ -35,9 +39,10 @@
|
|
|
35
39
|
| custom-code-outbound | Custom Code Outbound | A custom outbound response policy. | api-gateway |
|
|
36
40
|
| data-loss-prevention-outbound | Data Loss Prevention | Scans the upstream response body for sensitive data — PII, secrets, and financial identifiers — using an extensible catalog of built-in recognizers plus any custom patterns, and takes a configurable action when a match is found. The action is one of `mask` (redact matches before returning the response), `block` (replace the response with a `422` listing the detected entity names only), or `log` (record a warning and return unchanged). Only text content types are inspected; binary bodies pass through untouched, and the body is read from a clone so the client still receives the original stream. | api-gateway |
|
|
37
41
|
| data-loss-prevention-inbound | Data Loss Prevention | Scans the incoming request body for sensitive data — PII, secrets, and financial identifiers — using an extensible catalog of built-in recognizers plus any custom patterns, and takes a configurable action when a match is found. The action is one of `mask` (redact matches before forwarding the request), `block` (reject with a `422` listing the detected entity names only), or `log` (record a warning and forward unchanged). Only text content types are inspected; binary bodies pass through untouched, and the body is read from a clone so the upstream still receives the original stream. | api-gateway |
|
|
42
|
+
| ai-gateway-dlp-inbound | Data Loss Prevention (DLP) | Data Loss Prevention (DLP) Inbound Policy for the AI Gateway | ai-gateway |
|
|
38
43
|
| firebase-jwt-inbound | Firebase JWT Auth | Authenticate users using Firebase issued JWT tokens. | api-gateway |
|
|
39
44
|
| formdata-to-json-inbound | Form Data to JSON | Converts form data in the incoming request to JSON. | api-gateway |
|
|
40
|
-
| galileo-tracing-inbound | Galileo Tracing | Galileo Tracing Inbound Policy | ai-gateway |
|
|
45
|
+
| galileo-tracing-v2-inbound | Galileo Tracing | Galileo Tracing Inbound Policy | ai-gateway |
|
|
41
46
|
| geo-filter-inbound | Geo-location filtering | Block requests based on geo-location parameters: country, region code, and ASN | api-gateway |
|
|
42
47
|
| graphql-analytics-outbound | GraphQL Analytics | Reports GraphQL errors returned in response bodies to Zuplo's GraphQL analytics. GraphQL servers following the standard Apollo / graphql-yoga pattern return `200 OK` with an `errors[]` array in the body when an operation fails, which HTTP-level analytics alone report as a success — add this policy to a GraphQL route and failed operations show up as failures on the GraphQL dashboard, classified by error type. Each error in `errors[]` is classified from its `extensions.code` following the Apollo Server conventions (`GRAPHQL_PARSE_FAILED` → `syntax`, `GRAPHQL_VALIDATION_FAILED` → `validation`, `UNAUTHENTICATED` / `FORBIDDEN` → `auth`, timeout codes → `timeout`); custom codes can be mapped with `errorCodeClassification`, and anything unrecognized falls back to `defaultErrorClass` (`resolver`). Optionally set `logErrors` to also write a structured warning per errored response. The policy reads up to `maxScanBytes` of the body (128 KiB by default, 5 MiB maximum), scanning it for the `errors` token; a response larger than that is treated as error-free. When the token is found and the body fits, it is parsed and its errors reported. The response always passes through unchanged — the body is read from a clone, and any internal failure is swallowed so reporting can never break the request. The route must be marked `x-graphql: true` in `routes.oas.json` (which enables GraphQL analytics for the route); without the marker the policy logs a warning and does nothing. | api-gateway |
|
|
43
48
|
| graphql-cache-inbound | GraphQL Cache | Caches GraphQL query responses at the edge so identical queries are served without a round-trip to the origin. Unlike CDN caching that keys on the raw request body, this policy parses the GraphQL document and normalizes it before hashing: insignificant whitespace, field formatting, and fragment layout are collapsed, and variable object keys are sorted. Two requests that are semantically identical therefore share a cache entry even when their bodies differ byte-for-byte. There is no query size or nesting-depth limit. Only `query` operations are cached. Mutations, subscriptions, malformed documents, and non-JSON bodies are forwarded to the origin untouched. Cache hits and misses are reported on the `x-cache` response header, with a short key fingerprint on `x-cache-key`. To avoid serving one user's data to another, requests carrying an `authorization` or `cookie` header are not cached by default. Use `cacheKeyHeaders` to opt into caching them: each listed header's value is included in the cache key, so distinct credentials get distinct cache entries. | api-gateway |
|
|
@@ -87,7 +92,7 @@
|
|
|
87
92
|
| require-origin-inbound | Require Origin | Sets an allow-list for an origin header | api-gateway |
|
|
88
93
|
| require-user-claims-inbound | Require User Claims | Authorizes requests by validating claims on the authenticated user (`request.user`) against a configurable rule of `and`/`or` combinators and per-claim `eq`, `in`, and `startsWith` checks. Run it after any authentication policy that populates `request.user` — a JWT auth policy, API key auth, mTLS, and so on — to allow only specific callers (service accounts, OAuth clients, tenants, groups) without writing custom code. Every check fails closed: a missing or non-primitive claim never matches, comparisons are strict and type-sensitive, and requests without an authenticated user receive a 401 response. Denied requests receive a 403 response that does not echo claim values or expected values; the failing checks are written to the request log instead. Validation of the options runs lazily inside the policy constructor, which the runtime caches per policy name. Misconfigured options therefore fail on first use with a customer-facing `ConfigurationError` instead of failing at module load. | api-gateway |
|
|
89
94
|
| secret-masking-outbound | Secret Masking (deprecated) | Masks common secrets like Zuplo API keys, GitHub tokens, or SSH private key in the response body. | api-gateway |
|
|
90
|
-
| semantic-cache-inbound | Semantic Cache | Respond to matched incoming requests with semantically cached content The Semantic Cache Inbound policy caches responses based on semantic similarity of cache keys rather than exact matches. This allows for more flexible caching where similar requests can return cached responses even if the cache key is not exactly the same. The policy uses Large Language Model (LLM) embeddings to determine semantic similarity between cache keys based on a configurable similarity tolerance. Options: - semanticTolerance: The semantic similarity threshold for semantic cache matches (0-1, default: 0.2). Values closer to 0 require higher similarity. Can be overridden by custom functions. - expirationSecondsTtl: The timeout of the cache in seconds (default: 3600, 1 hour). Can be overridden by custom functions. - namespace: Optional namespace to isolate cache entries (default: "default"). Useful for multi-tenant scenarios or different cache contexts. - cacheBy: Determines how cache keys are generated: 'function' for custom logic or 'propertyPath' to extract from JSON body. | ai-gateway |
|
|
95
|
+
| semantic-cache-inbound | Semantic Cache (deprecated) | Respond to matched incoming requests with semantically cached content The Semantic Cache Inbound policy caches responses based on semantic similarity of cache keys rather than exact matches. This allows for more flexible caching where similar requests can return cached responses even if the cache key is not exactly the same. The policy uses Large Language Model (LLM) embeddings to determine semantic similarity between cache keys based on a configurable similarity tolerance. Options: - semanticTolerance: The semantic similarity threshold for semantic cache matches (0-1, default: 0.2). Values closer to 0 require higher similarity. Can be overridden by custom functions. - expirationSecondsTtl: The timeout of the cache in seconds (default: 3600, 1 hour). Can be overridden by custom functions. - namespace: Optional namespace to isolate cache entries (default: "default"). Useful for multi-tenant scenarios or different cache contexts. - cacheBy: Determines how cache keys are generated: 'function' for custom logic or 'propertyPath' to extract from JSON body. | ai-gateway |
|
|
91
96
|
| set-body-inbound | Set Body | Sets the body of the request in the inbound pipeline - make sure to convert a GET/HEAD request to another method when using this policy. | api-gateway |
|
|
92
97
|
| set-headers-outbound | Set Headers | Adds or sets headers on the on the outgoing response. | api-gateway |
|
|
93
98
|
| set-status-outbound | Set Status Code | Sets the status code on the on the outgoing response. | api-gateway |
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# AI Gateway Authentication
|
|
2
|
+
|
|
3
|
+
The AI Gateway Authentication policy authenticates requests with an AI Gateway
|
|
4
|
+
application API key. After a key is accepted, the calling application is
|
|
5
|
+
identified on `request.user` — `sub` is the application name and `data` its
|
|
6
|
+
metadata, both readable from custom policies — and the application's AI Gateway
|
|
7
|
+
configuration (its selected policy chain, model access, and limits) takes effect
|
|
8
|
+
for the request through the AI Gateway policies later in the route.
|
|
9
|
+
|
|
10
|
+
Use this policy when an application (or every application on a route) must
|
|
11
|
+
present an AI Gateway application API key.
|
|
12
|
+
|
|
13
|
+
A missing or invalid key returns `401 Unauthorized`. A valid key that belongs to
|
|
14
|
+
a different application than the route's `app_id` returns `403 Forbidden`.
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
Create the AI Gateway applications and their API keys before calling the
|
|
19
|
+
gateway. Each client must use a key issued for one of those applications.
|
|
20
|
+
|
|
21
|
+
## Add the policy
|
|
22
|
+
|
|
23
|
+
Declare the policy in `config/policies.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"policies": [
|
|
28
|
+
{
|
|
29
|
+
"name": "ai-gateway-auth-v2-inbound",
|
|
30
|
+
"policyType": "ai-gateway-auth-v2",
|
|
31
|
+
"handler": {
|
|
32
|
+
"export": "AIGatewayAuthV2InboundPolicy",
|
|
33
|
+
"module": "$import(@zuplo/runtime)",
|
|
34
|
+
"options": {
|
|
35
|
+
"cacheTtlSeconds": 60
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Authentication is optional. Choose where to attach it based on how widely keys
|
|
44
|
+
should be required:
|
|
45
|
+
|
|
46
|
+
### Per application (app-level)
|
|
47
|
+
|
|
48
|
+
Add the policy to an application's `inboundPolicyChain`. Only that application
|
|
49
|
+
requires an API key; other applications on the same route can omit it. The route
|
|
50
|
+
should run the configuration executor alone so it can load configuration from
|
|
51
|
+
the `app_id` path parameter before the app chain runs:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"inboundPolicyChain": [
|
|
56
|
+
{
|
|
57
|
+
"name": "ai-gateway-auth-v2-inbound"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Every application on the route (route-level)
|
|
64
|
+
|
|
65
|
+
Add the policy on the route **before** the configuration loader (or before the
|
|
66
|
+
executor on executor-only routes). That requires an API key for every
|
|
67
|
+
application that hits the route:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"x-zuplo-route": {
|
|
72
|
+
"corsPolicy": "none",
|
|
73
|
+
"handler": {
|
|
74
|
+
"export": "aiGatewayHandlerV2",
|
|
75
|
+
"module": "$import(@zuplo/runtime)",
|
|
76
|
+
"options": {}
|
|
77
|
+
},
|
|
78
|
+
"policies": {
|
|
79
|
+
"inbound": [
|
|
80
|
+
"ai-gateway-auth-v2-inbound",
|
|
81
|
+
"ai-gateway-configuration-loader-v2-inbound",
|
|
82
|
+
"ai-gateway-configuration-executor-v2-inbound"
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When auth runs on the route, it loads the app configuration from the key and the
|
|
90
|
+
loader/executor reuse that channel. When auth is omitted from the route (or only
|
|
91
|
+
present in some apps' chains), the loader (or the executor alone) loads
|
|
92
|
+
configuration from the route's `app_id` path parameter instead.
|
|
93
|
+
|
|
94
|
+
> **Protect every public gateway.** Without this policy, the gateway resolves
|
|
95
|
+
> the application from the URL and accepts the request without an application
|
|
96
|
+
> key. Only leave authentication out when another control, such as network
|
|
97
|
+
> isolation, restricts access. Team policy templates can include a locked auth
|
|
98
|
+
> entry so new applications require keys by default.
|
|
99
|
+
|
|
100
|
+
## Call the gateway
|
|
101
|
+
|
|
102
|
+
By default, clients send the application key as a bearer token:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
curl https://gateway.example.com/v1/chat/completions \
|
|
106
|
+
--header "Authorization: Bearer YOUR_APP_KEY" \
|
|
107
|
+
--header "Content-Type: application/json" \
|
|
108
|
+
--data '{
|
|
109
|
+
"model": "openai/gpt-5-mini",
|
|
110
|
+
"messages": [{ "role": "user", "content": "Hello" }]
|
|
111
|
+
}'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Authentication scheme matching is case-insensitive. A missing key, an invalid
|
|
115
|
+
scheme, or a key that is not authorized receives a `401 Unauthorized` response.
|
|
116
|
+
|
|
117
|
+
## Use a custom header
|
|
118
|
+
|
|
119
|
+
Set `authHeader` to accept the key from another header. Set `authScheme` to an
|
|
120
|
+
empty string when the header contains only the key:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"name": "ai-gateway-auth-v2-inbound",
|
|
125
|
+
"policyType": "ai-gateway-auth-v2",
|
|
126
|
+
"handler": {
|
|
127
|
+
"export": "AIGatewayAuthV2InboundPolicy",
|
|
128
|
+
"module": "$import(@zuplo/runtime)",
|
|
129
|
+
"options": {
|
|
130
|
+
"authHeader": "x-api-key",
|
|
131
|
+
"authScheme": "",
|
|
132
|
+
"cacheTtlSeconds": 60
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Clients can then call the gateway with:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
curl https://gateway.example.com/v1/chat/completions \
|
|
142
|
+
--header "x-api-key: YOUR_APP_KEY" \
|
|
143
|
+
--header "Content-Type: application/json" \
|
|
144
|
+
--data '{
|
|
145
|
+
"model": "openai/gpt-5-mini",
|
|
146
|
+
"messages": [{ "role": "user", "content": "Hello" }]
|
|
147
|
+
}'
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Choose a cache duration
|
|
151
|
+
|
|
152
|
+
`cacheTtlSeconds` controls how long an authentication result can be reused. The
|
|
153
|
+
minimum value is 10 seconds.
|
|
154
|
+
|
|
155
|
+
- Use a shorter duration when key changes must take effect quickly.
|
|
156
|
+
- Use a longer duration to reduce authentication latency and repeated validation
|
|
157
|
+
work.
|
|
158
|
+
|
|
159
|
+
A revoked key can continue to work until its cached result expires.
|
|
160
|
+
|
|
161
|
+
## Options
|
|
162
|
+
|
|
163
|
+
- `cacheTtlSeconds`: Number of seconds to cache an authentication result.
|
|
164
|
+
Defaults to `10` and must be at least `10`.
|
|
165
|
+
- `authHeader`: Header containing the application key. Defaults to
|
|
166
|
+
`Authorization`.
|
|
167
|
+
- `authScheme`: Scheme before the key. Defaults to `Bearer`. Use `""` for a
|
|
168
|
+
header containing the key without a scheme.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
The AI Gateway Authentication policy protects an AI Gateway with application API
|
|
2
|
+
keys. It identifies the calling application on `request.user` (`sub` is the
|
|
3
|
+
application name, `data` its metadata) and puts the application's AI Gateway
|
|
4
|
+
configuration into effect for the policies later in the request pipeline.
|
|
5
|
+
|
|
6
|
+
Add it to an application's `inboundPolicyChain` to require a key for that app
|
|
7
|
+
only, or place it on the route before the configuration executor to require a
|
|
8
|
+
key for every application on the route. Clients can send keys with the standard
|
|
9
|
+
`Authorization: Bearer` header or with a custom header and scheme.
|
|
10
|
+
Authentication results can be cached briefly to reduce request latency.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema",
|
|
3
|
+
"$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-auth-v2-inbound.json",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"title": "AI Gateway Authentication",
|
|
6
|
+
"isDeprecated": false,
|
|
7
|
+
"isPaidAddOn": false,
|
|
8
|
+
"isEnterprise": false,
|
|
9
|
+
"isInternal": false,
|
|
10
|
+
"isBeta": false,
|
|
11
|
+
"isHidden": false,
|
|
12
|
+
"requiresAI": true,
|
|
13
|
+
"policyType": "ai-gateway-auth-v2",
|
|
14
|
+
"products": ["ai-gateway"],
|
|
15
|
+
"description": "Authenticates requests to an AI Gateway endpoint with application API keys.\n\nAdd this policy to an application's `inboundPolicyChain` to require a key for that app only, or place it on the route before the configuration executor to require a key for every application on the route. The policies that follow can read the authenticated application from `request.user` (`sub` is the application name, `data` its metadata), and the application's AI Gateway configuration takes effect for the request. Use `authHeader` and `authScheme` when clients send their app key somewhere other than the default `Authorization: Bearer` header.\n\nWhen the matched route captures an `app_id` path parameter (platform catch-all `/:app_id/(.*)`), this policy also requires `configuration.id === request.params.app_id` and returns 403 on mismatch.",
|
|
16
|
+
"deprecatedMessage": "",
|
|
17
|
+
"required": ["handler"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"handler": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"default": {},
|
|
22
|
+
"required": ["export", "module", "options"],
|
|
23
|
+
"properties": {
|
|
24
|
+
"export": {
|
|
25
|
+
"const": "AIGatewayAuthV2InboundPolicy",
|
|
26
|
+
"description": "The name of the exported type"
|
|
27
|
+
},
|
|
28
|
+
"module": {
|
|
29
|
+
"const": "$import(@zuplo/runtime)",
|
|
30
|
+
"description": "The module containing the policy"
|
|
31
|
+
},
|
|
32
|
+
"options": {
|
|
33
|
+
"x-zuplo-policy-type": "ai-gateway-auth-v2",
|
|
34
|
+
"title": "AIGatewayAuthV2InboundPolicyOptions",
|
|
35
|
+
"type": "object",
|
|
36
|
+
"description": "The options for this policy.",
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"required": [],
|
|
39
|
+
"properties": {
|
|
40
|
+
"cacheTtlSeconds": {
|
|
41
|
+
"type": "number",
|
|
42
|
+
"default": 10,
|
|
43
|
+
"minimum": 10,
|
|
44
|
+
"description": "The time to cache authentication results for a particular key. Higher values will decrease latency. Cached results will be valid until the cache expires even in the event the key is deleted, etc."
|
|
45
|
+
},
|
|
46
|
+
"authHeader": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"default": "Authorization",
|
|
49
|
+
"x-show-example": false,
|
|
50
|
+
"x-advanced": true,
|
|
51
|
+
"description": "The name of the header with the key."
|
|
52
|
+
},
|
|
53
|
+
"authScheme": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"default": "Bearer",
|
|
56
|
+
"x-show-example": false,
|
|
57
|
+
"x-advanced": true,
|
|
58
|
+
"description": "The scheme used on the header."
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"examples": [
|
|
64
|
+
{
|
|
65
|
+
"export": "AIGatewayAuthV2InboundPolicy",
|
|
66
|
+
"module": "$import(@zuplo/runtime)",
|
|
67
|
+
"options": {
|
|
68
|
+
"cacheTtlSeconds": 10
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|