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.
Files changed (157) hide show
  1. package/docs/ai-gateway/integrations/ai-sdk.mdx +3 -2
  2. package/docs/ai-gateway/integrations/claude-code.mdx +3 -2
  3. package/docs/ai-gateway/integrations/codex.mdx +7 -5
  4. package/docs/ai-gateway/integrations/goose.mdx +4 -3
  5. package/docs/ai-gateway/integrations/langchain.mdx +3 -3
  6. package/docs/ai-gateway/integrations/openai.mdx +3 -3
  7. package/docs/ai-gateway/policies/overview.mdx +3 -17
  8. package/docs/ai-gateway/universal-api.mdx +4 -3
  9. package/docs/caching/custom-caching-policy.mdx +1 -1
  10. package/docs/caching/gateway-caching.mdx +3 -3
  11. package/docs/caching/overview.mdx +10 -10
  12. package/docs/dedicated/akamai/ai-powered-applications.mdx +2 -2
  13. package/docs/dev-portal/zudoku/configuration/search.md +5 -0
  14. package/docs/dev-portal/zudoku/openapi-extensions/x-mcp-server.md +30 -0
  15. package/docs/policies/_index.md +12 -7
  16. package/docs/policies/ai-gateway-auth-v2-inbound/doc.md +168 -0
  17. package/docs/policies/ai-gateway-auth-v2-inbound/intro.md +10 -0
  18. package/docs/policies/ai-gateway-auth-v2-inbound/schema.json +74 -0
  19. package/docs/policies/ai-gateway-configuration-executor-v2-inbound/doc.md +442 -0
  20. package/docs/policies/ai-gateway-configuration-executor-v2-inbound/intro.md +14 -0
  21. package/docs/policies/ai-gateway-configuration-executor-v2-inbound/schema.json +60 -0
  22. package/docs/policies/ai-gateway-configuration-loader-v2-inbound/doc.md +105 -0
  23. package/docs/policies/ai-gateway-configuration-loader-v2-inbound/intro.md +6 -0
  24. package/docs/policies/ai-gateway-configuration-loader-v2-inbound/schema.json +60 -0
  25. package/docs/policies/ai-gateway-dlp-inbound/doc.md +127 -0
  26. package/docs/policies/ai-gateway-dlp-inbound/intro.md +5 -0
  27. package/docs/policies/ai-gateway-dlp-inbound/schema.json +4050 -0
  28. package/docs/policies/ai-gateway-fallback-model-v2-inbound/doc.md +10 -2
  29. package/docs/policies/ai-gateway-fallback-model-v2-inbound/intro.md +2 -2
  30. package/docs/policies/ai-gateway-fallback-model-v2-inbound/schema.json +22 -8
  31. package/docs/policies/ai-gateway-metering-v2-inbound/doc.md +19 -16
  32. package/docs/policies/ai-gateway-metering-v2-inbound/intro.md +9 -0
  33. package/docs/policies/ai-gateway-metering-v2-inbound/schema.json +20 -24
  34. package/docs/policies/ai-gateway-model-filtering-v2-inbound/doc.md +6 -5
  35. package/docs/policies/ai-gateway-model-filtering-v2-inbound/intro.md +2 -2
  36. package/docs/policies/ai-gateway-model-filtering-v2-inbound/schema.json +17 -3
  37. package/docs/policies/ai-gateway-semantic-cache-v2-inbound/doc.md +72 -0
  38. package/docs/policies/ai-gateway-semantic-cache-v2-inbound/intro.md +9 -0
  39. package/docs/policies/ai-gateway-semantic-cache-v2-inbound/schema.json +120 -0
  40. package/docs/policies/akamai-ai-firewall-v2-inbound/doc.md +87 -0
  41. package/docs/policies/akamai-ai-firewall-v2-inbound/intro.md +10 -0
  42. package/docs/policies/{akamai-ai-firewall → akamai-ai-firewall-v2-inbound}/schema.json +36 -9
  43. package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +1 -0
  44. package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +1 -0
  45. package/docs/policies/amberflo-metering-inbound/schema.json +1 -0
  46. package/docs/policies/api-key-inbound/schema.json +1 -0
  47. package/docs/policies/audit-log-inbound/schema.json +1 -0
  48. package/docs/policies/auth0-jwt-auth-inbound/schema.json +1 -0
  49. package/docs/policies/authzen-inbound/schema.json +1 -0
  50. package/docs/policies/axiomatics-authz-inbound/schema.json +1 -0
  51. package/docs/policies/basic-auth-inbound/schema.json +1 -0
  52. package/docs/policies/bot-detection-inbound/schema.json +1 -0
  53. package/docs/policies/brownout-inbound/schema.json +1 -0
  54. package/docs/policies/caching-inbound/schema.json +1 -0
  55. package/docs/policies/cdn-cache-control-outbound/schema.json +1 -0
  56. package/docs/policies/change-method-inbound/schema.json +1 -0
  57. package/docs/policies/clear-headers-inbound/schema.json +1 -0
  58. package/docs/policies/clear-headers-outbound/schema.json +1 -0
  59. package/docs/policies/clerk-jwt-auth-inbound/schema.json +1 -0
  60. package/docs/policies/cognito-jwt-auth-inbound/schema.json +1 -0
  61. package/docs/policies/comet-opik-tracing-v2-inbound/doc.md +78 -0
  62. package/docs/policies/comet-opik-tracing-v2-inbound/intro.md +10 -0
  63. package/docs/policies/{comet-opik-tracing-inbound → comet-opik-tracing-v2-inbound}/schema.json +40 -5
  64. package/docs/policies/complex-rate-limit-inbound/schema.json +1 -0
  65. package/docs/policies/composite-inbound/schema.json +1 -0
  66. package/docs/policies/composite-outbound/schema.json +1 -0
  67. package/docs/policies/curity-phantom-token-inbound/schema.json +1 -0
  68. package/docs/policies/data-loss-prevention-inbound/doc.md +22 -6
  69. package/docs/policies/data-loss-prevention-inbound/schema.json +10 -1
  70. package/docs/policies/data-loss-prevention-outbound/doc.md +23 -6
  71. package/docs/policies/data-loss-prevention-outbound/schema.json +10 -1
  72. package/docs/policies/firebase-jwt-inbound/schema.json +1 -0
  73. package/docs/policies/formdata-to-json-inbound/schema.json +1 -0
  74. package/docs/policies/galileo-tracing-v2-inbound/doc.md +72 -0
  75. package/docs/policies/galileo-tracing-v2-inbound/intro.md +8 -0
  76. package/docs/policies/{galileo-tracing-inbound → galileo-tracing-v2-inbound}/schema.json +40 -5
  77. package/docs/policies/geo-filter-inbound/schema.json +1 -0
  78. package/docs/policies/graphql-analytics-outbound/schema.json +1 -0
  79. package/docs/policies/graphql-cache-inbound/schema.json +1 -0
  80. package/docs/policies/graphql-complexity-limit-inbound/schema.json +1 -0
  81. package/docs/policies/graphql-disable-introspection-inbound/schema.json +1 -0
  82. package/docs/policies/graphql-introspection-filter-outbound/schema.json +1 -0
  83. package/docs/policies/http-deprecation-outbound/schema.json +1 -0
  84. package/docs/policies/ip-address-restriction-inbound/schema.json +1 -0
  85. package/docs/policies/jwt-scopes-inbound/schema.json +1 -0
  86. package/docs/policies/ldap-auth-inbound/schema.json +1 -0
  87. package/docs/policies/mcp-auth0-oauth-inbound/schema.json +1 -0
  88. package/docs/policies/mcp-capability-filter-inbound/schema.json +1 -0
  89. package/docs/policies/mcp-clerk-oauth-inbound/schema.json +1 -0
  90. package/docs/policies/mcp-cognito-oauth-inbound/schema.json +1 -0
  91. package/docs/policies/mcp-entra-oauth-inbound/schema.json +1 -0
  92. package/docs/policies/mcp-google-oauth-inbound/schema.json +1 -0
  93. package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +1 -0
  94. package/docs/policies/mcp-logto-oauth-inbound/schema.json +1 -0
  95. package/docs/policies/mcp-oauth-inbound/schema.json +1 -0
  96. package/docs/policies/mcp-okta-oauth-inbound/schema.json +1 -0
  97. package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +1 -0
  98. package/docs/policies/mcp-ping-oauth-inbound/schema.json +1 -0
  99. package/docs/policies/mcp-token-exchange-inbound/schema.json +1 -0
  100. package/docs/policies/mcp-workos-oauth-inbound/schema.json +1 -0
  101. package/docs/policies/mock-api-inbound/schema.json +1 -0
  102. package/docs/policies/moesif-inbound/schema.json +1 -0
  103. package/docs/policies/monetization-inbound/schema.json +1 -0
  104. package/docs/policies/mtls-auth-inbound/schema.json +1 -0
  105. package/docs/policies/okta-fga-authz-inbound/schema.json +1 -0
  106. package/docs/policies/okta-jwt-auth-inbound/schema.json +1 -0
  107. package/docs/policies/open-id-jwt-auth-inbound/schema.json +1 -0
  108. package/docs/policies/openfga-authz-inbound/schema.json +1 -0
  109. package/docs/policies/openmeter-inbound/schema.json +1 -0
  110. package/docs/policies/prompt-injection-outbound/schema.json +1 -0
  111. package/docs/policies/propel-auth-jwt-inbound/schema.json +1 -0
  112. package/docs/policies/query-param-to-header-inbound/schema.json +1 -0
  113. package/docs/policies/quota-inbound/schema.json +1 -0
  114. package/docs/policies/rate-limit-inbound/schema.json +1 -0
  115. package/docs/policies/readme-metrics-inbound/schema.json +1 -0
  116. package/docs/policies/remove-headers-inbound/schema.json +1 -0
  117. package/docs/policies/remove-headers-outbound/schema.json +1 -0
  118. package/docs/policies/remove-query-params-inbound/schema.json +1 -0
  119. package/docs/policies/replace-string-outbound/schema.json +1 -0
  120. package/docs/policies/request-size-limit-inbound/schema.json +1 -0
  121. package/docs/policies/request-validation-inbound/schema.json +1 -0
  122. package/docs/policies/require-origin-inbound/schema.json +1 -0
  123. package/docs/policies/require-user-claims-inbound/schema.json +1 -0
  124. package/docs/policies/secret-masking-outbound/schema.json +1 -0
  125. package/docs/policies/semantic-cache-inbound/schema.json +3 -2
  126. package/docs/policies/set-body-inbound/schema.json +1 -0
  127. package/docs/policies/set-headers-inbound/schema.json +1 -0
  128. package/docs/policies/set-headers-outbound/schema.json +1 -0
  129. package/docs/policies/set-query-params-inbound/schema.json +1 -0
  130. package/docs/policies/set-status-outbound/schema.json +1 -0
  131. package/docs/policies/set-upstream-api-key-inbound/schema.json +1 -0
  132. package/docs/policies/sleep-inbound/schema.json +1 -0
  133. package/docs/policies/stripe-webhook-verification-inbound/schema.json +1 -0
  134. package/docs/policies/supabase-jwt-auth-inbound/schema.json +1 -0
  135. package/docs/policies/traffic-splitting-inbound/schema.json +1 -0
  136. package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +1 -0
  137. package/docs/policies/upstream-aws-service-auth-inbound/schema.json +1 -0
  138. package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +1 -0
  139. package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +1 -0
  140. package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +1 -0
  141. package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +1 -0
  142. package/docs/policies/upstream-gcp-jwt-inbound/schema.json +1 -0
  143. package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +1 -0
  144. package/docs/policies/upstream-oauth-client-credentials-inbound/schema.json +1 -0
  145. package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +1 -0
  146. package/docs/policies/validate-json-schema-inbound/schema.json +1 -0
  147. package/docs/policies/web-bot-auth-inbound/schema.json +1 -0
  148. package/docs/policies/xml-to-json-outbound/schema.json +1 -0
  149. package/package.json +5 -5
  150. package/docs/ai-gateway/policies/akamai-ai-firewall.mdx +0 -122
  151. package/docs/ai-gateway/policies/authentication.mdx +0 -43
  152. package/docs/ai-gateway/policies/comet-opik-tracing.mdx +0 -177
  153. package/docs/ai-gateway/policies/fallback-model.mdx +0 -40
  154. package/docs/ai-gateway/policies/galileo-tracing.mdx +0 -161
  155. package/docs/ai-gateway/policies/metering.mdx +0 -47
  156. package/docs/ai-gateway/policies/model-filtering.mdx +0 -49
  157. package/docs/ai-gateway/policies/semantic-cache.mdx +0 -48
