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.
- package/docs/ai-gateway/fallback.mdx +132 -0
- package/docs/articles/api-key-api.mdx +1 -1
- package/docs/articles/api-key-best-practices.mdx +2 -2
- package/docs/articles/api-key-react-component.mdx +1 -1
- package/docs/articles/bypass-policy-for-testing.mdx +3 -3
- package/docs/articles/configuring-auth0-for-mcp-auth.mdx +1 -1
- package/docs/articles/configuring-okta-for-mcp-auth.mdx +1 -1
- package/docs/articles/health-checks.mdx +5 -5
- package/docs/articles/log-request-response-data.mdx +4 -4
- package/docs/articles/mcp-quickstart.mdx +3 -3
- package/docs/articles/multiple-auth-policies.mdx +3 -3
- package/docs/articles/plugin-azure-event-hubs.mdx +1 -1
- package/docs/articles/s3-signed-url-uploads.mdx +3 -4
- package/docs/articles/use-openapi-extension-data.mdx +1 -1
- package/docs/articles/waf-ddos-akamai.md +1 -1
- package/docs/articles/waf-ddos-aws-waf-shield.mdx +1 -1
- package/docs/articles/waf-ddos-fastly.mdx +1 -1
- package/docs/guides/geolocation-backend-routing.mdx +1 -1
- package/docs/guides/modify-openapi-paths.mdx +1 -1
- package/docs/handlers/legacy-dev-portal-handler.mdx +1 -1
- package/docs/handlers/redirect.mdx +3 -3
- package/docs/mcp-gateway/auth/manual-oauth-testing.mdx +2 -2
- package/docs/mcp-gateway/code-config/multi-upstream.mdx +1 -1
- package/docs/mcp-gateway/how-to/connect-upstream-oauth.mdx +4 -3
- package/docs/mcp-server/prompts.mdx +1 -1
- package/docs/policies/akamai-ai-firewall/schema.json +1 -1
- package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +1 -1
- package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +1 -1
- package/docs/policies/amberflo-metering-inbound/schema.json +1 -1
- package/docs/policies/api-key-inbound/schema.json +1 -1
- package/docs/policies/audit-log-inbound/schema.json +1 -1
- package/docs/policies/auth0-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/authzen-inbound/schema.json +1 -1
- package/docs/policies/axiomatics-authz-inbound/schema.json +1 -1
- package/docs/policies/basic-auth-inbound/schema.json +1 -1
- package/docs/policies/bot-detection-inbound/schema.json +1 -1
- package/docs/policies/brownout-inbound/schema.json +1 -1
- package/docs/policies/caching-inbound/schema.json +1 -1
- package/docs/policies/change-method-inbound/schema.json +1 -1
- package/docs/policies/clear-headers-inbound/schema.json +1 -1
- package/docs/policies/clear-headers-outbound/schema.json +1 -1
- package/docs/policies/clerk-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/cognito-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/comet-opik-tracing-inbound/schema.json +1 -1
- package/docs/policies/complex-rate-limit-inbound/schema.json +1 -1
- package/docs/policies/composite-inbound/schema.json +1 -1
- package/docs/policies/composite-outbound/schema.json +1 -1
- package/docs/policies/curity-phantom-token-inbound/schema.json +1 -1
- package/docs/policies/firebase-jwt-inbound/schema.json +1 -1
- package/docs/policies/formdata-to-json-inbound/schema.json +1 -1
- package/docs/policies/galileo-tracing-inbound/schema.json +1 -1
- package/docs/policies/geo-filter-inbound/schema.json +1 -1
- package/docs/policies/graphql-complexity-limit-inbound/schema.json +1 -1
- package/docs/policies/graphql-disable-introspection-inbound/schema.json +1 -1
- package/docs/policies/graphql-introspection-filter-outbound/schema.json +1 -1
- package/docs/policies/http-deprecation-outbound/schema.json +1 -1
- package/docs/policies/jwt-scopes-inbound/schema.json +1 -1
- package/docs/policies/ldap-auth-inbound/schema.json +1 -1
- package/docs/policies/mcp-auth0-oauth-inbound/schema.json +76 -1
- package/docs/policies/mcp-capability-filter-inbound/schema.json +1 -1
- package/docs/policies/mcp-clerk-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-cognito-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-entra-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-google-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-logto-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-oauth-inbound/schema.json +76 -1
- package/docs/policies/mcp-okta-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-ping-oauth-inbound/schema.json +1 -1
- package/docs/policies/mcp-token-exchange-inbound/schema.json +1 -1
- package/docs/policies/mcp-workos-oauth-inbound/schema.json +1 -1
- package/docs/policies/mock-api-inbound/schema.json +1 -1
- package/docs/policies/moesif-inbound/schema.json +1 -1
- package/docs/policies/monetization-inbound/schema.json +1 -1
- package/docs/policies/mtls-auth-inbound/intro.md +3 -3
- package/docs/policies/mtls-auth-inbound/schema.json +1 -1
- package/docs/policies/okta-fga-authz-inbound/schema.json +1 -1
- package/docs/policies/okta-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/open-id-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/openfga-authz-inbound/schema.json +1 -1
- package/docs/policies/openmeter-inbound/schema.json +1 -1
- package/docs/policies/prompt-injection-outbound/schema.json +1 -1
- package/docs/policies/propel-auth-jwt-inbound/schema.json +1 -1
- package/docs/policies/query-param-to-header-inbound/schema.json +1 -1
- package/docs/policies/quota-inbound/schema.json +1 -1
- package/docs/policies/rate-limit-inbound/schema.json +1 -1
- package/docs/policies/readme-metrics-inbound/schema.json +1 -1
- package/docs/policies/remove-headers-inbound/schema.json +1 -1
- package/docs/policies/remove-headers-outbound/schema.json +1 -1
- package/docs/policies/remove-query-params-inbound/schema.json +1 -1
- package/docs/policies/replace-string-outbound/schema.json +1 -1
- package/docs/policies/request-size-limit-inbound/schema.json +1 -1
- package/docs/policies/request-validation-inbound/schema.json +1 -1
- package/docs/policies/require-origin-inbound/schema.json +1 -1
- package/docs/policies/secret-masking-outbound/schema.json +1 -1
- package/docs/policies/semantic-cache-inbound/schema.json +1 -1
- package/docs/policies/set-body-inbound/schema.json +1 -1
- package/docs/policies/set-headers-inbound/schema.json +1 -1
- package/docs/policies/set-headers-outbound/schema.json +1 -1
- package/docs/policies/set-query-params-inbound/schema.json +1 -1
- package/docs/policies/set-status-outbound/schema.json +1 -1
- package/docs/policies/set-upstream-api-key-inbound/schema.json +1 -1
- package/docs/policies/sleep-inbound/schema.json +1 -1
- package/docs/policies/stripe-webhook-verification-inbound/schema.json +1 -1
- package/docs/policies/supabase-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-gcp-jwt-inbound/schema.json +1 -1
- package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +1 -1
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +1 -1
- package/docs/policies/validate-json-schema-inbound/schema.json +1 -1
- package/docs/policies/web-bot-auth-inbound/schema.json +1 -1
- package/docs/policies/xml-to-json-outbound/schema.json +1 -1
- package/docs/programmable-api/zuplo-request.mdx +1 -1
- 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
|
+

