zuplo 7.10.0 → 7.11.1

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.
@@ -83,10 +83,8 @@ Streaming (`stream: true`) works on all three serving endpoints.
83
83
 
84
84
  On the OpenAI-compatible side, endpoint support is per model, decided by AWS:
85
85
 
86
- - The GPT-5.x models (`openai.gpt-5.6-sol`, `openai.gpt-5.5`, and family) serve
87
- the Responses API only. Sending one to `/v1/chat/completions` returns Mantle's
88
- own error that the model doesn't support that API.
89
- - The GPT-OSS models (`openai.gpt-oss-120b`, `openai.gpt-oss-20b`) serve both
86
+ - The GPT-5.x models (`openai.gpt-5.6-sol`, `openai.gpt-5.5`, and family) and
87
+ the GPT-OSS models (`openai.gpt-oss-120b`, `openai.gpt-oss-20b`) serve both
90
88
  chat completions and the Responses API.
91
89
  - Most of the other models serve chat completions only, and answer
92
90
  `/v1/responses` with an error.
@@ -319,8 +317,8 @@ serves both APIs, so it can be confusing—support is per model family, per the
319
317
  [endpoint table](#supported-endpoints-by-model-family).
320
318
 
321
319
  **Mantle answers that the model doesn't support the API.** Endpoint support is
322
- per model on the OpenAI-compatible side—the GPT-5.x models serve only
323
- `/v1/responses`, and most other models serve only `/v1/chat/completions`. Check
320
+ per model on the OpenAI-compatible side. The GPT-5.x and GPT-OSS models serve
321
+ both endpoints, but most other models serve only `/v1/chat/completions`. Check
324
322
  the **APIs supported** row on the model's AWS model card.
325
323
 
326
324
  **A model in the picker fails at request time.** The model picker lists Mantle's
@@ -11,14 +11,17 @@ out, or an applicable usage limit is exceeded, instead of returning an error to
11
11
  the caller. They're configured with the **Fallback Model** policy in the app's
12
12
  [policy chain](./policy-chains.mdx).
13
13
 
14
- The AI Gateway offers two independent fallback mechanisms, each triggered by a
15
- different condition:
14
+ The AI Gateway offers two fallback mechanisms, each triggered by a different
15
+ condition:
16
16
 
17
17
  | Mechanism | Triggers when… | Without a fallback set… |
18
18
  | ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------- |
19
19
  | **Fallback & Timeout** | The primary fails with a retryable error (`5xx`, `408`, `425`, `429`), a network failure, or a timeout | The gateway returns the error to the caller |
20
20
  | **Quota Fallback** | An app, pool, or gateway usage limit is exceeded | The request is blocked with a `429` |
21
21
 
22
+ If you set both, the fallback also backs up the quota fallback. For details, see
23
+ [How the two fallbacks combine](#how-the-two-fallbacks-combine).
24
+
22
25
  Both are configured entirely in the Zuplo Portal, and either can route to _any_
23
26
  provider—the fallback doesn't have to share the primary's provider. Fallback
24
27
  models are referenced like any model, as `providerName/model`.
@@ -82,21 +85,41 @@ toward every applicable limit.
82
85
 
83
86
  ## How the two fallbacks combine
84
87
 
85
- The mechanisms are evaluated independently and can both be active on the same
86
- app:
88
+ Both fallbacks can be active on the same app. The fallback model backs up
89
+ whichever model the request goes to first:
87
90
 
88
- - A request that's **over quota** routes to the quota fallback model.
89
- - A request that's **within quota** but hits an **error or timeout** on the
90
- primary routes to the error and timeout fallback model.
91
+ - A request that's **within quota** goes to the primary model. If the primary
92
+ fails with a retryable error or times out, the request moves to the fallback
93
+ model.
94
+ - A request that's **over quota** goes to the quota fallback model. If the quota
95
+ fallback fails the same way, the request moves to the fallback model.
91
96
 
92
- Set whichever fallbacks match the failure modes you want to protect against.
93
- Neither is required.
97
+ As a result, an over-quota request can still run on the fallback model. Set
98
+ whichever fallbacks match the failure modes you want to protect against. Neither
99
+ is required.
94
100
 
95
101
  :::note
96
102
 
97
- Error and timeout fallback applies to Chat Completions and Embeddings requests.
98
- Requests to the native `/v1/messages` and `/v1/responses` endpoints pass through
99
- without retrying a backup model; the quota fallback still applies to them.
103
+ On Chat Completions and Embeddings requests, the fallback covers every failure
104
+ that the **Fallback & Timeout** row lists. Other requests follow narrower rules:
105
+
106
+ - **Responses and Messages requests** (`POST /v1/responses` and
107
+ `POST /v1/messages`) move to the fallback only on a `429`. The gateway first
108
+ retries the primary twice, after 250 ms and then after 500 ms. The request
109
+ moves only if the primary still returns `429` and the fallback model serves
110
+ the same endpoint. A `5xx` error, a network failure, or a timeout doesn't move
111
+ the request, and the fallback timeout doesn't apply. Over quota, these
112
+ requests use the quota fallback only if it serves the endpoint. Otherwise, the
113
+ gateway returns `429`.
114
+ - **Token counting requests** (`/v1/messages/count_tokens`) never use the
115
+ fallback. Over quota, they use the quota fallback only if it can count tokens.
116
+ Otherwise, the gateway returns `429`.
117
+ - **[System One](./jev.mdx) requests** (`/v1/systemone`) and requests that
118
+ retrieve, delete, or list the input items of a stored response never use
119
+ either fallback. Over quota, the gateway returns `429`.
120
+
121
+ No model serves both `/v1/responses` and `/v1/messages`. If your clients call
122
+ both endpoints, each fallback model covers at most one of them.
100
123
 
101
124
  :::
102
125
 
@@ -9,59 +9,47 @@ configured to run as a custom origin behind Akamai.
9
9
  ## Securing Zuplo from Direct Access
10
10
 
11
11
  With any WAF product, you will want to ensure that network traffic can't bypass
12
- your WAF and hit your Zuplo Gateway directly. Akamai offers several ways to
13
- ensure that your gateway is only accessible through the WAF.
12
+ your WAF and hit your Zuplo Gateway directly. To do that, every request from
13
+ Akamai must prove that it came from **your** Akamai property, not just from
14
+ Akamai's network.
14
15
 
15
- The information below is a summary of Akamai's own recommendations for securing
16
- your backend - regardless of whether you are using Zuplo, another gateway, or
17
- Akamai origins. You can reference the
18
- [Akamai documentation](https://techdocs.akamai.com/application-security/docs/origin-server-protection).
16
+ Use one of these:
19
17
 
20
- ### IP Address Restrictions
18
+ | Method | How it works |
19
+ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
20
+ | [Shared secret header](#shared-secret-header) | Akamai adds a secret header to every request it forwards. The gateway rejects requests without it. |
21
+ | [Mutual TLS](#mutual-tls-mtls) | Akamai presents a client certificate when it connects to the gateway. The gateway rejects connections without one. |
21
22
 
22
- Akamai maintains a list of IP addresses that you can use to restrict access to
23
- your Zuplo Gateway. This is a good way to ensure that only Akamai can access
24
- your gateway. However, as Akamai is a multi-tenant service, this method isn't
25
- sufficient to protect unauthorized traffic from hitting your gateway.
23
+ :::warning
26
24
 
27
- In Zuplo, you can use a
28
- [custom code policy](../policies/custom-code-inbound.mdx) to limit traffic to
29
- only the Akamai IP addresses. Add a module in your project (for example,
30
- `modules/ip-restriction.ts`) that allows only your permitted IP ranges, then
31
- configure the policy with the IP ranges that Akamai publishes for your account
32
- in Akamai Control Center.
25
+ Don't rely on Akamai IP addresses alone. Akamai's edge IP ranges, including the
26
+ [Origin IP ACL](https://techdocs.akamai.com/origin-ip-acl/docs/update-your-origin-server)
27
+ ranges, are shared by every Akamai customer. Anyone with an Akamai account can
28
+ configure a property that points at your gateway and sends traffic from those
29
+ addresses. Akamai's own
30
+ [guidance](https://techdocs.akamai.com/origin-ip-acl/docs/recommendations-and-caveats)
31
+ states that Origin IP ACL "isn't a substitute for authentication". See
32
+ [IP-based restrictions](#ip-based-restrictions).
33
33
 
34
- ```json
35
- {
36
- "name": "allow-akamai-only",
37
- "policyType": "custom-code-inbound",
38
- "handler": {
39
- "export": "default",
40
- "module": "$import(./modules/ip-restriction)",
41
- "options": {
42
- "allowedIpAddresses": ["23.32.0.0/11", "104.64.0.0/10"]
43
- }
44
- }
45
- }
46
- ```
34
+ :::
47
35
 
48
- With this policy in place, only Akamai traffic will be allowed to hit your Zuplo
49
- Gateway.
36
+ The rest of this section summarizes Akamai's recommendations for securing an
37
+ origin. For the full details, see the
38
+ [Akamai documentation](https://techdocs.akamai.com/application-security/docs/origin-server-protection).
50
39
 
51
- ### Custom Headers
40
+ ### Shared Secret Header
52
41
 
53
- Another way to ensure that traffic is coming from Akamai is to use custom
54
- headers. Custom headers can be added to your Akamai configuration and then
55
- checked by your Zuplo Gateway. This provides an additional layer of security on
56
- top of IP address restrictions and prevents any unauthorized traffic from
57
- hitting your gateway - regardless of the source.
42
+ A shared secret header is the simplest option, and it works on every Zuplo plan.
58
43
 
59
- In Akamai, you can configure custom headers using the Property Manager or the
60
- Akamai API. Add a custom header with a secret value that only you and Akamai
61
- know.
44
+ In Akamai, use the
45
+ [Modify Incoming Request Header](https://techdocs.akamai.com/property-mgr/docs/modify-incoming-req-header)
46
+ behavior in Property Manager to add a header, such as `x-akamai-auth`, with a
47
+ long random value. Store the same value in Zuplo as a secret
48
+ [environment variable](./environment-variables.mdx) named
49
+ `AKAMAI_SECRET_HEADER_VALUE`.
62
50
 
63
- In Zuplo, you can use a small custom code policy to limit traffic to only those
64
- requests that include the custom header and secret value.
51
+ In Zuplo, add a small custom code policy that rejects requests without the
52
+ header and secret value.
65
53
 
66
54
  ```ts title="modules/require-akamai-header.ts"
67
55
  import {
@@ -94,59 +82,79 @@ export default async function policy(
94
82
  }
95
83
  ```
96
84
 
97
- With this policy in place, only requests that include the custom header with the
98
- secret value will be allowed to hit your Zuplo Gateway.
99
-
100
- ## Additional Akamai Origin Security Options
85
+ Add this policy first in the inbound policy list of every route. With it in
86
+ place, only requests that carry the secret value reach your Zuplo Gateway. Treat
87
+ the value like any other credential: rotate it periodically by updating the
88
+ Akamai behavior and the environment variable together.
101
89
 
102
- Akamai provides several additional security features to protect your origin
103
- servers beyond IP restrictions and custom headers:
90
+ ### Mutual TLS (mTLS)
104
91
 
105
- ### Mutual TLS (mTLS) Authentication
92
+ Mutual TLS authenticates Akamai with a certificate instead of a header value.
93
+ It's the strongest option, and there's no secret in the request for anything
94
+ downstream to log or leak.
106
95
 
107
- Use mutual TLS to establish secure, certificate-based authentication between
108
- Akamai edge servers and your origin. This ensures only authenticated Akamai
109
- servers can connect to your backend.
96
+ 1. In Akamai, upload a client certificate to the
97
+ [mTLS Origin Keystore](https://techdocs.akamai.com/property-mgr/docs/mtls-origin-keystore)
98
+ and attach it to your property's origin.
99
+ 2. In Zuplo, upload the CA certificate that issued it and add the
100
+ [`mtls-auth-inbound`](/docs/policies/mtls-auth-inbound) policy to your
101
+ routes. See
102
+ [Client mTLS authentication](./securing-the-gateway-with-client-mtls.mdx).
110
103
 
111
- Learn more:
112
- [mTLS Origin Keystore](https://techdocs.akamai.com/property-mgr/docs/mtls-origin-keystore)
104
+ Use a CA that issues certificates only for Akamai. CA certificates in Zuplo are
105
+ scoped to your account, so any client certificate that the CA issues passes the
106
+ check.
113
107
 
114
- ### Origin IP Access Control List
108
+ ### IP-Based Restrictions
115
109
 
116
- Configure an IP-based access control list that specifically defines which Akamai
117
- IP addresses can access your origin servers. This provides more granular control
118
- than general IP restrictions.
119
-
120
- Learn more:
121
- [Origin IP ACL](https://techdocs.akamai.com/origin-ip-acl/docs/welcome)
110
+ Akamai maintains a list of IP addresses that you can use to restrict access to
111
+ your Zuplo Gateway. This is a good way to ensure that only Akamai can access
112
+ your gateway. However, Akamai is a multi-tenant service, so this method isn't
113
+ enough on its own to keep unauthorized traffic from reaching your gateway. Use
114
+ it **in addition to** a shared secret header or mTLS, never instead of one.
115
+
116
+ 1. In Akamai, add the
117
+ [Origin IP Access Control List](https://techdocs.akamai.com/origin-ip-acl/docs/set-up-origin-ip-acl)
118
+ behavior to your property, in the same rule as the Origin Server behavior.
119
+ Without this behavior, requests to your origin can come from any Akamai edge
120
+ address, not just the Origin IP ACL ranges.
121
+ 2. In Zuplo, add the
122
+ [IP Address Restriction](/docs/policies/ip-address-restriction-inbound)
123
+ policy with the
124
+ [Origin IP ACL ranges](https://techdocs.akamai.com/origin-ip-acl/docs/update-your-origin-server).
125
+ The ranges below were current when this page was written. Check Akamai's list
126
+ before you use them.
122
127
 
123
- ### Site Shield
128
+ ```json
129
+ {
130
+ "name": "allow-akamai-ips",
131
+ "policyType": "ip-address-restriction-inbound",
132
+ "handler": {
133
+ "export": "IpAddressRestrictionInboundPolicy",
134
+ "module": "$import(@zuplo/runtime)",
135
+ "options": {
136
+ "allow": [
137
+ "2.16.0.0/13",
138
+ "23.0.0.0/12",
139
+ "23.192.0.0/11",
140
+ "23.32.0.0/11",
141
+ "95.100.0.0/15",
142
+ "184.24.0.0/13",
143
+ "2a02:26f0::/32",
144
+ "2600:1400::/24",
145
+ "2405:9600::/32"
146
+ ]
147
+ }
148
+ }
149
+ }
150
+ ```
124
151
 
125
- Site Shield provides a dedicated set of IP addresses that Akamai uses to connect
126
- to your origin servers. This creates a more predictable and secure connection
127
- pattern between Akamai and your backend infrastructure.
152
+ Akamai changes these ranges from time to time and announces the changes through
153
+ the Firewall Rules Notification tool.
154
+ [Subscribe to it](https://techdocs.akamai.com/firewall-rules/docs/subscribe-to-notifications)
155
+ so you can update the policy before old ranges are retired.
128
156
 
129
- Learn more:
130
157
  [Site Shield](https://techdocs.akamai.com/site-shield/docs/welcome-site-shield)
131
-
132
- ### Authentication Token 2.0
133
-
134
- Implement token-based authentication for origin requests. This method allows you
135
- to validate that requests are coming from legitimate Akamai edge servers using
136
- cryptographic tokens.
137
-
138
- Learn more:
139
- [Auth Token 2.0](https://techdocs.akamai.com/property-mgr/docs/auth-token-2-0-ver)
140
-
141
- ### Custom Request Headers with Shared Secrets
142
-
143
- Configure Akamai to modify incoming request headers and add shared secret values
144
- that your origin can validate. This is similar to the custom header approach
145
- mentioned above but provides more advanced header manipulation capabilities.
146
-
147
- Learn more:
148
- [Modify Incoming Request Header](https://techdocs.akamai.com/property-mgr/docs/modify-incoming-req-header)
149
-
150
- These security measures can be used individually or combined to create multiple
151
- layers of protection for your Zuplo Gateway when running behind Akamai App & API
152
- Protector.
158
+ is an alternative to Origin IP ACL that uses a smaller set of addresses. Like
159
+ Origin IP ACL, it restricts where traffic comes from but doesn't authenticate
160
+ your property, so pair it with a shared secret header or mTLS.
@@ -22,8 +22,9 @@ components:
22
22
  Zuplo Gateway instances based on geographic location, health status, and load
23
23
  balancing policies.
24
24
  3. **Zuplo Gateway** - Deployed on Akamai Connected Cloud, the gateway handles
25
- authentication, authorization, rate limiting, and request routing. Origin IP
26
- ACL ensures only Akamai edge servers can reach the gateway.
25
+ authentication, authorization, rate limiting, and request routing. A shared
26
+ secret header or mTLS ensures only your Akamai property can reach the
27
+ gateway.
27
28
  4. **Backend Services** - Your origin servers can be hosted on Akamai compute,
28
29
  customer VPCs, on-premise data centers, or public cloud providers.
29
30
 
@@ -55,7 +56,7 @@ to Zuplo and your backend services:
55
56
  </DiagramGroup>
56
57
  <DiagramEdge from="client" to="cdn" />
57
58
  <DiagramEdge from="cdn" to="gtm" fromSide="bottom" toSide="top" />
58
- <DiagramEdge from="gtm" to="gateway" label="Origin IP ACL" />
59
+ <DiagramEdge from="gtm" to="gateway" label="Shared secret or mTLS" />
59
60
  <DiagramEdge from="gateway" to="backend" />
60
61
  </Diagram>
61
62
 
@@ -66,8 +67,9 @@ to Zuplo and your backend services:
66
67
  2. **CDN to GTM** - The edge server forwards the request to Akamai Global
67
68
  Traffic Manager, which determines the optimal Zuplo instance to handle the
68
69
  request.
69
- 3. **GTM to Zuplo** - GTM routes the request to a Zuplo Gateway. Origin IP ACL
70
- ensures only traffic from Akamai's edge network reaches the gateway.
70
+ 3. **GTM to Zuplo** - GTM routes the request to a Zuplo Gateway. The gateway
71
+ accepts the request only if it carries your shared secret header or presents
72
+ your mTLS client certificate.
71
73
  4. **Zuplo to Backend** - The Zuplo Gateway processes the request (applying
72
74
  policies, authentication, rate limiting) and forwards it to your backend
73
75
  services.
@@ -91,23 +93,31 @@ to continuously monitor the health of your Zuplo deployments. When a gateway
91
93
  fails health checks, GTM automatically routes traffic to healthy instances,
92
94
  providing seamless failover.
93
95
 
94
- ### Secure connectivity with Origin IP ACL
96
+ ### Securing the connection from Akamai to Zuplo
95
97
 
96
- The connection between Akamai edge servers and Zuplo Gateways uses
97
- [Origin IP ACL](https://techdocs.akamai.com/origin-ip-acl/docs/welcome) to
98
- restrict access to the gateway. Origin IP ACL ensures that only requests from
99
- Akamai's edge network can reach your Zuplo origin. This provides:
98
+ Every request that reaches the gateway must prove it came from **your** Akamai
99
+ property. We recommend one of these:
100
100
 
101
- - **Origin protection** - Requests to your Zuplo gateway can only originate from
102
- Akamai's edge servers
103
- - **Simplified management** - Akamai maintains a stable list of CIDR blocks to
104
- configure in your firewall
105
- - **Automatic updates** - Subscribe to Akamai's Firewall Rules Notification tool
106
- to receive alerts when IP ranges change
101
+ - **Shared secret header** - Akamai adds a secret header to every request it
102
+ forwards, using the
103
+ [Modify Incoming Request Header](https://techdocs.akamai.com/property-mgr/docs/modify-incoming-req-header)
104
+ behavior. The gateway rejects requests without it.
105
+ - **Mutual TLS** - Akamai presents a client certificate from its
106
+ [mTLS Origin Keystore](https://techdocs.akamai.com/property-mgr/docs/mtls-origin-keystore),
107
+ and the gateway rejects connections without one.
107
108
 
108
- All traffic between Akamai edge and origin uses TLS encryption. Origin IP ACL
109
- adds an additional layer of access control by restricting which IP addresses can
110
- connect to your gateway.
109
+ You can add
110
+ [Origin IP ACL](https://techdocs.akamai.com/origin-ip-acl/docs/welcome) as an
111
+ extra layer that limits connections to Akamai's edge IP addresses. Don't use it
112
+ on its own: the Origin IP ACL ranges are shared by every Akamai customer, and
113
+ Akamai
114
+ [states](https://techdocs.akamai.com/origin-ip-acl/docs/recommendations-and-caveats)
115
+ that it "isn't a substitute for authentication".
116
+
117
+ For setup steps for each option, see
118
+ [Securing Zuplo from direct access](../../articles/waf-ddos-akamai.md#securing-zuplo-from-direct-access).
119
+
120
+ All traffic between Akamai edge and origin uses TLS encryption.
111
121
 
112
122
  ## Multi-region deployment
113
123
 
@@ -266,7 +276,6 @@ deployment, see [Setting up Akamai CDNs](./cdn.mdx). This guide covers:
266
276
 
267
277
  - Property hostname configuration for Zuplo Gateway and developer portal
268
278
  - Origin server settings with host header forwarding
269
- - Origin IP ACL configuration for secure edge-to-origin connectivity
270
279
  - Caching behaviors for API responses
271
280
 
272
281
  ## Next steps
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Setting up Akamai CDNs
3
- sidebar_label: Akamai CDN
3
+ sidebar_label: CDN Setup
4
4
  ---
5
5
 
6
6
  <!-- vale Vale.Spelling["Edgescape","Maxage"] = NO -->
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: "Managed Dedicated: AWS Architecture"
3
+ sidebar_label: Architecture
4
+ description:
5
+ How a Zuplo Managed Dedicated instance runs on AWS, and what you need to know
6
+ to connect clients and backends to it.
7
+ ---
8
+
9
+ A Managed Dedicated instance on AWS runs in its own VPC, in an AWS account that
10
+ Zuplo manages, in the AWS region you choose. Zuplo provisions, operates, scales,
11
+ and upgrades the instance. You don't need an AWS account to use it, but you need
12
+ one to connect it to backends in your own VPC.
13
+
14
+ For the components that make up every Managed Dedicated instance, see
15
+ [Architecture](../architecture.mdx).
16
+
17
+ ## Availability
18
+
19
+ The gateway runs across multiple availability zones in your region, and the load
20
+ balancer in front of it spreads traffic across zones. If one zone fails, the
21
+ other zones keep serving traffic.
22
+
23
+ To run in more than one region, contact your account manager.
24
+
25
+ ## Inbound traffic
26
+
27
+ Clients reach the gateway through a public, internet-facing load balancer. Zuplo
28
+ terminates TLS and manages the certificates, including for your
29
+ [custom domains](../custom-domains.mdx).
30
+
31
+ To put a CDN or WAF, such as Amazon CloudFront with AWS WAF, in front of the
32
+ gateway, make sure clients can't bypass it and call the gateway directly. Have
33
+ the CDN add a shared secret header that the gateway checks, or authenticate the
34
+ CDN with
35
+ [client mTLS](../../articles/securing-the-gateway-with-client-mtls.mdx).
36
+
37
+ ## Outbound traffic and IP addresses
38
+
39
+ The gateway reaches the internet through NAT gateways, one per availability
40
+ zone, each with a fixed public IP address. If your backend or a third-party API
41
+ allowlists callers by IP address, ask your account manager for these addresses.
42
+
43
+ ## Connecting to your backends
44
+
45
+ The gateway can call any backend it can reach over the internet. To keep backend
46
+ traffic off the public internet, use PrivateLink, VPC peering, or Transit
47
+ Gateway. See [AWS Private Networking](./private-networking.mdx).
48
+
49
+ However your backend is reached, make sure it only accepts requests from your
50
+ gateway. See [Securing your backend](../../articles/securing-your-backend.mdx).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Managed Dedicated: AWS Private Networking"
3
- sidebar_label: AWS Private Networking
3
+ sidebar_label: Private Networking
4
4
  ---
5
5
 
6
6
  Zuplo Managed Dedicated can run on AWS and connect privately to backends that
@@ -133,7 +133,7 @@ patterns to expect.
133
133
 
134
134
  ## Next steps
135
135
 
136
- - Review the general [Managed Dedicated networking](./networking.mdx) overview
137
- - Review [Managed Dedicated architecture](./architecture.mdx)
136
+ - Review the general [Managed Dedicated networking](../networking.mdx) overview
137
+ - Review [Managed Dedicated architecture](../architecture.mdx)
138
138
  - [Schedule time with Zuplo](https://book.zuplo.com) to review your AWS network
139
139
  design
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: "Managed Dedicated: Azure Architecture"
3
+ sidebar_label: Architecture
4
+ description:
5
+ How a Zuplo Managed Dedicated instance runs on Azure, and what you need to
6
+ know to connect clients and backends to it.
7
+ ---
8
+
9
+ A Managed Dedicated instance on Azure runs in its own virtual network (VNet), in
10
+ an Azure subscription that Zuplo manages, in the Azure region you choose. Zuplo
11
+ provisions, operates, scales, and upgrades the instance. You don't need an Azure
12
+ subscription to use it, but you need one to connect it to backends in your own
13
+ VNet.
14
+
15
+ For the components that make up every Managed Dedicated instance, see
16
+ [Architecture](../architecture.mdx).
17
+
18
+ ## Availability
19
+
20
+ The gateway runs across the availability zones in your region. If one zone
21
+ fails, the other zones keep serving traffic.
22
+
23
+ To run in more than one region, contact your account manager.
24
+
25
+ ## Inbound traffic
26
+
27
+ Clients reach the gateway through a public load balancer. Zuplo terminates TLS
28
+ and manages the certificates, including for your
29
+ [custom domains](../custom-domains.mdx).
30
+
31
+ To put a CDN or WAF, such as Azure Front Door, in front of the gateway, make
32
+ sure clients can't bypass it and call the gateway directly. Have the CDN add a
33
+ shared secret header that the gateway checks, or authenticate the CDN with
34
+ [client mTLS](../../articles/securing-the-gateway-with-client-mtls.mdx).
35
+
36
+ ## Outbound traffic and IP addresses
37
+
38
+ The gateway reaches the internet through a NAT gateway with a fixed public IP
39
+ address. If your backend or a third-party API allowlists callers by IP address,
40
+ ask your account manager for this address.
41
+
42
+ ## Connecting to your backends
43
+
44
+ The gateway can call any backend it can reach over the internet. To keep backend
45
+ traffic off the public internet, use Private Endpoint or VNet peering. See
46
+ [Azure Private Networking](./private-networking.mdx).
47
+
48
+ However your backend is reached, make sure it only accepts requests from your
49
+ gateway. See [Securing your backend](../../articles/securing-your-backend.mdx).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Managed Dedicated: Azure Private Networking"
3
- sidebar_label: Azure Private Networking
3
+ sidebar_label: Private Networking
4
4
  ---
5
5
 
6
6
  Zuplo Managed Dedicated can run on Azure and connect privately to backends that
@@ -160,7 +160,7 @@ patterns to expect.
160
160
 
161
161
  ## Next steps
162
162
 
163
- - Review the general [Managed Dedicated networking](./networking.mdx) overview
164
- - Review [Managed Dedicated architecture](./architecture.mdx)
163
+ - Review the general [Managed Dedicated networking](../networking.mdx) overview
164
+ - Review [Managed Dedicated architecture](../architecture.mdx)
165
165
  - [Schedule time with Zuplo](https://book.zuplo.com) to review your Azure
166
166
  network design
@@ -20,7 +20,7 @@ expects aren't the same:
20
20
  web server hosts several sites and picks one based on the `Host` header. Your
21
21
  gateway connects to the shared address and names the site it wants.
22
22
  - **Private networking.** With
23
- [private networking](../aws-private-networking.mdx), you reach a backend
23
+ [private networking](../aws/private-networking.mdx), you reach a backend
24
24
  through an internal endpoint or IP whose DNS name doesn't match the public
25
25
  hostname the backend is configured for, such as `https://10.0.4.12` with a
26
26
  `Host` of `api.acme.com`.
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: "Managed Dedicated: Configuration"
3
+ sidebar_label: Overview
4
+ description: Settings in zuplo.jsonc that apply to Managed Dedicated projects.
5
+ ---
6
+
7
+ Managed Dedicated projects use the same `zuplo.jsonc` file as every other Zuplo
8
+ project. A few settings in that file are specific to Managed Dedicated. This
9
+ page lists them. For every other setting, see
10
+ [Project Configuration](../../programmable-api/zuplo-json.mdx).
11
+
12
+ ```jsonc
13
+ {
14
+ "version": 1,
15
+ "projectType": "managed-dedicated",
16
+ }
17
+ ```
18
+
19
+ ## Managed Dedicated settings
20
+
21
+ | Setting | Description |
22
+ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
23
+ | `projectType` | Set to `"managed-dedicated"` for projects that deploy to a Managed Dedicated instance. |
24
+ | `allowHostHeaderOverride` | Lets your code set a `Host` header that differs from the request URL. Off by default. See [Host Header Override](./host-header-override.mdx). |
25
+
26
+ ## Editing zuplo.jsonc
27
+
28
+ The `zuplo.jsonc` file isn't editable in the Zuplo Portal. Connect your project
29
+ to [source control](../source-control.mdx) and edit the file there, or push a
30
+ local change with git. Changes take effect on your next deployment.
@@ -0,0 +1,51 @@
1
+ ---
2
+ title: "Managed Dedicated: GCP Architecture"
3
+ sidebar_label: Architecture
4
+ description:
5
+ How a Zuplo Managed Dedicated instance runs on Google Cloud, and what you need
6
+ to know to connect clients and backends to it.
7
+ ---
8
+
9
+ A Managed Dedicated instance on Google Cloud runs in its own VPC network, in a
10
+ Google Cloud project that Zuplo manages, in the region you choose. Zuplo
11
+ provisions, operates, scales, and upgrades the instance. You don't need a Google
12
+ Cloud project to use it, but you need one to connect it to backends in your own
13
+ VPC.
14
+
15
+ For the components that make up every Managed Dedicated instance, see
16
+ [Architecture](../architecture.mdx).
17
+
18
+ ## Availability
19
+
20
+ The gateway runs across multiple zones in your region. If one zone fails, the
21
+ other zones keep serving traffic.
22
+
23
+ To run in more than one region, contact your account manager.
24
+
25
+ ## Inbound traffic
26
+
27
+ Clients reach the gateway through a public load balancer. Zuplo terminates TLS
28
+ and manages the certificates, including for your
29
+ [custom domains](../custom-domains.mdx).
30
+
31
+ To put a CDN or WAF, such as Cloud CDN with Google Cloud Armor, in front of the
32
+ gateway, make sure clients can't bypass it and call the gateway directly. Have
33
+ the CDN add a shared secret header that the gateway checks, or authenticate the
34
+ CDN with
35
+ [client mTLS](../../articles/securing-the-gateway-with-client-mtls.mdx).
36
+
37
+ ## Outbound traffic and IP addresses
38
+
39
+ The gateway reaches the internet through Cloud NAT. By default, these outbound
40
+ IP addresses aren't reserved and can change. If your backend or a third-party
41
+ API allowlists callers by IP address, ask your account manager to reserve
42
+ outbound addresses for your instance before you rely on them.
43
+
44
+ ## Connecting to your backends
45
+
46
+ The gateway can call any backend it can reach over the internet. To keep backend
47
+ traffic off the public internet, use Private Service Connect or VPC Network
48
+ Peering. See [GCP Private Networking](./private-networking.mdx).
49
+
50
+ However your backend is reached, make sure it only accepts requests from your
51
+ gateway. See [Securing your backend](../../articles/securing-your-backend.mdx).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Managed Dedicated: GCP Private Networking"
3
- sidebar_label: GCP Private Networking
3
+ sidebar_label: Private Networking
4
4
  ---
5
5
 
6
6
  Zuplo Managed Dedicated can run on Google Cloud and connect privately to
@@ -118,7 +118,7 @@ patterns to expect.
118
118
 
119
119
  ## Next steps
120
120
 
121
- - Review the general [Managed Dedicated networking](./networking.mdx) overview
122
- - Review [Managed Dedicated architecture](./architecture.mdx)
121
+ - Review the general [Managed Dedicated networking](../networking.mdx) overview
122
+ - Review [Managed Dedicated architecture](../architecture.mdx)
123
123
  - [Schedule time with Zuplo](https://book.zuplo.com) to review your GCP network
124
124
  design
@@ -24,11 +24,13 @@ To discuss your networking requirements, please contact your account manager.
24
24
  ## Cloud-specific guidance
25
25
 
26
26
  - For AWS private backend connectivity, see
27
- [AWS Private Networking](./aws-private-networking.mdx)
27
+ [AWS Private Networking](./aws/private-networking.mdx)
28
28
  - For Azure private backend connectivity, see
29
- [Azure Private Networking](./azure-private-networking.mdx)
29
+ [Azure Private Networking](./azure/private-networking.mdx)
30
30
  - For Google Cloud private backend connectivity, see
31
- [GCP Private Networking](./gcp-private-networking.mdx)
31
+ [GCP Private Networking](./gcp/private-networking.mdx)
32
+ - For Akamai Connected Cloud, see
33
+ [Akamai Dedicated Architecture](./akamai/architecture.mdx)
32
34
 
33
35
  ## Zuplo Ingress to Customer Private Network
34
36
 
@@ -26,10 +26,14 @@ Managed Dedicated hosting might be the right choice for you if you need:
26
26
  Zuplo Managed Dedicated can be deployed on a wide range of cloud providers and
27
27
  hosting platforms, including:
28
28
 
29
- - **Akamai Connected Cloud** - Leverage Akamai's global network infrastructure
30
- - **AWS** - Deploy to Amazon Web Services with full VPC integration
31
- - **Azure** - Run on Microsoft Azure with private networking support
32
- - **GCP** - Deploy to Google Cloud Platform with custom networking
29
+ - **[Akamai Connected Cloud](./akamai/architecture.mdx)** - Leverage Akamai's
30
+ global network infrastructure
31
+ - **[AWS](./aws/architecture.mdx)** - Deploy to Amazon Web Services with full
32
+ VPC integration
33
+ - **[Azure](./azure/architecture.mdx)** - Run on Microsoft Azure with private
34
+ networking support
35
+ - **[GCP](./gcp/architecture.mdx)** - Deploy to Google Cloud Platform with
36
+ custom networking
33
37
  - **Equinix** - Use Equinix data centers for colocation and connectivity
34
38
  - **TerraSwitch** - Deploy to TerraSwitch infrastructure
35
39
  - **Other providers** - Contact us to discuss support for additional providers
@@ -50,21 +50,7 @@ If you don't have an Auth0 account, you can sign up for a
50
50
 
51
51
  Keep the default **Refresh Token Expiration** settings unless you have specific requirements.
52
52
 
53
- 3. Create an Auth0 API:
54
- - Navigate to the [APIs section](https://manage.auth0.com/#/apis) in the Auth0 dashboard
55
- - Click **Create API**
56
- - Set a name (e.g., "Dev Portal API") and an identifier (e.g., `https://your-domain.com/api`)
57
- - Choose **RS256** as the signing algorithm
58
- - Save the API
59
-
60
- :::warning
61
-
62
- This step is important. If you skip creating an API, Dev Portal will not be able to validate the
63
- tokens issued by Auth0, leading to authentication failures.
64
-
65
- :::
66
-
67
- 4. **Configure Zudoku**
53
+ 3. **Configure Zudoku**
68
54
 
69
55
  Add the Auth0 configuration to your [Dev Portal configuration file](./overview.md):
70
56
 
@@ -76,7 +62,6 @@ If you don't have an Auth0 account, you can sign up for a
76
62
  type: "auth0",
77
63
  domain: "your-domain.us.auth0.com",
78
64
  clientId: "<your-auth0-client-id>",
79
- audience: "https://your-domain.com/api", // Your Auth0 API identifier
80
65
  },
81
66
  // ... other configuration
82
67
  };
@@ -85,7 +70,36 @@ If you don't have an Auth0 account, you can sign up for a
85
70
  Where:
86
71
  - **domain**: Your Auth0 domain (found in your application's Basic Information)
87
72
  - **clientId**: The Client ID from your Auth0 application settings
88
- - **audience**: The identifier of the Auth0 API you created (e.g., `https://your-domain.com/api`)
73
+
74
+ 4. **(Optional) Configure an audience for API access**
75
+
76
+ Only configure an `audience` if you need the access token to call a specific API (for example,
77
+ when using the API playground to send authenticated requests to your backend). Without an
78
+ audience, Auth0 issues an opaque token that can be used to identify the user via `/userinfo` —
79
+ which is all Dev Portal needs for sign-in and protected routes.
80
+
81
+ :::tip
82
+
83
+ Avoid setting an audience when you don't need it. Issuing an access token scoped to an API when
84
+ it isn't going to call that API gives the token broader privileges than necessary.
85
+
86
+ :::
87
+
88
+ If you do need API access:
89
+ - Navigate to the [APIs section](https://manage.auth0.com/#/apis) in the Auth0 dashboard
90
+ - Click **Create API**, set a name (e.g., "Dev Portal API") and an identifier (e.g.,
91
+ `https://your-domain.com/api`)
92
+ - Choose **RS256** as the signing algorithm and save the API
93
+ - Add the identifier to your Dev Portal configuration:
94
+
95
+ ```typescript
96
+ authentication: {
97
+ type: "auth0",
98
+ domain: "your-domain.us.auth0.com",
99
+ clientId: "<your-auth0-client-id>",
100
+ audience: "https://your-domain.com/api", // Your Auth0 API identifier
101
+ }
102
+ ```
89
103
 
90
104
  </Stepper>
91
105
 
@@ -188,8 +202,9 @@ authentication: {
188
202
  3. **Authentication Loop**: Check that your Auth0 domain is a plain hostname only (e.g.,
189
203
  `your-domain.us.auth0.com`) without a protocol prefix (`https://`) or trailing slash.
190
204
 
191
- 4. **Token Validation Errors**: Ensure the audience in your Dev Portal configuration matches the
192
- identifier of the Auth0 API you created.
205
+ 4. **Token Validation Errors**: If you've configured an `audience`, make sure it matches the
206
+ identifier of the Auth0 API you created. If you don't need to call an API, remove `audience` from
207
+ your configuration — Auth0 will issue an opaque token suitable for `/userinfo`.
193
208
 
194
209
  ## Next Steps
195
210
 
@@ -284,12 +284,16 @@ URL.
284
284
  // ...
285
285
  "redirects": [
286
286
  { "from": "/", "to": "/documentation/introduction" },
287
- { "from": "/documentation", "to": "/documentation/introduction" }
287
+ { "from": "/documentation", "to": "/documentation/introduction" },
288
+ { "from": "/blog/:slug", "to": "/posts/:slug" }
288
289
  ]
289
290
  // ...
290
291
  }
291
292
  ```
292
293
 
294
+ `from` paths can contain `:param` segments and a trailing `*` wildcard. See
295
+ [Redirects](/dev-portal/zudoku/guides/redirects#path-parameters-and-wildcards) for details.
296
+
293
297
  ### `port`
294
298
 
295
299
  The port on which the development server will run. Defaults to `3000`. This option can also be
@@ -52,6 +52,43 @@ redirects: [{ from: "/old-page", to: "/new-page" }];
52
52
  Trailing slashes in the `from` path are normalized automatically. Both `/old-page` and `/old-page/`
53
53
  will match the same redirect rule.
54
54
 
55
+ ## Path parameters and wildcards
56
+
57
+ A `from` path can match more than one URL. Use `:name` for a single path segment and a trailing `*`
58
+ for everything after a prefix. Reference the same tokens in `to` to carry the matched values over:
59
+
60
+ ```ts
61
+ redirects: [
62
+ // /blog/hello-world → /posts/hello-world
63
+ { from: "/blog/:slug", to: "/posts/:slug" },
64
+ // /v1/guides/auth/tokens → /guides/auth/tokens
65
+ { from: "/v1/*", to: "/*" },
66
+ // /dashboard/apps/42 → https://dashboard.example.com/apps/42
67
+ { from: "/dashboard/*", to: "https://dashboard.example.com/*" },
68
+ ];
69
+ ```
70
+
71
+ - **`:name`** matches exactly one segment. Add `?` (`:name?`) to make it optional.
72
+ - **`*`** must be the last segment of `from`. It also matches the prefix itself, so `/dashboard/*`
73
+ redirects `/dashboard` too. In that case the `/*` in `to` is dropped, leaving `/` if nothing else
74
+ remains.
75
+ - In `to`, `/:name` and `/*` must each fill a whole path segment, so `/posts/:slug` works and
76
+ `/posts-:slug` doesn't. Tokens that don't appear in `from` are left as they are.
77
+ - Dev Portal doesn't copy the incoming query string to the target.
78
+
79
+ Pages in your portal take precedence over a wildcard redirect, so `{ from: "/docs/*", to: "/" }`
80
+ still lets visitors reach `/docs/introduction` if that page exists.
81
+
82
+ Static hosts can't prerender a file for every URL a pattern matches, so pattern redirects behave
83
+ differently from exact ones:
84
+
85
+ - **Zuplo** and **Vercel**: Dev Portal turns the pattern into a regular-expression route in the build
86
+ output, and the platform returns an HTTP **301**.
87
+ - **SSR deployments**: the server returns an HTTP 301, the same as exact redirects.
88
+ - **Other static hosts**: no redirect file is written. If your host serves `404.html` (or your app's
89
+ `index.html`) for unknown paths, the page loads, Dev Portal matches the pattern, and the browser is
90
+ redirected. Otherwise, set up the redirect in your host's own configuration.
91
+
55
92
  ## How redirects work
56
93
 
57
94
  Dev Portal redirects operate at two levels depending on how the visitor reaches the page:
@@ -90,8 +90,8 @@ to `false`.
90
90
  Allow the Host header to be overridden by the client. This configuration
91
91
  defaults to `false`. This is only supported in managed dedicated environments.
92
92
  Only enable this setting if you understand the implications. See
93
- [Host Header Override](../dedicated/advanced/host-header-override.mdx) for when
94
- to use it and an example.
93
+ [Host Header Override](../dedicated/configuration/host-header-override.mdx) for
94
+ when to use it and an example.
95
95
 
96
96
  ```jsonc
97
97
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "7.10.0",
3
+ "version": "7.11.1",
4
4
  "type": "module",
5
5
  "description": "The official Zuplo CLI for local development and platform management",
6
6
  "homepage": "https://zuplo.com/docs/cli/overview",
@@ -32,9 +32,9 @@
32
32
  "zuplo": "zuplo.js"
33
33
  },
34
34
  "dependencies": {
35
- "@zuplo/cli": "7.10.0",
36
- "@zuplo/core": "7.10.0",
37
- "@zuplo/runtime": "7.10.0",
38
- "@zuplo/test": "7.10.0"
35
+ "@zuplo/cli": "7.11.1",
36
+ "@zuplo/core": "7.11.1",
37
+ "@zuplo/runtime": "7.11.1",
38
+ "@zuplo/test": "7.11.1"
39
39
  }
40
40
  }