@@ -1,4 +1,4 @@
1
- # AI Gateway Fallback Model (v2) Policy
1
+ # AI Gateway Fallback Model
2
2
 
3
3
  Use this policy to add resilience to a model selection created by Model
4
4
  Filtering or a custom routing policy. Place it after Model Filtering:
@@ -10,6 +10,10 @@ Model Filtering -> Fallback Model -> AI Gateway handler
10
10
  Fallback Model never creates a primary selection. If it runs without a prior
11
11
  selection, it logs a warning and leaves the request unchanged.
12
12
 
13
+ > **Policy order matters.** Put Fallback Model immediately after Model
14
+ > Filtering. Because filtering accepts the primary selection first, a fallback
15
+ > cannot widen the models an application may select.
16
+
13
17
  ## Options
14
18
 
15
19
  `models` must contain `completions`, `embeddings`, or both. Each configured
@@ -22,7 +26,11 @@ capability must set at least one of:
22
26
  fallback.
23
27
 
24
28
  `fallbackTimeoutSeconds` applies to every configured `fallback`. It defaults to
25
- 60 seconds and accepts values from 1 through 300.
29
+ 60 seconds and accepts values from 1 through 300. The timeout covers connection
30
+ setup and the wait for response headers. It does not limit how long a streaming
31
+ response body may continue after its headers arrive.
32
+
33
+ A fallback that names the same model as the primary selection is skipped.
26
34
 
