zuplo 6.70.63 → 6.70.67

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 (118) hide show
  1. package/docs/ai-gateway/fallback.mdx +132 -0
  2. package/docs/articles/api-key-api.mdx +1 -1
  3. package/docs/articles/api-key-best-practices.mdx +2 -2
  4. package/docs/articles/api-key-react-component.mdx +1 -1
  5. package/docs/articles/bypass-policy-for-testing.mdx +3 -3
  6. package/docs/articles/configuring-auth0-for-mcp-auth.mdx +1 -1
  7. package/docs/articles/configuring-okta-for-mcp-auth.mdx +1 -1
  8. package/docs/articles/health-checks.mdx +5 -5
  9. package/docs/articles/log-request-response-data.mdx +4 -4
  10. package/docs/articles/mcp-quickstart.mdx +3 -3
  11. package/docs/articles/multiple-auth-policies.mdx +3 -3
  12. package/docs/articles/plugin-azure-event-hubs.mdx +1 -1
  13. package/docs/articles/s3-signed-url-uploads.mdx +3 -4
  14. package/docs/articles/use-openapi-extension-data.mdx +1 -1
  15. package/docs/articles/waf-ddos-akamai.md +1 -1
  16. package/docs/articles/waf-ddos-aws-waf-shield.mdx +1 -1
  17. package/docs/articles/waf-ddos-fastly.mdx +1 -1
  18. package/docs/guides/geolocation-backend-routing.mdx +1 -1
  19. package/docs/guides/modify-openapi-paths.mdx +1 -1
  20. package/docs/handlers/legacy-dev-portal-handler.mdx +1 -1
  21. package/docs/handlers/redirect.mdx +3 -3
  22. package/docs/mcp-gateway/auth/manual-oauth-testing.mdx +2 -2
  23. package/docs/mcp-gateway/code-config/multi-upstream.mdx +1 -1
  24. package/docs/mcp-gateway/how-to/connect-upstream-oauth.mdx +4 -3
  25. package/docs/mcp-server/prompts.mdx +1 -1
  26. package/docs/policies/akamai-ai-firewall/schema.json +1 -1
  27. package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +1 -1
  28. package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +1 -1
  29. package/docs/policies/amberflo-metering-inbound/schema.json +1 -1
  30. package/docs/policies/api-key-inbound/schema.json +1 -1
  31. package/docs/policies/audit-log-inbound/schema.json +1 -1
  32. package/docs/policies/auth0-jwt-auth-inbound/schema.json +1 -1
  33. package/docs/policies/authzen-inbound/schema.json +1 -1
  34. package/docs/policies/axiomatics-authz-inbound/schema.json +1 -1
  35. package/docs/policies/basic-auth-inbound/schema.json +1 -1
  36. package/docs/policies/bot-detection-inbound/schema.json +1 -1
  37. package/docs/policies/brownout-inbound/schema.json +1 -1
  38. package/docs/policies/caching-inbound/schema.json +1 -1
  39. package/docs/policies/change-method-inbound/schema.json +1 -1
  40. package/docs/policies/clear-headers-inbound/schema.json +1 -1
  41. package/docs/policies/clear-headers-outbound/schema.json +1 -1
  42. package/docs/policies/clerk-jwt-auth-inbound/schema.json +1 -1
  43. package/docs/policies/cognito-jwt-auth-inbound/schema.json +1 -1
  44. package/docs/policies/comet-opik-tracing-inbound/schema.json +1 -1
  45. package/docs/policies/complex-rate-limit-inbound/schema.json +1 -1
  46. package/docs/policies/composite-inbound/schema.json +1 -1
  47. package/docs/policies/composite-outbound/schema.json +1 -1
  48. package/docs/policies/curity-phantom-token-inbound/schema.json +1 -1
  49. package/docs/policies/firebase-jwt-inbound/schema.json +1 -1
  50. package/docs/policies/formdata-to-json-inbound/schema.json +1 -1
  51. package/docs/policies/galileo-tracing-inbound/schema.json +1 -1
  52. package/docs/policies/geo-filter-inbound/schema.json +1 -1
  53. package/docs/policies/graphql-complexity-limit-inbound/schema.json +1 -1
  54. package/docs/policies/graphql-disable-introspection-inbound/schema.json +1 -1
  55. package/docs/policies/graphql-introspection-filter-outbound/schema.json +1 -1
  56. package/docs/policies/http-deprecation-outbound/schema.json +1 -1
  57. package/docs/policies/jwt-scopes-inbound/schema.json +1 -1
  58. package/docs/policies/ldap-auth-inbound/schema.json +1 -1
  59. package/docs/policies/mcp-auth0-oauth-inbound/schema.json +76 -1
  60. package/docs/policies/mcp-capability-filter-inbound/schema.json +1 -1
  61. package/docs/policies/mcp-clerk-oauth-inbound/schema.json +1 -1
  62. package/docs/policies/mcp-cognito-oauth-inbound/schema.json +1 -1
  63. package/docs/policies/mcp-entra-oauth-inbound/schema.json +1 -1
  64. package/docs/policies/mcp-google-oauth-inbound/schema.json +1 -1
  65. package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +1 -1
  66. package/docs/policies/mcp-logto-oauth-inbound/schema.json +1 -1
  67. package/docs/policies/mcp-oauth-inbound/schema.json +76 -1
  68. package/docs/policies/mcp-okta-oauth-inbound/schema.json +1 -1
  69. package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +1 -1
  70. package/docs/policies/mcp-ping-oauth-inbound/schema.json +1 -1
  71. package/docs/policies/mcp-token-exchange-inbound/schema.json +1 -1
  72. package/docs/policies/mcp-workos-oauth-inbound/schema.json +1 -1
  73. package/docs/policies/mock-api-inbound/schema.json +1 -1
  74. package/docs/policies/moesif-inbound/schema.json +1 -1
  75. package/docs/policies/monetization-inbound/schema.json +1 -1
  76. package/docs/policies/mtls-auth-inbound/intro.md +3 -3
  77. package/docs/policies/mtls-auth-inbound/schema.json +1 -1
  78. package/docs/policies/okta-fga-authz-inbound/schema.json +1 -1
  79. package/docs/policies/okta-jwt-auth-inbound/schema.json +1 -1
  80. package/docs/policies/open-id-jwt-auth-inbound/schema.json +1 -1
  81. package/docs/policies/openfga-authz-inbound/schema.json +1 -1
  82. package/docs/policies/openmeter-inbound/schema.json +1 -1
  83. package/docs/policies/prompt-injection-outbound/schema.json +1 -1
  84. package/docs/policies/propel-auth-jwt-inbound/schema.json +1 -1
  85. package/docs/policies/query-param-to-header-inbound/schema.json +1 -1
  86. package/docs/policies/quota-inbound/schema.json +1 -1
  87. package/docs/policies/rate-limit-inbound/schema.json +1 -1
  88. package/docs/policies/readme-metrics-inbound/schema.json +1 -1
  89. package/docs/policies/remove-headers-inbound/schema.json +1 -1
  90. package/docs/policies/remove-headers-outbound/schema.json +1 -1
  91. package/docs/policies/remove-query-params-inbound/schema.json +1 -1
  92. package/docs/policies/replace-string-outbound/schema.json +1 -1
  93. package/docs/policies/request-size-limit-inbound/schema.json +1 -1
  94. package/docs/policies/request-validation-inbound/schema.json +1 -1
  95. package/docs/policies/require-origin-inbound/schema.json +1 -1
  96. package/docs/policies/secret-masking-outbound/schema.json +1 -1
  97. package/docs/policies/semantic-cache-inbound/schema.json +1 -1
  98. package/docs/policies/set-body-inbound/schema.json +1 -1
  99. package/docs/policies/set-headers-inbound/schema.json +1 -1
  100. package/docs/policies/set-headers-outbound/schema.json +1 -1
  101. package/docs/policies/set-query-params-inbound/schema.json +1 -1
  102. package/docs/policies/set-status-outbound/schema.json +1 -1
  103. package/docs/policies/set-upstream-api-key-inbound/schema.json +1 -1
  104. package/docs/policies/sleep-inbound/schema.json +1 -1
  105. package/docs/policies/stripe-webhook-verification-inbound/schema.json +1 -1
  106. package/docs/policies/supabase-jwt-auth-inbound/schema.json +1 -1
  107. package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +1 -1
  108. package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +1 -1
  109. package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +1 -1
  110. package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +1 -1
  111. package/docs/policies/upstream-gcp-jwt-inbound/schema.json +1 -1
  112. package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +1 -1
  113. package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +1 -1
  114. package/docs/policies/validate-json-schema-inbound/schema.json +1 -1
  115. package/docs/policies/web-bot-auth-inbound/schema.json +1 -1
  116. package/docs/policies/xml-to-json-outbound/schema.json +1 -1
  117. package/docs/programmable-api/zuplo-request.mdx +1 -1
  118. package/package.json +4 -4
