zuplo 7.9.8 → 7.9.11
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/dev-portal/zudoku/configuration/api-reference.md +2 -0
- package/docs/dev-portal/zudoku/configuration/authentication-openid.md +27 -5
- package/docs/dev-portal/zudoku/configuration/authentication.md +25 -0
- package/docs/dev-portal/zudoku/configuration/footer.mdx +4 -2
- package/docs/dev-portal/zudoku/configuration/protected-routes.md +9 -1
- package/docs/dev-portal/zudoku/configuration/site.md +2 -1
- package/docs/dev-portal/zudoku/guides/processors.mdx +8 -0
- package/docs/dev-portal/zudoku/openapi-extensions/x-internal.md +88 -0
- package/docs/policies/ai-gateway-auth-inbound/doc.md +25 -0
- package/docs/policies/ai-gateway-auth-inbound/schema.json +2 -1
- package/package.json +5 -5
|
@@ -399,6 +399,8 @@ different levels of your API documentation.
|
|
|
399
399
|
### Operations
|
|
400
400
|
|
|
401
401
|
- `x-zudoku-playground-enabled`: Control playground visibility for an operation (default: `true`)
|
|
402
|
+
- `x-internal`: Hide an operation from the documentation. Also works on path items and parameters.
|
|
403
|
+
See [`x-internal`](../openapi-extensions/x-internal)
|
|
402
404
|
- `x-explorer-enabled`: Alias for `x-zudoku-playground-enabled` for compatibility Example:
|
|
403
405
|
|
|
404
406
|
```json
|
|
@@ -28,11 +28,12 @@ Add the `authentication` property to your [Dev Portal configuration](./overview.
|
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
| Option
|
|
32
|
-
|
|
|
33
|
-
| `clientId`
|
|
34
|
-
| `issuer`
|
|
35
|
-
| `scopes`
|
|
31
|
+
| Option | Required | Description |
|
|
32
|
+
| ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| `clientId` | Yes | The OAuth client ID issued by your provider. |
|
|
34
|
+
| `issuer` | Yes | The issuer URL. Dev Portal discovers endpoints from `<issuer>/.well-known/openid-configuration`. |
|
|
35
|
+
| `scopes` | No | Scopes to request. Defaults to `["openid", "profile", "email"]`. |
|
|
36
|
+
| `allowInsecureRequests` | No | Allow discovery and token requests against an `http://` issuer. Defaults to `false`. Intended only for local development — never enable this in production. |
|
|
36
37
|
|
|
37
38
|
## Provider Setup
|
|
38
39
|
|
|
@@ -126,6 +127,27 @@ After sign-in Dev Portal calls the provider's
|
|
|
126
127
|
`name`, `email`, `picture`, and `email_verified` from the response. Map these claims in your
|
|
127
128
|
provider if they are not emitted by default.
|
|
128
129
|
|
|
130
|
+
## Local Development with an HTTP Issuer
|
|
131
|
+
|
|
132
|
+
`oauth4webapi` (the library Dev Portal uses under the hood) rejects issuers that don't use `https://` by
|
|
133
|
+
default, since OIDC requires TLS in production. If you're running an identity provider locally over
|
|
134
|
+
plain HTTP (e.g. a dockerized Keycloak on `http://localhost:9090`), set `allowInsecureRequests` to
|
|
135
|
+
`true` so discovery and token requests are allowed to use `http://`:
|
|
136
|
+
|
|
137
|
+
```typescript title="zudoku.config.ts"
|
|
138
|
+
{
|
|
139
|
+
authentication: {
|
|
140
|
+
type: "openid",
|
|
141
|
+
clientId: "<your-client-id>",
|
|
142
|
+
issuer: "http://localhost:9090/auth/realms/<your-realm>",
|
|
143
|
+
allowInsecureRequests: true,
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Only enable this for local development. Never set `allowInsecureRequests` to `true` against a
|
|
149
|
+
production issuer.
|
|
150
|
+
|
|
129
151
|
## Troubleshooting
|
|
130
152
|
|
|
131
153
|
- **Discovery fails**: verify `<issuer>/.well-known/openid-configuration` resolves and matches the
|
|
@@ -214,6 +214,31 @@ fields are used to display the user profile:
|
|
|
214
214
|
|
|
215
215
|
If the provider does not return a field, it will be left blank.
|
|
216
216
|
|
|
217
|
+
## Redirects after sign-in
|
|
218
|
+
|
|
219
|
+
By default, users return to the page they started from after signing in. For
|
|
220
|
+
[protected routes](./protected-routes.md) that is the path and query string they tried to open; for
|
|
221
|
+
`useAuth().login({ redirectTo })` it is the `redirectTo` you pass.
|
|
222
|
+
|
|
223
|
+
Setting `redirectToAfterSignIn` overrides that return URL: every sign-in lands on the configured
|
|
224
|
+
path instead. Only set it if you always want users to land on the same page, and leave it unset to
|
|
225
|
+
return users to where they were. `redirectToAfterSignUp` behaves the same way for sign-up.
|
|
226
|
+
|
|
227
|
+
```typescript title="zudoku.config.ts"
|
|
228
|
+
{
|
|
229
|
+
authentication: {
|
|
230
|
+
type: "auth0",
|
|
231
|
+
// ...
|
|
232
|
+
// Omit to return users to the page they came from
|
|
233
|
+
redirectToAfterSignIn: "/docs",
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
This applies to all built-in providers. For Supabase social (OAuth) sign-in, the return URL must
|
|
239
|
+
also be allowed under **Redirect URLs** in your Supabase project's authentication settings, and a
|
|
240
|
+
return URL on another origin falls back to your site's root.
|
|
241
|
+
|
|
217
242
|
## Protected Routes
|
|
218
243
|
|
|
219
244
|
Once authentication is configured, you can protect specific routes in your documentation to require
|
|
@@ -143,7 +143,8 @@ footer: {
|
|
|
143
143
|
dark: "/path/to/dark-logo.png"
|
|
144
144
|
},
|
|
145
145
|
alt: "Company Logo",
|
|
146
|
-
width:
|
|
146
|
+
width: 120, // optional intrinsic width
|
|
147
|
+
height: 24 // optional intrinsic height; set both to prevent layout shift
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
150
|
```
|
|
@@ -208,7 +209,8 @@ footer: {
|
|
|
208
209
|
dark: "/images/logo-dark.svg"
|
|
209
210
|
},
|
|
210
211
|
alt: "Company Logo",
|
|
211
|
-
width:
|
|
212
|
+
width: 100,
|
|
213
|
+
height: 24
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
```
|
|
@@ -45,7 +45,15 @@ authenticated to access these routes.
|
|
|
45
45
|
|
|
46
46
|
When a user tries to access a protected route, a login dialog will appear prompting them to sign in
|
|
47
47
|
or register. After logging in, they are automatically redirected back to the route they were trying
|
|
48
|
-
to access.
|
|
48
|
+
to access, including its query string.
|
|
49
|
+
|
|
50
|
+
:::caution{title="redirectToAfterSignIn takes precedence"}
|
|
51
|
+
|
|
52
|
+
If `authentication.redirectToAfterSignIn` is set, users are sent to that path after every sign-in
|
|
53
|
+
instead of the page they were trying to open. Leave it unset to return users to where they were. See
|
|
54
|
+
[Redirects after sign-in](./authentication.md#redirects-after-sign-in).
|
|
55
|
+
|
|
56
|
+
:::
|
|
49
57
|
|
|
50
58
|
## Object Format
|
|
51
59
|
|
|
@@ -58,7 +58,8 @@ Configure the site's logo with different versions for light and dark themes:
|
|
|
58
58
|
dark: "/dark-logo.png"
|
|
59
59
|
},
|
|
60
60
|
alt: "Company Logo",
|
|
61
|
-
width:
|
|
61
|
+
width: 120, // optional intrinsic width
|
|
62
|
+
height: 32, // optional intrinsic height; set both to prevent layout shift
|
|
62
63
|
href: "/", // optional link target (defaults to "/")
|
|
63
64
|
reloadDocument: true, // optional, defaults to true
|
|
64
65
|
}
|
|
@@ -19,6 +19,14 @@ For information on how to configure processors in your project, see the
|
|
|
19
19
|
|
|
20
20
|
Dev Portal provides several built-in processors that you can use to transform your schemas:
|
|
21
21
|
|
|
22
|
+
:::note
|
|
23
|
+
|
|
24
|
+
Items marked with [`x-internal`](../openapi-extensions/x-internal) are removed automatically in
|
|
25
|
+
every build, so you don't need to configure `removePaths` or `removeParameters` for that. The
|
|
26
|
+
`x-internal` examples below show how the processors work.
|
|
27
|
+
|
|
28
|
+
:::
|
|
29
|
+
|
|
22
30
|
### `removeExtensions`
|
|
23
31
|
|
|
24
32
|
Removes OpenAPI extensions (`x-` prefixed properties) from your schema:
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: x-internal
|
|
3
|
+
sidebar_icon: eye-off
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use `x-internal` to hide internal endpoints and parameters from your API documentation. Anything
|
|
7
|
+
marked with `x-internal: true` is removed from the schema before Dev Portal renders it, so it doesn't
|
|
8
|
+
show up in the navigation, on operation pages, in the playground, or in documents published with
|
|
9
|
+
[`publish`](/dev-portal/zudoku/configuration/api-reference#publish-a-canonical-openapi-document).
|
|
10
|
+
|
|
11
|
+
`x-internal` is built in and applies to every Dev Portal project. You don't need to add a
|
|
12
|
+
[schema processor](/dev-portal/zudoku/guides/processors) for it.
|
|
13
|
+
|
|
14
|
+
:::warning
|
|
15
|
+
|
|
16
|
+
`x-internal` only affects the documentation. The endpoints still exist on your API and can still be
|
|
17
|
+
called. Don't rely on it to secure anything.
|
|
18
|
+
|
|
19
|
+
:::
|
|
20
|
+
|
|
21
|
+
## Location
|
|
22
|
+
|
|
23
|
+
The extension can be added at the following levels:
|
|
24
|
+
|
|
25
|
+
| Level | Effect |
|
|
26
|
+
| -------------------- | ----------------------------------------------------------------- |
|
|
27
|
+
| **Path Item Object** | Removes the whole path, including all of its operations. |
|
|
28
|
+
| **Operation Object** | Removes only that operation. Other methods on the same path stay. |
|
|
29
|
+
| **Parameter Object** | Removes the parameter from the path item or operation. |
|
|
30
|
+
|
|
31
|
+
| Option | Type | Description |
|
|
32
|
+
| ------------ | --------- | ---------------------------------------------------- |
|
|
33
|
+
| `x-internal` | `boolean` | Set to `true` to remove the item from documentation. |
|
|
34
|
+
|
|
35
|
+
`$ref`s are not resolved, so add `x-internal` to the parameter where it is used rather than to a
|
|
36
|
+
shared `components.parameters` entry.
|
|
37
|
+
|
|
38
|
+
Other objects such as tags, schemas, schema properties and responses are not covered. Use a custom
|
|
39
|
+
[schema processor](/dev-portal/zudoku/guides/processors#custom-processors) if you need to hide those.
|
|
40
|
+
|
|
41
|
+
## Example
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
paths:
|
|
45
|
+
/admin:
|
|
46
|
+
x-internal: true # hides the entire path
|
|
47
|
+
get:
|
|
48
|
+
summary: Admin dashboard
|
|
49
|
+
responses:
|
|
50
|
+
"200":
|
|
51
|
+
description: OK
|
|
52
|
+
/users:
|
|
53
|
+
get:
|
|
54
|
+
summary: List users
|
|
55
|
+
parameters:
|
|
56
|
+
- name: limit
|
|
57
|
+
in: query
|
|
58
|
+
schema:
|
|
59
|
+
type: integer
|
|
60
|
+
- name: debug
|
|
61
|
+
in: query
|
|
62
|
+
x-internal: true # hides only this parameter
|
|
63
|
+
schema:
|
|
64
|
+
type: boolean
|
|
65
|
+
responses:
|
|
66
|
+
"200":
|
|
67
|
+
description: OK
|
|
68
|
+
delete:
|
|
69
|
+
summary: Delete all users
|
|
70
|
+
x-internal: true # hides only this operation
|
|
71
|
+
responses:
|
|
72
|
+
"204":
|
|
73
|
+
description: Deleted
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
In this example, the documentation shows `GET /users` with only the `limit` parameter. The `/admin`
|
|
77
|
+
path, the `DELETE /users` operation, and the `debug` parameter are all hidden.
|
|
78
|
+
|
|
79
|
+
## Notes
|
|
80
|
+
|
|
81
|
+
- `x-internal` applies to APIs loaded from files (`type: "file"`), the same as other
|
|
82
|
+
[schema processors](/dev-portal/zudoku/guides/processors). Schemas loaded from a URL are not processed.
|
|
83
|
+
- Your own schema processors in `zudoku.build.ts` run first, so they can add `x-internal` to items
|
|
84
|
+
programmatically.
|
|
85
|
+
- The [`schemaDownload`](/dev-portal/zudoku/configuration/api-reference#options) option serves your original
|
|
86
|
+
schema file, which still contains the items marked with `x-internal`.
|
|
87
|
+
- There is currently no option to turn this behavior off. If you need to keep an item in your
|
|
88
|
+
documentation, remove its `x-internal` flag.
|
|
@@ -114,6 +114,9 @@ curl https://gateway.example.com/v1/chat/completions \
|
|
|
114
114
|
|
|
115
115
|
Authentication scheme matching is case-insensitive. A missing key, an invalid
|
|
116
116
|
scheme, or a key that is not authorized receives a `401 Unauthorized` response.
|
|
117
|
+
The 401 carries a `WWW-Authenticate` challenge that names the expected scheme
|
|
118
|
+
and, when it is not `Authorization`, the header. See
|
|
119
|
+
[Unauthorized responses](#unauthorized-responses).
|
|
117
120
|
|
|
118
121
|
Once the key is accepted, the policy removes the `authHeader` header from the
|
|
119
122
|
request. The application key never reaches an upstream provider or a policy
|
|
@@ -221,6 +224,28 @@ applies: `authHeader` and `authScheme` select the Zuplo key, and providers use
|
|
|
221
224
|
their configured credentials. Moving the gateway key to an arbitrary custom
|
|
222
225
|
header alone does not enable passthrough.
|
|
223
226
|
|
|
227
|
+
## Unauthorized responses
|
|
228
|
+
|
|
229
|
+
Every 401 from this policy carries a `WWW-Authenticate` challenge built from the
|
|
230
|
+
policy options, so a client learns where the key goes without seeing the
|
|
231
|
+
configuration. The scheme is `authScheme`, or `ApiKey` when `authScheme` is
|
|
232
|
+
empty and the header carries only the key. A `header` parameter names
|
|
233
|
+
`authHeader` when it is not `Authorization`. This policy's own 403 responses
|
|
234
|
+
carry no challenge. On a User App route, the fail-closed 403 carries the same
|
|
235
|
+
`WWW-Authenticate` challenge when this policy refused the key.
|
|
236
|
+
|
|
237
|
+
| Options | `WWW-Authenticate` |
|
|
238
|
+
| ------------------------------------------------- | --------------------------------------------------- |
|
|
239
|
+
| `{}` | `Bearer realm="ai-gateway"` |
|
|
240
|
+
| `{ "authScheme": "Token" }` | `Token realm="ai-gateway"` |
|
|
241
|
+
| `{ "authHeader": "x-gateway-key" }` | `Bearer realm="ai-gateway", header="x-gateway-key"` |
|
|
242
|
+
| `{ "authHeader": "x-api-key", "authScheme": "" }` | `ApiKey realm="ai-gateway", header="x-api-key"` |
|
|
243
|
+
|
|
244
|
+
With `credentialPassthrough` enabled, the challenge adds
|
|
245
|
+
`passthrough="Authorization"` to say the provider credential goes in
|
|
246
|
+
`Authorization`, for example
|
|
247
|
+
`ApiKey realm="ai-gateway", header="zp-gateway-api-key", passthrough="Authorization"`.
|
|
248
|
+
|
|
224
249
|
## Choose a cache duration
|
|
225
250
|
|
|
226
251
|
`cacheTtlSeconds` controls how long an authentication result can be reused. The
|
|
@@ -73,7 +73,8 @@
|
|
|
73
73
|
"default": "Bearer",
|
|
74
74
|
"x-show-example": false,
|
|
75
75
|
"x-advanced": true,
|
|
76
|
-
"
|
|
76
|
+
"pattern": "^(\\$env\\([^)]+\\)|[!#$%&'*+.^_`|~0-9A-Za-z-]*)$",
|
|
77
|
+
"description": "The scheme that prefixes the key in the authHeader header, for example Bearer. Set to an empty string when the header contains only the key. The scheme must be a single HTTP token such as Bearer, or empty for a bare key. $env(NAME) is accepted and validated after substitution."
|
|
77
78
|
},
|
|
78
79
|
"credentialPassthrough": {
|
|
79
80
|
"type": "boolean",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zuplo",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.11",
|
|
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.9.
|
|
36
|
-
"@zuplo/core": "7.9.
|
|
37
|
-
"@zuplo/runtime": "7.9.
|
|
38
|
-
"@zuplo/test": "7.9.
|
|
35
|
+
"@zuplo/cli": "7.9.11",
|
|
36
|
+
"@zuplo/core": "7.9.11",
|
|
37
|
+
"@zuplo/runtime": "7.9.11",
|
|
38
|
+
"@zuplo/test": "7.9.11"
|
|
39
39
|
}
|
|
40
40
|
}
|