27
35
  ## Cross-provider fallback example
28
36
 
@@ -1,4 +1,4 @@
1
- AI Gateway Fallback Model (v2) adds retry, timeout, and quota fallbacks to an
2
- existing model selection. Place it after AI Gateway Model Filtering (v2). It
1
+ AI Gateway Fallback Model adds retry, timeout, and quota fallbacks to an
2
+ existing model selection. Place it after AI Gateway Model Filtering. It
3
3
  preserves the primary selection and never creates one when the policy chain is
4
4
  misordered.
@@ -2,16 +2,17 @@
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
3
  "$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-fallback-model-v2-inbound.json",
4
4
  "type": "object",
5
- "title": "AI Gateway Fallback Model (v2)",
5
+ "title": "AI Gateway Fallback Model",
6
6
  "isDeprecated": false,
7
7
  "isPaidAddOn": false,
8
8
  "isEnterprise": false,
9
9
  "isInternal": false,
10
- "isBeta": true,
10
+ "isBeta": false,
11
11
  "isHidden": false,
12
12
  "requiresAI": true,
13
+ "policyType": "ai-gateway-fallback-model-v2",
13
14
  "products": ["ai-gateway"],
14
- "description": "Adds failure and quota fallbacks to an existing AI Gateway model selection.\n\nPlace this policy after AI Gateway Model Filtering (v2). It never creates a model selection, so a misplaced policy cannot bypass filtering.",
15
+ "description": "Adds failure and quota fallbacks to an existing AI Gateway model selection.\n\nPlace this policy after AI Gateway Model Filtering. It never creates a model selection, so a misplaced policy cannot bypass filtering.",
15
16
  "deprecatedMessage": "",