@@ -0,0 +1,132 @@
1
+ ---
2
+ title: Fallback Models
3
+ sidebar_label: Fallbacks
4
+ description:
5
+ Configure error, timeout, and quota fallback models for an AI Gateway app in
6
+ the Zuplo Portal so it keeps serving requests when the primary model fails or
7
+ goes over quota.
8
+ ---
9
+
10
+ Each AI Gateway app calls a primary model: the provider, completions model, and
11
+ optional embeddings model you select under **AI Models** on the app's
12
+ **Settings** tab. Fallbacks let an app keep serving requests when that primary
13
+ model fails, times out, or runs over its usage limits, instead of returning an
14
+ error to the caller.
15
+
16
+ The AI Gateway offers two independent fallback mechanisms, each triggered by a
17
+ different condition:
18
+
19
+ | Mechanism | Triggers when… | Without a fallback set… |
20
+ | ---------------------- | -------------------------------------------------------- | ----------------------------------- |
21
+ | **Fallback & Timeout** | The primary returns a `4xx`/`5xx` or exceeds the timeout | The error is returned to the caller |
22
+ | **Quota Fallback** | One of the app's usage limits is exceeded | The request is blocked with a `429` |
23
+
24
+ Both are configured entirely in the Zuplo Portal, and either can route to _any_
25
+ provider. The fallback doesn't have to share the primary's provider.
26
+
27
+ ## Error and timeout fallback
28
+
29
+ The **Fallback & Timeout** section fails an app over to a second model when the
30
+ primary model returns a `4xx` or `5xx` response, or when the request takes
31
+ longer than the configured timeout. This protects against provider outages, rate
32
+ limiting on the primary provider, and slow responses.
33
+
34
+ ### Configure an error and timeout fallback
35
+
36
+ <Stepper>
37
+
38
+ 1. Open the [Apps](https://portal.zuplo.com/+/account/project/ai/apps) tab of
39
+ your AI Gateway project and select the app to edit.
40
+
41
+ 1. Select the **Settings** tab and find the **Fallback & Timeout** section.
42
+
43
+ 1. Choose a **Fallback Provider**. This can be the same provider as the primary
44
+ or a different one, including a [custom provider](./custom-providers.mdx).
45
+
46
+ 1. Select the **Fallback Completions** model. If the app uses embeddings, also
47
+ select a **Fallback Embeddings** model.
48
+
49
+ 1. Set the **Request timeout (seconds)** value to bound how long the primary
50
+ model call can run before the gateway fails over. The default is `60`, but
51
+ you can set any value that suits your app.
52
+
53
+ 1. Click **Save Changes**.
54
+
55
+ </Stepper>
56
+
57
+ <Framed>
58
+
59
+ ![The Fallback & Timeout section of the app Settings tab, showing the Fallback Provider, Fallback Completions, Fallback Embeddings, and Request timeout fields](./fallback-and-timeout.png)
60
+
61
+ </Framed>
62
+
63
+ :::note
64
+
65
+ The request timeout applies _only_ when a fallback model is set. If no fallback
66
+ is configured, the primary model call runs unbounded.
67
+
68
+ :::
69
+
70
+ ## Quota fallback
71
+
72
+ The **Quota Fallback** section routes requests to an alternate, usually cheaper,
73
+ model when one of the app's [usage limits](./usage-limits.mdx) is exceeded,
74
+ rather than blocking the request with a `429`. This keeps an app available after
75
+ it crosses a budget, token, or request threshold, while shifting the overflow
76
+ traffic to a lower-cost model.
77
+
78
+ If you leave the quota fallback empty, the app blocks requests with a `429` once
79
+ it goes over quota.
80
+
81
+ ### Configure a quota fallback
82
+
83
+ <Stepper>
84
+
85
+ 1. Open the [Apps](https://portal.zuplo.com/+/account/project/ai/apps) tab and
86
+ select the app to edit.
87
+
88
+ 1. Select the **Settings** tab. Set the limits you want to enforce under **Usage
89
+ Limits & Thresholds**, then find the **Quota Fallback** section below them.
90
+
91
+ 1. Choose a **Quota Fallback Provider**, then select the **Quota Fallback
92
+ Completions** model. If the app uses embeddings, also select a **Quota
93
+ Fallback Embeddings** model.
94
+
95
+ 1. Click **Save Changes**.
96
+
97
+ </Stepper>
98
+
99
+ <Framed>
100
+
101
+ ![The Quota Fallback section of the app Settings tab, below Usage Limits & Thresholds, showing the Quota Fallback Provider, Quota Fallback Completions, and Quota Fallback Embeddings fields](./quota-fallback.png)
102
+
103
+ </Framed>
104
+
105
+ :::tip
106
+
107
+ Point the quota fallback at a smaller, cheaper model so overflow traffic stays
108
+ inexpensive while remaining available. The fallback's own usage still counts
109
+ toward the app's limits.
110
+
111
+ :::
112
+
113
+ ## How the two fallbacks combine
114
+
115
+ The mechanisms are evaluated independently and can both be active on the same
116
+ app:
117
+
118
+ - A request that is **over quota** routes to the quota fallback model.
119
+ - A request that is **within quota** but hits an **error or timeout** on the
120
+ primary routes to the error and timeout fallback model.
121
+
122
+ Set whichever fallbacks match the failure modes you want to protect against.
123
+ Neither is required.
124
+
125
+ ## Related resources
126
+
127
+ - [Managing Apps](./managing-apps.mdx) - Create, edit, and delete AI Gateway
128
+ apps.
129
+ - [Usage Limits & Thresholds](./usage-limits.mdx) - Configure the budget, token,
130
+ and request limits that trigger a quota fallback.
131
+ - [Custom Providers](./custom-providers.mdx) - Add your own provider to use as a
132
+ primary or fallback model.
@@ -87,7 +87,7 @@ export ACCOUNT_NAME=my-account
87
87
  # Your bucket API URL (Found in Settings > General)
88
88
  export BUCKET_NAME=my-bucket
89
89
  # Your Zuplo API Key (Found in Settings > Zuplo API Keys)
90
- export ZAPI_KEY=zpka_YOUR_API_KEY
90
+ export API_KEY=zpka_YOUR_API_KEY
91
91
  ```
92
92
 
93
93
  ### Creating a Consumer with a Key
@@ -49,8 +49,8 @@ microseconds.
49
49
 
50
50
  Zuplo keys include a checksum signature that can be verified mathematically at
51
51
  the edge. This happens as part of the
52
- [validation flow](./api-key-management.mdx#how-authentication-works): the format
53
- and checksum are checked before any network call, rejecting invalid keys with
52
+ [validation flow](../concepts/api-keys.md#how-validation-works): the format and
53
+ checksum are checked before any network call, rejecting invalid keys with
54
54
  near-zero cost.
55
55
 
56
56
  ## 3. Support secret scanning and leak detection
@@ -77,7 +77,7 @@ const MyComponent = () => {
77
77
  "<ACCESS_TOKEN>"
78
78
  );
79
79
 
80
- return <ApiKeyManager provider={provider} />;
80
+ return <ApiKeyManager provider={defaultProvider} />;
81
81
  };
82
82
  ```
83
83
 
@@ -37,7 +37,7 @@ Create the custom policy configuration in the `policies.json` file.
37
37
 
38
38
  ```json title="config/policies.json"
39
39
  {
40
- "policies": [{
40
+ "policies": [
41
41
  {
42
42
  "name": "monetization-with-bypass-inbound",
43
43
  "policyType": "custom-code-inbound",
@@ -48,9 +48,9 @@ Create the custom policy configuration in the `policies.json` file.
48
48
  "config1": "YOUR_VALUE",
49
49
  "config2": true
50
50
  }
51
- },
51
+ }
52
52
  }
53
- }]
53
+ ]
54
54
  }
55
55
  ```
56
56
 
@@ -127,7 +127,7 @@ will need to do the following:
127
127
  ```json
128
128
  {
129
129
  "name": "mcp-oauth-inbound",
130
- "policyType": "oauth-inbound",
130
+ "policyType": "auth0-jwt-auth-inbound",
131
131
  "handler": {
132
132
  "export": "Auth0JwtInboundPolicy",
133
133
  "module": "$import(@zuplo/runtime)",
@@ -154,7 +154,7 @@ will need to do the following:
154
154
 
155
155
  "policies": {
156
156
  "inbound": [
157
- "mcp-oauth-inbound"
157
+ "mcp-okta-oauth-inbound"
158
158
  ]
159
159
  }
160
160
  }
@@ -63,12 +63,12 @@ ensure that it's reachable and functioning. If you have multiple backend
63
63
  services you can check each of them.
64
64
 
65
65
  ```ts title="modules/health.ts"
66
- import { ZuploContext, ZuploRequest, ZuploResponse } from "@zuplo/runtime";
66
+ import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
67
67
 
68
68
  export default async function handler(
69
69
  request: ZuploRequest,
70
70
  context: ZuploContext,
71
- ): Promise<ZuploResponse> {
71
+ ): Promise<Response> {
72
72
  try {
73
73
  // Make a simple request to the backend to check its health
74
74
  const responses = await Promise.allSettled([
@@ -90,7 +90,7 @@ export default async function handler(
90
90
  ) as PromiseFulfilledResult<Response> | undefined;
91
91
  if (!backendResponse) {
92
92
  context.log.error("All backend health checks failed", { responses });
93
- return new ZuploResponse("Service Unavailable", { status: 503 });
93
+ return new Response("Service Unavailable", { status: 503 });
94
94
  } else {
95
95
  const failedResponses = responses.filter(
96
96
  (res) => res.status === "rejected",
@@ -99,11 +99,11 @@ export default async function handler(
99
99
  statuses: failedResponses.map((res) => res.reason.status),
100
100
  statusText: failedResponses.map((res) => res.reason.statusText),
101
101
  });
102
- return new ZuploResponse("Service Unavailable", { status: 503 });
102
+ return new Response("Service Unavailable", { status: 503 });
103
103
  }
104
104
  } catch (error) {
105
105
  context.log.error("Error during health check", { error });
106
- return new ZuploResponse("Service Unavailable", { status: 503 });
106
+ return new Response("Service Unavailable", { status: 503 });
107
107
  }
108
108
  }
109
109
  ```
@@ -108,10 +108,10 @@ personal information. Always sanitize or redact sensitive fields before logging.
108
108
  Create an outbound policy to log response information:
109
109
 
110
110
  ```ts title="modules/log-response-headers.ts"
111
- import type { ZuploContext, ZuploRequest, ZuploResponse } from "@zuplo/runtime";
111
+ import type { ZuploContext, ZuploRequest } from "@zuplo/runtime";
112
112
 
113
113
  export default async function outboundPolicy(
114
- response: ZuploResponse,
114
+ response: Response,
115
115
  request: ZuploRequest,
116
116
  context: ZuploContext,
117
117
  ) {
@@ -136,10 +136,10 @@ Log the response body from your backend. Clone the response first to avoid
136
136
  consuming the body stream.
137
137
 
138
138
  ```ts title="modules/log-response-body.ts"
139
- import type { ZuploContext, ZuploRequest, ZuploResponse } from "@zuplo/runtime";
139
+ import type { ZuploContext, ZuploRequest } from "@zuplo/runtime";
140
140
 
141
141
  export default async function outboundPolicy(
142
- response: ZuploResponse,
142
+ response: Response,
143
143
  request: ZuploRequest,
144
144
  context: ZuploContext,
145
145
  ) {
@@ -74,12 +74,12 @@ If you're not familiar with Zuplo, it's recommended to go through the
74
74
 
75
75
  1. Connect your MCP Client
76
76
 
77
- You can use any MCP client you like. We like the OpenAPI platform's
77
+ You can use any MCP client you like. We like the OpenAI platform's
78
78
  playground.
79
79
 
80
80
  Go to
81
81
  [platform.openai.com/playground](https://platform.openai.com/playground)
82
- (you'll need an OpenAPI account).
82
+ (you'll need an OpenAI account).
83
83
 
84
84
  ![Add tool](../../public/media/mcp-quickstart/openai-add-tool.png)
85
85
 
@@ -93,7 +93,7 @@ If you're not familiar with Zuplo, it's recommended to go through the
93
93
 
94
94
  ![Copy MCP Server URL](../../public/media/mcp-quickstart/copy-mcp-server-url.png)
95
95
 
96
- Back to the OpenAPI playground...
96
+ Back to the OpenAI playground...
97
97
 
98
98
  <ModalScreenshot size="sm">
99
99
 
@@ -31,10 +31,10 @@ cause errors or lead to security issues.
31
31
  :::
32
32
 
33
33
  All of the Zuplo built-in authentication policies have an option called
34
- `allowUnauthenticatedRequests`. This option is `true` by default, meaning for an
35
- anonymous request, the policy will immediately return a response with a 401:
34
+ `allowUnauthenticatedRequests`. This option is `false` by default, meaning for
35
+ an anonymous request, the policy will immediately return a response with a 401:
36
36
  Unauthorized status. **In the case of multiple policies, this setting must be
37
- `false`.** This means that even if the request isn't authenticated, the policy
37
+ `true`.** This means that even if the request isn't authenticated, the policy
38
38
  will still let the request through.
39
39
 
40
40
  :::tip
@@ -17,7 +17,7 @@ in TypeScript and a function to extract the field data from the `Response`,
17
17
 
18
18
  The plugin is configured in the
19
19
  [Runtime Extensions](../programmable-api/runtime-extensions.mdx) file
20
- `zuplo.runtime.ts`: git sta
20
+ `zuplo.runtime.ts`:
21
21
 
22
22
  ```ts title="modules/zuplo.runtime.ts"
23
23
  // The interface that describes the rows
@@ -18,8 +18,7 @@ entirely.
18
18
 
19
19
  If you require larger request sizes you can consider Zuplo's
20
20
  [Managed Dedicated](../dedicated/overview.mdx) offering which allows custom
21
- request size limits. Contact your Zuplo offering which allows custom request
22
- size limits. Contact your Zuplo representative for more information.
21
+ request size limits. Contact your Zuplo representative for more information.
23
22
 
24
23
  :::
25
24
 
@@ -51,8 +50,8 @@ Store your AWS credentials securely in Zuplo environment variables:
51
50
 
52
51
  If you are developing locally and want code completion, etc., in your project,
53
52
  install the AWS SDK for S3 to your project. These
54
- dependencies](../programmable-api/node-modules.mdx) are already available in the
55
- Zuplo runtime.
53
+ [dependencies](../programmable-api/node-modules.mdx) are already available in
54
+ the Zuplo runtime.
56
55
 
57
56
  ```bash
58
57
  npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
@@ -71,7 +71,7 @@ export default async function (request: ZuploRequest, context: ZuploContext) {
71
71
  const routeData = context.route.raw();
72
72
  const myCustomConfig = routeData["x-my-custom-config"];
73
73
 
74
- // Logs "Customer config, 10"
74
+ // Logs "Custom config, 10"
75
75
  context.log.debug("Custom config", myCustomConfig);
76
76
 
77
77
  return "Hello";
@@ -65,7 +65,7 @@ those requests that include the custom header and secret value.
65
65
  "name": "allow-akamai-custom-header",
66
66
  "policyType": "require-header-inbound",
67
67
  "handler": {
68
- "export": "RequireHeaderInboundPolicyOptions",
68
+ "export": "RequireHeaderInboundPolicy",
69
69
  "module": "$import(@zuplo/runtime)",
70
70
  "options": {
71
71
  "headerName": "x-akamai-auth",
@@ -63,7 +63,7 @@ those requests that include the custom header and secret value.
63
63
  "name": "allow-cloudfront-custom-header",
64
64
  "policyType": "require-header-inbound",
65
65
  "handler": {
66
- "export": "RequireHeaderInboundPolicyOptions",
66
+ "export": "RequireHeaderInboundPolicy",
67
67
  "module": "$import(@zuplo/runtime)",
68
68
  "options": {
69
69
  "headerName": "secure-header",
@@ -136,7 +136,7 @@ export default async function (
136
136
  Math.abs(currentTimeInMilliseconds - timestampInMilliseconds) / 1000;
137
137
  const offset = options.requestOffset ?? 30;
138
138
  if (differenceInSeconds > offset) {
139
- context.log.error("The request is old than 30 seconds.");
139
+ context.log.error(`The request is older than ${offset} seconds.`);
140
140
  return HttpProblems.unauthorized(request, context);
141
141
  }
142
142
 
@@ -294,7 +294,7 @@ For Option 1 (Custom Handler):
294
294
  }
295
295
  ```
296
296
 
297
- For Option 2 (URL Rewrite Handler), see the configuration shown above.
297
+ For Option 2 (URL Forward Handler), see the configuration shown above.
298
298
 
299
299
  ## Testing Your Policy
300
300
 
@@ -196,7 +196,7 @@ const insertSegment = process.argv[3] || "/v1";
196
196
  const inputFile = process.argv[4] || "openapi.json";
197
197
  const outputFile = process.argv[5] || "openapi-modified.json";
198
198
 
199
- insertPathSegment(basePrefix, insertSegment, inputFile, outputFile).catch(
199
+ insertPathSegment(inputFile, outputFile, basePrefix, insertSegment).catch(
200
200
  console.error,
201
201
  );
202
202
  ```
@@ -72,7 +72,7 @@ Use the path pattern `/docs(.*)` (not `/docs/(.*)`) to match both the root path
72
72
  ### Custom Domain
73
73
 
74
74
  By default, the handler redirects to your project's default Zuplo domain (e.g.,
75
- `my-project-1a3ksl3.zuplo.site`). If you've set up a custom domain for your
75
+ `my-project-1a3ksl3.zuplo.app`). If you've set up a custom domain for your
76
76
  developer portal, the handler will automatically use the custom domain instead.
77
77
 
78
78
  :::note
@@ -39,10 +39,10 @@ following example redirects requests at the root of a domain to a docs page at
39
39
  "options": {
40
40
  "location": "/docs"
41
41
  }
42
+ },
43
+ "policies": {
44
+ "inbound": []
42
45
  }
43
- },
44
- "policies": {
45
- "inbound": []
46
46
  }
47
47
  }
48
48
  }
@@ -220,8 +220,8 @@ REDIRECT_URI="http://localhost:8765/callback"
220
220
 
221
221
  :::warning
222
222
 
223
- The authorization code is single-use and short-lived (typically 30 seconds).
224
- Run the next step immediately after copying it.
223
+ The authorization code is single-use and short-lived (60 seconds). Run the
224
+ next step immediately after copying it.
225
225
 
226
226
  :::
227
227
 
@@ -166,7 +166,7 @@ A few notes on what's set per upstream:
166
166
  "handler": {
167
167
  "module": "$import(@zuplo/runtime/mcp-gateway)",
168
168
  "export": "McpProxyHandler",
169
- "options": { "rewritePattern": "https://mcp.stripe.com/mcp" },
169
+ "options": { "rewritePattern": "https://mcp.stripe.com" },
170
170
  },
171
171
  "policies": {
172
172
  "inbound": ["auth0-managed-oauth", "mcp-token-exchange-stripe"],
@@ -219,9 +219,10 @@ The corresponding route:
219
219
  }
220
220
  ```
221
221
 
222
- Stripe requires the bare `mcp` scope explicitly. The default PRM URL (derived
223
- from the route's `rewritePattern` of `https://mcp.stripe.com/mcp`) is correct,
224
- so no override is needed.
222
+ Stripe requires the bare `mcp` scope explicitly. Point the route's
223
+ `rewritePattern` at `https://mcp.stripe.com` Stripe serves its MCP endpoint at
224
+ the origin root, not under `/mcp`. Stripe publishes PRM at the root well-known
225
+ path, so the default derived PRM URL is correct and no override is needed.
225
226
 
226
227
  ### Notion (PRM override at `/mcp` path)
227
228
 
@@ -277,7 +277,7 @@ Response:
277
277
 
278
278
  ### Message Organization
279
279
 
280
- - Use `system` messages for general behavior instructions
280
+ - Use `assistant` messages for general behavior instructions
281
281
  - Use `assistant` messages for specific task guidance
282
282
  - Structure complex prompts as multiple focused messages
283
283
  - Keep individual messages concise and purposeful
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/akamai-ai-firewall.json",
4
4
  "type": "object",
5
5
  "title": "Akamai AI Firewall",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/akamai-firewall-for-ai-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Akamai Firewall for AI",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/akamai-firewall-for-ai-outbound.json",
4
4
  "type": "object",
5
5
  "title": "Akamai Firewall for AI",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/amberflo-metering-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Amberflo Metering / Billing",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/api-key-inbound.json",
4
4
  "type": "object",
5
5
  "title": "API Key Authentication",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/audit-log-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Audit Logs",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/auth0-jwt-auth-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Auth0 JWT Auth",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/authzen-inbound.json",
4
4
  "type": "object",
5
5
  "title": "AuthZEN Authorization",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/axiomatics-authz-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Axiomatics Authorization",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/basic-auth-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Basic Auth",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/bot-detection-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Bot Detection",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/brownout-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Brown Out",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/caching-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Caching",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/change-method-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Change Method",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/clear-headers-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Clear Request Headers",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/clear-headers-outbound.json",
4
4
  "type": "object",
5
5
  "title": "Clear Response Headers",
6
6
  "isDeprecated": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft-07/schema",
3
- "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/clerk-jwt-auth-inbound.json",
4
4
  "type": "object",
5
5
  "title": "Clerk JWT Auth",
6
6
  "isDeprecated": false,