|
|
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
|
+

|
|
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
|
|
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](
|
|
53
|
-
|
|
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
|
|
@@ -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
|
-
|
|
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": "
|
|
130
|
+
"policyType": "auth0-jwt-auth-inbound",
|
|
131
131
|
"handler": {
|
|
132
132
|
"export": "Auth0JwtInboundPolicy",
|
|
133
133
|
"module": "$import(@zuplo/runtime)",
|
|
@@ -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
|
|
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<
|
|
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
|
|
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
|
|
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
|
|
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
|
|
111
|
+
import type { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
112
112
|
|
|
113
113
|
export default async function outboundPolicy(
|
|
114
|
-
response:
|
|
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
|
|
139
|
+
import type { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
140
140
|
|
|
141
141
|
export default async function outboundPolicy(
|
|
142
|
-
response:
|
|
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
|
|
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
|
|
82
|
+
(you'll need an OpenAI account).
|
|
83
83
|
|
|
84
84
|

|
|
85
85
|
|
|
@@ -93,7 +93,7 @@ If you're not familiar with Zuplo, it's recommended to go through the
|
|
|
93
93
|
|
|
94
94
|

|
|
95
95
|
|
|
96
|
-
Back to the
|
|
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 `
|
|
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
|
-
`
|
|
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`:
|
|
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
|
|
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
|
|
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 "
|
|
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": "
|
|
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": "
|
|
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(
|
|
139
|
+
context.log.error(`The request is older than ${offset} seconds.`);
|
|
140
140
|
return HttpProblems.unauthorized(request, context);
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -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(
|
|
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.
|
|
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
|
|
@@ -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 (
|
|
224
|
-
|
|
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
|
|
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.
|
|
223
|
-
|
|
224
|
-
|
|
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 `
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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,
|