16
17
  "required": ["handler"],
17
18
  "properties": {
@@ -35,6 +36,17 @@
35
36
  "description": "Options for adding failure and quota fallbacks to an existing AI Gateway model selection.",
36
37
  "additionalProperties": false,
37
38
  "required": ["models"],
39
+ "examples": [
40
+ {
41
+ "models": {
42
+ "completions": {
43
+ "fallback": "anthropic/claude-haiku-4-5",
44
+ "quotaFallback": "openai/gpt-4o-mini"
45
+ }
46
+ },
47
+ "fallbackTimeoutSeconds": 60
48
+ }
49
+ ],
38
50
  "properties": {
39
51
  "models": {
40
52
  "type": "object",
@@ -88,7 +100,7 @@
88
100
  "fallbackTimeoutSeconds": {
89
101
  "type": "number",
90
102
  "title": "Fallback Timeout Seconds",
91
- "description": "How long a primary model may take before the failure fallback is attempted.",
103
+ "description": "How long to wait for primary-model response headers before attempting the failure fallback. The timeout does not bound a streaming response body after its headers arrive.",
92
104
  "minimum": 1,
93
105
  "maximum": 300,
94
106
  "default": 60
@@ -101,11 +113,13 @@
101
113
  "export": "AIGatewayFallbackModelV2InboundPolicy",
102
114
  "module": "$import(@zuplo/runtime)",
103
115
  "options": {
104
- "fallbackTimeoutSeconds": 60,
105
116
  "models": {
106
- "completions": {},
107
- "embeddings": {}
108
- }
117
+ "completions": {
118
+ "fallback": "anthropic/claude-haiku-4-5",
119
+ "quotaFallback": "openai/gpt-4o-mini"
120
+ }
121
+ },
122
+ "fallbackTimeoutSeconds": 60
109
123
  }
110
124
  }
111
125
  ]
@@ -1,8 +1,17 @@
1
- # AI Gateway Metering (v2)
1
+ # AI Gateway Metering
2
2
 
3
- `ai-gateway-metering-v2-inbound` records AI Gateway usage and enforces daily or
4
- monthly limits before the provider request runs. Declare the policy in
5
- `policies.json`, then add it to an application's `inboundPolicyChain`.
3
+ AI Gateway Metering records application usage and enforces budgets before the
4
+ provider request runs. It meters spend, tokens, and requests. Each meter has
5
+ independent daily and monthly periods and an optional warning threshold that
6
+ notifies without blocking.
7
+
8
+ When a limit is exceeded, the policy activates the model selection's
9
+ `quotaFallback` when AI Gateway Fallback Model supplied one. Otherwise it
10
+ returns `429 Too Many Requests`.
11
+
12
+ Place Metering after Model Filtering and Fallback Model so an exceeded budget
13
+ can activate the quota fallback. Put policies that may answer early, such as
14
+ Semantic Cache, after Metering so cache hits still count toward request limits.
6
15
 
7
16
  ## Example
8
17
 
@@ -37,8 +46,9 @@ The supported meters are `costs`, `tokens`, and `requests`. Each meter can have
37
46
  `daily` and `monthly` settings. A period is enforced only when `enabled` is
38
47
  `true` and `limit` is present. Usage equal to the limit is blocked.
39
48
 
40
- When `throwOnFailure` is `false`, metering failures pass the request through.
41
- Set it to `true` to fail the request instead.
49
+ > **Budgets fail open by default.** When `throwOnFailure` is `false`, a metering
50
+ > service failure lets the request proceed unmetered and no limit is checked.
51
+ > Set it to `true` to reject the request instead.
42
52
 
43
53
  ## Team limits
44
54
 
@@ -47,19 +57,12 @@ through a server-side hierarchical check against aggregated usage. The
47
57
  `options.limits` settings govern only the app running this policy; the server
48
58
  walks the ancestor chain and reports the first exceeded limit.
49
59
 
50
- An exceeded team or root limit follows the same configured model-fallback or 429
51
- response path as an app limit. Ancestor enforcement cannot be disabled from the
52
- app's policy-chain entry. When the hierarchical check is unavailable,
60
+ An exceeded team or gateway limit follows the same configured model-fallback or
61
+ 429 response path as an app limit. Ancestor enforcement cannot be disabled from
62
+ the app's policy-chain entry. When the hierarchical check is unavailable,
53
63
  `throwOnFailure` controls the behavior: the default skips enforcement for that
54
64
  request while continuing to meter it, and `true` fails the request.
55
65
 
56
- ### Known residual
57
-
58
- Grandfathered v2 apps that already store `metadata.limits` are still evaluated
59
- at the leaf by the server's hierarchy walk. The companion Gateway Service change
60
- rejects introducing or modifying app metadata limits; cleaning up stale rows is
61
- tracked separately.
62
-
63
66
  ## Set limits from custom code
64
67
 
65
68
  Use a custom inbound policy to vary limits for individual requests. For example,
@@ -0,0 +1,9 @@
1
+ The AI Gateway Metering policy records each application's spend, tokens, and
2
+ requests and enforces daily or monthly budgets. When a limit is exceeded, it
3
+ uses the model selection's quota fallback when one is configured or returns
4
+ `429 Too Many Requests`.
5
+
6
+ Place it after Model Filtering and Fallback Model, and before policies such as
7
+ Semantic Cache that may answer without calling a provider. Metering fails open
8
+ by default when its service is unavailable; set `throwOnFailure` to `true` to
9
+ reject requests instead.
@@ -2,16 +2,17 @@
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
3
  "$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-metering-v2-inbound.json",
4
4
  "type": "object",
5
- "title": "AI Gateway Metering (v2)",
5
+ "title": "AI Gateway Metering",
6
6
  "isDeprecated": false,
7
7
  "isPaidAddOn": false,
8
8
  "isEnterprise": false,
9
9
  "isInternal": false,
10
- "isBeta": true,
10
+ "isBeta": false,
11
11
  "isHidden": false,
12
12
  "requiresAI": true,
13
+ "policyType": "ai-gateway-metering-v2",
13
14
  "products": ["ai-gateway"],
14
- "description": "Meters AI Gateway v2 usage and enforces app and ancestor usage limits.\n\nLimits configured on parent teams or the bucket root are enforced through a server-side hierarchical check.\n\nThe authentication policy must run before this policy so the app configuration id is available for meter storage and analytics.",
15
+ "description": "Meters AI Gateway usage and enforces app and ancestor usage limits.\n\nLimits configured on parent teams or the bucket root are enforced through a server-side hierarchical check.\n\nThe authentication policy must run before this policy so the app configuration id is available for meter storage and analytics.",
15
16
  "deprecatedMessage": "",
16
17
  "required": ["handler"],
17
18
  "properties": {
@@ -32,9 +33,22 @@
32
33
  "x-zuplo-policy-type": "ai-gateway-metering-v2",
33
34
  "title": "AIGatewayMeteringV2InboundPolicyOptions",
34
35
  "type": "object",
35
- "description": "Options for metering AI Gateway v2 usage and enforcing request-time limits.",
36
+ "description": "Options for metering AI Gateway usage and enforcing request-time limits.",
36
37
  "additionalProperties": false,
37
38
  "required": [],
39
+ "examples": [
40
+ {
41
+ "limits": {
42
+ "requests": {
43
+ "daily": {
44
+ "enabled": true,
45
+ "limit": 1000
46
+ }
47
+ }
48
+ },
49
+ "throwOnFailure": false
50
+ }
51
+ ],
38
52
  "properties": {
39
53
  "throwOnFailure": {
40
54
  "type": "boolean",
@@ -258,28 +272,10 @@
258
272
  "module": "$import(@zuplo/runtime)",
259
273
  "options": {
260
274
  "limits": {
261
- "costs": {
262
- "daily": {
263
- "warning": {}
264
- },
265
- "monthly": {
266
- "warning": {}
267
- }
268
- },
269
275
  "requests": {
270
276
  "daily": {
271
- "warning": {}
272
- },
273
- "monthly": {
274
- "warning": {}
275
- }
276
- },
277
- "tokens": {
278
- "daily": {
279
- "warning": {}
280
- },
281
- "monthly": {
282
- "warning": {}
277
+ "enabled": true,
278
+ "limit": 1000
283
279
  }
284
280
  }
285
281
  },
@@ -1,7 +1,8 @@
1
- # AI Gateway Model Filtering (v2) Policy
1
+ # AI Gateway Model Filtering
2
2
 
3
3
  Use this policy when an AI Gateway route must restrict which models clients may
4
- select. The policy is optional.
4
+ select. Without it, an application can use any available model from the
5
+ providers configured for the Zuplo project. The policy is optional.
5
6
 
6
7
  Choose the setup that matches the route:
7
8
 
@@ -170,9 +171,9 @@ For example, this embedding request is evaluated against `models.embeddings`:
170
171
 
171
172
  ## Adding fallbacks
172
173
 
173
- Declare AI Gateway Fallback Model (v2) separately and place it immediately after
174
- this policy. Its `fallback` handles retryable errors and timeouts;
175
- `quotaFallback` handles usage-limit signals independently.
174
+ Declare AI Gateway Fallback Model separately and place it immediately after this
175
+ policy. Its `fallback` handles retryable errors and timeouts; `quotaFallback`
176
+ handles usage-limit signals independently.
176
177
 
177
178
  ## Write your own routing policy
178
179
 
@@ -1,5 +1,5 @@
1
- AI Gateway Model Filtering (v2) controls which `providerName/model` references
1
+ AI Gateway Model Filtering controls which `providerName/model` references
2
2
  clients may select. Use an `allowList` for a curated catalog with a default, or
3
3
  a `blockList` for an open catalog with explicit exclusions. Put this policy
4
- before AI Gateway Fallback Model (v2), which adds fallback behavior only after a
4
+ before AI Gateway Fallback Model, which adds fallback behavior only after a
5
5
  primary model has passed filtering.
@@ -2,14 +2,15 @@
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
3
  "$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-model-filtering-v2-inbound.json",
4
4
  "type": "object",
5
- "title": "AI Gateway Model Filtering (v2)",
5
+ "title": "AI Gateway Model Filtering",
6
6
  "isDeprecated": false,
7
7
  "isPaidAddOn": false,
8
8
  "isEnterprise": false,
9
9
  "isInternal": false,
10
- "isBeta": true,
10
+ "isBeta": false,
11
11
  "isHidden": false,
12
12
  "requiresAI": true,
13
+ "policyType": "ai-gateway-model-filtering-v2",
13
14
  "products": ["ai-gateway"],
14
15
  "description": "Matches AI Gateway requests against curated allow lists or open block lists, then stores the winning model reference for the route handler.",
15
16
  "deprecatedMessage": "",
@@ -35,6 +36,15 @@
35
36
  "description": "Options for allowing or blocking providerName/model references for each AI Gateway capability.",
36
37
  "additionalProperties": false,
37
38
  "required": ["models"],
39
+ "examples": [
40
+ {
41
+ "models": {
42
+ "completions": {
43
+ "allowList": ["openai/gpt-4o-mini"]
44
+ }
45
+ }
46
+ }
47
+ ],
38
48
  "properties": {
39
49
  "models": {
40
50
  "type": "object",
@@ -139,7 +149,11 @@
139
149
  "export": "AIGatewayModelFilteringV2InboundPolicy",
140
150
  "module": "$import(@zuplo/runtime)",
141
151
  "options": {
142
- "models": {}
152
+ "models": {
153
+ "completions": {
154
+ "allowList": ["openai/gpt-4o-mini"]
155
+ }
156
+ }
143
157
  }
144
158
  }
145
159
  ]
@@ -0,0 +1,72 @@
1
+ # AI Gateway Semantic Cache
2
+
3
+ AI Gateway Semantic Cache answers a request from a previous response when the
4
+ new prompt is semantically similar to one already seen. A hit skips the provider
5
+ call. One inbound policy handles both directions: it checks the cache on the way
6
+ in and, on a miss, stores a successful provider response on the way out.
7
+
8
+ A cache hit returns immediately, so later inbound policies do not run. Place
9
+ Semantic Cache after Metering so hits still count toward application request
10
+ limits. Put guardrails before the cache when they must inspect every request.
11
+
12
+ ## How matching works
13
+
14
+ The cache builds an embedding from the system context and the most recent
15
+ conversation messages. It then requires the endpoint format, model, system
16
+ context, and non-conversation request parameters to match exactly before
17
+ accepting a semantic match. This prevents a similar prompt from crossing model,
18
+ parameter, or system-prompt boundaries.
19
+
20
+ `semanticTolerance` controls how loose the semantic match may be. A response is
21
+ reused when similarity is at least `1 - semanticTolerance`; the default `0.2`
22
+ therefore requires a similarity of at least `0.8`.
23
+
24
+ All three text-based AI Gateway shapes are supported: Chat Completions,
25
+ Responses, and Anthropic Messages. Streaming responses are accumulated for
26
+ storage and can be replayed as streams on a later hit.
27
+
28
+ ## Options
29
+
30
+ | Option | Default | What it does |
31
+ | ----------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
32
+ | `semanticTolerance` | `0.2` | Controls the minimum semantic similarity. Smaller values require a closer match. |
33
+ | `expirationSecondsTtl` | `3600` | Keeps a cached response for this many seconds, up to 30 days. |
34
+ | `recentMessageCount` | `1` | Uses this many recent conversation messages in the semantic key. System and developer messages are always included. |
35
+ | `maxConversationLength` | Unset | Skips conversations longer than this many messages. |
36
+ | `endpoints` | All three shapes | Limits caching to selected endpoint shapes. |
37
+ | `namespace` | Resolved configuration ID, or unset | Partitions entries when no application configuration ID is available. |
38
+
39
+ Increasing `recentMessageCount` makes the cache consider more conversational
40
+ context. Setting `maxConversationLength` can reduce topic-drift risk when only a
41
+ small recent window is used.
42
+
43
+ ## What isn't cached
44
+
45
+ - Requests whose selected message window has no user message.
46
+ - Selected messages containing images, files, audio, tool calls, tool results,
47
+ or other content that cannot be represented safely as text.
48
+ - Conversations longer than `maxConversationLength`, when that option is set.
49
+ - Provider responses whose status is not `200`.
50
+ - Empty, filtered, malformed, or otherwise unreadable responses.
51
+
52
+ Earlier multimodal messages outside the selected recent window do not prevent a
53
+ text-only recent prompt from being cached.
54
+
55
+ The cache always fails open. If a lookup, match, or store operation fails, the
56
+ request continues to the provider rather than being rejected.
57
+
58
+ ## Application isolation
59
+
60
+ When a request resolves to an application, its configuration ID fixes the
61
+ namespace and isolates its cached responses from other applications. The
62
+ `namespace` option only applies when the gateway has no application
63
+ configuration ID. Set it explicitly when unidentified traffic must be isolated
64
+ from other requests that also lack a configuration ID.
65
+
66
+ ## Read cache outcomes
67
+
68
+ Responses report the outcome in the RFC 9211 `Cache-Status` header under the
69
+ cache name `zp-aigw-sem-cache`. Responses also include these headers:
70
+
71
+ - `x-ai-gateway-cache`: `HIT` or `MISS`.
72
+ - `x-ai-gateway-cache-similarity`: the similarity score for a hit.
@@ -0,0 +1,9 @@
1
+ The AI Gateway Semantic Cache returns a previous response when a new prompt is
2
+ semantically similar, avoiding another provider call. One inbound policy checks
3
+ the cache and stores successful responses on a miss; no outbound policy is
4
+ required.
5
+
6
+ Place it after Metering so cache hits still count toward application request
7
+ limits. Resolved applications are isolated by configuration ID; set `namespace`
8
+ to partition traffic that has no configuration ID. Failures always pass the
9
+ request through to the provider.
@@ -0,0 +1,120 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-semantic-cache-v2-inbound.json",
4
+ "type": "object",
5
+ "title": "AI Gateway Semantic Cache",
6
+ "isDeprecated": false,
7
+ "isPaidAddOn": false,
8
+ "isEnterprise": true,
9
+ "isInternal": false,
10
+ "isBeta": false,
11
+ "isHidden": false,
12
+ "requiresAI": true,
13
+ "policyType": "ai-gateway-semantic-cache-v2",
14
+ "products": ["ai-gateway"],
15
+ "description": "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.\n\nCaching 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.\n\nCache 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.",
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": "AIGatewaySemanticCacheV2InboundPolicy",
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-semantic-cache-v2",
34
+ "type": "object",
35
+ "title": "AIGatewaySemanticCacheInboundPolicyOptions",
36
+ "description": "Options for the AI Gateway Semantic Cache policy. Configured inline in policies.json; the policy reads nothing from the AI Gateway configuration to decide whether to cache.",
37
+ "additionalProperties": false,
38
+ "required": [],
39
+ "examples": [
40
+ {
41
+ "semanticTolerance": 0.2,
42
+ "expirationSecondsTtl": 3600,
43
+ "recentMessageCount": 1
44
+ }
45
+ ],
46
+ "properties": {
47
+ "semanticTolerance": {
48
+ "type": "number",
49
+ "title": "Semantic Tolerance",
50
+ "description": "The semantic similarity threshold for semantic cache matches. Values closer to 0 require closer similarity, while larger values allow more flexible matching. Default is 0.2.",
51
+ "minimum": 0,
52
+ "maximum": 1,
53
+ "default": 0.2
54
+ },
55
+ "expirationSecondsTtl": {
56
+ "type": "integer",
57
+ "title": "Cache TTL (seconds)",
58
+ "description": "How long a cached response lives, in whole seconds. Defaults to 3600 (1 hour); maximum 2592000 (30 days).",
59
+ "minimum": 1,
60
+ "maximum": 2592000,
61
+ "default": 3600
62
+ },
63
+ "namespace": {
64
+ "type": "string",
65
+ "title": "Cache Namespace",
66
+ "description": "Partitions the cache when the authenticated application has no configuration id. Applications with a configuration id always use it, so cache entries stay isolated per application."
67
+ },
68
+ "recentMessageCount": {
69
+ "type": "integer",
70
+ "title": "Recent Message Count",
71
+ "description": "How many of the conversation's most recent messages (input items on the Responses endpoint) form the cache key, both when storing a response and when matching later requests. Earlier messages are ignored, so a multi-turn conversation can hit an entry cached from a shorter one; system messages are always included. Requests whose keyed window contains no user message (for example a conversation ending in an assistant prefill) are not cached. Defaults to 1 (match on the newest message only).",
72
+ "minimum": 1,
73
+ "default": 1
74
+ },
75
+ "maxConversationLength": {
76
+ "type": "number",
77
+ "title": "Max Conversation Length",
78
+ "x-advanced": true,
79
+ "description": "Skip caching entirely when the conversation has more than this many messages. Unset by default (no limit). Set a bound to guard against topic drift: the cache key covers only the last recentMessageCount messages, so the deeper a conversation goes, the more likely a match on recent messages alone ignores earlier context that should change the answer.",
80
+ "minimum": 1
81
+ },
82
+ "endpoints": {
83
+ "type": "array",
84
+ "title": "Applicable Endpoints",
85
+ "x-advanced": true,
86
+ "description": "The endpoint shapes to cache. Defaults to all shapes: \\['openai-chat', 'anthropic-messages', 'openai-responses'\\].",
87
+ "items": {
88
+ "type": "string",
89
+ "enum": [
90
+ "openai-chat",
91
+ "openai-responses",
92
+ "anthropic-messages"
93
+ ]
94
+ }
95
+ },
96
+ "onUnknownShape": {
97
+ "type": "string",
98
+ "title": "On Unknown Shape",
99
+ "x-advanced": true,
100
+ "description": "Unused by the cache (a cache miss is never unsafe, so it always fails open). Present for interface consistency.",
101
+ "enum": ["deny", "skip"],
102
+ "default": "skip"
103
+ }
104
+ }
105
+ }
106
+ },
107
+ "examples": [
108
+ {
109
+ "export": "AIGatewaySemanticCacheV2InboundPolicy",
110
+ "module": "$import(@zuplo/runtime)",
111
+ "options": {
112
+ "semanticTolerance": 0.2,
113
+ "expirationSecondsTtl": 3600,
114
+ "recentMessageCount": 1
115
+ }
116
+ }
117
+ ]
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,87 @@
1
+ # Akamai AI Firewall
2
+
3
+ The Akamai AI Firewall policy sends prompts and completions to
4
+ [Akamai Firewall for AI](https://www.akamai.com/products/firewall-for-ai) and
5
+ blocks content that your Akamai configuration denies. One inbound policy covers
6
+ both directions: it scans the request before the provider call and the response
7
+ afterward, including streaming responses.
8
+
9
+ Detection rules and their categories live in Akamai Control Center. The policy
10
+ enforces rules configured to deny; rules configured only to alert do not block
11
+ the request.
12
+
13
+ ## Configure the policy
14
+
15
+ Create or select an Akamai Firewall for AI configuration and API key. Declare
16
+ the policy once in `config/policies.json`, then add the declaration to each
17
+ application policy chain that should be protected. To protect new applications
18
+ by default, include it in the team's policy template.
19
+
20
+ ```json
21
+ {
22
+ "name": "akamai-ai-firewall-v2-inbound",
23
+ "policyType": "akamai-ai-firewall-v2",
24
+ "handler": {
25
+ "export": "AkamaiAIFirewallV2InboundPolicy",
26
+ "module": "$import(@zuplo/runtime)",
27
+ "options": {
28
+ "configurationId": "your-configuration-id",
29
+ "api-key": "$env(AKAMAI_AI_FIREWALL_API_KEY)"
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ When an application chain entry should inherit these credentials, omit the
36
+ entry's `options`. Entry options replace the declaration's complete options
37
+ object; they do not merge with it.
38
+
39
+ ## Options
40
+
41
+ | Option | Default | What it does |
42
+ | --------------------------------------- | ---------- | --------------------------------------------------------------- |
43
+ | `configurationId` | Required | Selects the Akamai firewall configuration. |
44
+ | `api-key` | Required | Authenticates to Akamai. The property name includes the hyphen. |
45
+ | `applicationId` | Unset | Supplies an optional Akamai application identifier. |
46
+ | `endpoints` | All shapes | Limits inspection to selected AI Gateway endpoint shapes. |
47
+ | `onUnknownShape` | `deny` | Denies or skips a request whose shape cannot be inspected. |
48
+ | `onError` | `block` | Blocks or allows traffic when the Akamai detection call fails. |
49
+ | `streamingAccumulation.enabled` | `true` | Enables response inspection for streaming requests. |
50
+ | `streamingAccumulation.eventsInterval` | `5` | Buffers this many stream events between checks. |
51
+ | `streamingAccumulation.checkIntervalMs` | Unset | Also runs checks on a timer when configured. |
52
+
53
+ Unknown option keys and incomplete credentials are rejected. Invalid options
54
+ fail closed so a broken chain never silently disables the guardrail.
55
+
56
+ ## Streaming behavior
57
+
58
+ For streaming responses, the gateway withholds each batch of events until the
59
+ Akamai check passes. This prevents denied content from reaching the client, but
60
+ the buffering and network check add latency. If a later batch is denied, the
61
+ stream ends with a content-filter stop rather than changing the HTTP status of a
62
+ response that has already started.
63
+
64
+ ## Block and failure behavior
65
+
66
+ A denied request or non-streaming response returns `400` in the request shape's
67
+ native error format and includes the Akamai rule ID. Anthropic Messages uses an
68
+ Anthropic-style error; Chat Completions and Responses use an OpenAI-style error.
69
+ Provider error responses are not scanned.
70
+
71
+ | Situation | Result |
72
+ | ----------------------------------------------------------------------- | -------------------------------------------------- |
73
+ | Options are invalid or incomplete | Request rejected before unguarded traffic can run. |
74
+ | The endpoint shape cannot be inspected | `400`, with code `guardrail_uninspectable`. |
75
+ | A recognized request body cannot be parsed | Request continues without input inspection. |
76
+ | A successful response body cannot be parsed | Response passes through without output inspection. |
77
+ | Akamai rejects the credentials, rate-limits the call, or is unavailable | `502`, with code `guardrail_unavailable`. |
78
+ | The endpoint is excluded by `endpoints` | Request passes through without inspection. |
79
+
80
+ Setting `onError` to `allow` changes service failures to fail open. An expired
81
+ credential can then leave the gateway returning successful responses without
82
+ inspection, so monitor firewall findings and sudden drops in block volume.
83
+
84
+ ## Additional resources
85
+
86
+ - [Akamai Firewall for AI](https://www.akamai.com/products/firewall-for-ai)
87
+ - [Akamai AI security solutions](https://www.akamai.com/solutions/security/ai-security)
@@ -0,0 +1,10 @@
1
+ The Akamai AI Firewall policy scans AI Gateway prompts and completions with
2
+ Akamai Firewall for AI. One inbound policy protects both request and response
3
+ content, including streaming responses, and blocks content that an Akamai rule
4
+ denies.
5
+
6
+ For runtime inspection, the policy denies unknown endpoint shapes and handled
7
+ Akamai detection-call failures by default. If a recognized request or successful
8
+ response has an unparseable JSON body, the policy skips scanning that body and
9
+ passes it through. Detection rules and categories are configured in Akamai
10
+ Control Center.