zuplo 6.72.2 → 6.72.7
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/analytics/access-and-entitlements.md +27 -34
- package/docs/analytics/overview.md +7 -6
- package/docs/analytics/reference/url-parameters.md +2 -10
- package/docs/analytics/shared-controls.md +3 -10
- package/docs/analytics/tabs/agents.md +3 -3
- package/docs/analytics/tabs/requests.md +2 -4
- package/docs/articles/accounts/audit-logs.mdx +4 -4
- package/docs/articles/audit-logging.mdx +65 -0
- package/docs/articles/audit-logs.mdx +222 -0
- package/docs/articles/connect-to-aws-alb-with-mtls.mdx +89 -13
- package/docs/articles/{custom-audit-log-policy.mdx → custom-audit-logs.mdx} +26 -22
- package/docs/articles/graphql-security.mdx +2 -1
- package/docs/articles/graphql.mdx +8 -0
- package/docs/articles/opentelemetry.mdx +7 -5
- package/docs/articles/securing-backend-mtls.mdx +92 -3
- package/docs/articles/troubleshooting-slow-responses.mdx +4 -3
- package/docs/articles/troubleshooting.md +3 -1
- package/docs/policies/_index.md +3 -0
- package/docs/policies/audit-log-inbound/doc.md +16 -11
- package/docs/policies/authzen-inbound/schema.json +1 -1
- package/docs/policies/axiomatics-authz-inbound/schema.json +1 -1
- package/docs/policies/clerk-jwt-auth-inbound/schema.json +3 -3
- package/docs/policies/mcp-auth0-oauth-inbound/schema.json +8 -5
- package/docs/policies/mcp-clerk-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-cognito-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-entra-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-google-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-logto-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-oauth-inbound/schema.json +8 -5
- package/docs/policies/mcp-okta-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-ping-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-token-exchange-inbound/doc.md +72 -4
- package/docs/policies/mcp-token-exchange-inbound/intro.md +5 -4
- package/docs/policies/mcp-token-exchange-inbound/schema.json +277 -2
- package/docs/policies/mcp-workos-oauth-inbound/schema.json +78 -0
- package/docs/policies/mtls-auth-inbound/intro.md +52 -5
- package/docs/policies/okta-fga-authz-inbound/schema.json +1 -1
- package/docs/policies/open-id-jwt-auth-inbound/schema.json +3 -3
- package/docs/policies/openfga-authz-inbound/schema.json +1 -1
- package/docs/policies/propel-auth-jwt-inbound/schema.json +3 -3
- package/docs/policies/require-user-claims-inbound/doc.md +120 -0
- package/docs/policies/require-user-claims-inbound/intro.md +9 -0
- package/docs/policies/require-user-claims-inbound/schema.json +1323 -0
- package/docs/policies/semantic-cache-inbound/schema.json +1 -1
- package/docs/policies/upstream-aws-federated-auth-inbound/doc.md +78 -0
- package/docs/policies/upstream-aws-federated-auth-inbound/intro.md +20 -0
- package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +98 -0
- package/docs/policies/upstream-aws-service-auth-inbound/doc.md +89 -0
- package/docs/policies/upstream-aws-service-auth-inbound/intro.md +19 -0
- package/docs/policies/upstream-aws-service-auth-inbound/schema.json +113 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +4 -4
- package/docs/policies/upstream-gcp-federated-auth-inbound/doc.md +2 -2
- package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +5 -5
- package/docs/policies/upstream-gcp-service-auth-inbound/doc.md +3 -3
- package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +3 -3
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +19 -0
- package/docs/programmable-api/overview.mdx +0 -7
- package/package.json +4 -4
- package/docs/programmable-api/audit-log.mdx +0 -74
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Custom Audit
|
|
3
|
-
sidebar_label: Audit
|
|
2
|
+
title: Custom Audit Logs
|
|
3
|
+
sidebar_label: Custom Audit Logs
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
[Zuplo Audit Logs](./audit-logs.mdx) stores your audit trail in Zuplo and gives
|
|
7
|
+
you a portal viewer and query API out of the box. If your organization uses an
|
|
8
|
+
external audit logging service instead, you can send events to it directly from
|
|
9
|
+
the gateway with a [custom policy](../policies/custom-code-inbound.mdx) that
|
|
10
|
+
uses [runtime hooks](../programmable-api/runtime-extensions.mdx). This approach
|
|
11
|
+
works on any plan — it's just custom code — and gives you full control over
|
|
12
|
+
which events are recorded, the event format, and the destination.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
detecting and correcting issues such as unauthorized access or permission
|
|
11
|
-
elevations within your system. Audit logging is also a requirement for many
|
|
12
|
-
compliance certifications as well as part of the buying criteria for larger
|
|
13
|
-
enterprises.
|
|
14
|
-
|
|
15
|
-
Adding Audit Logging to your APIs that are secured with Zuplo is as easy as
|
|
16
|
-
adding a custom policy. Typically you want to add audit logs to any API that
|
|
17
|
-
modifies data, however depending on the API you may want it on read operations
|
|
18
|
-
as well (for example retrieve a secret key, etc.)
|
|
19
|
-
|
|
20
|
-
## Example Policy: WorkOS Audit Logs
|
|
14
|
+
## Example: WorkOS Audit Logs
|
|
21
15
|
|
|
22
16
|
[WorkOS](https://workos.com/) provides various services that help enable
|
|
23
|
-
enterprise features on your service such as SSO and Audit Logs.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
using their API.
|
|
17
|
+
enterprise features on your service such as SSO and Audit Logs. The following
|
|
18
|
+
custom policy logs API calls to the WorkOS Audit Logs API after each response is
|
|
19
|
+
sent:
|
|
27
20
|
|
|
28
21
|
```ts
|
|
29
22
|
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
|
|
@@ -34,7 +27,7 @@ export async function auditLogPlugin(
|
|
|
34
27
|
policyName: string,
|
|
35
28
|
) {
|
|
36
29
|
// Clone the request so the body can be read in the hook
|
|
37
|
-
// note: remove this
|
|
30
|
+
// note: remove this if you don't need content from the body
|
|
38
31
|
const cloned = request.clone();
|
|
39
32
|
context.addResponseSendingFinalHook(async (response) => {
|
|
40
33
|
const incomingBody = await cloned.json();
|
|
@@ -48,7 +41,7 @@ export async function auditLogPlugin(
|
|
|
48
41
|
version: 1,
|
|
49
42
|
actor: {
|
|
50
43
|
type: "user",
|
|
51
|
-
//
|
|
44
|
+
// Use the user sub for authenticated users
|
|
52
45
|
id: request.user.sub,
|
|
53
46
|
metadata: {
|
|
54
47
|
role: "user",
|
|
@@ -93,3 +86,14 @@ export async function auditLogPlugin(
|
|
|
93
86
|
return request;
|
|
94
87
|
}
|
|
95
88
|
```
|
|
89
|
+
|
|
90
|
+
The same pattern works for any provider with an HTTP API — swap the event shape
|
|
91
|
+
and endpoint for your provider's, and store credentials in
|
|
92
|
+
[environment variables](./environment-variables.mdx).
|
|
93
|
+
|
|
94
|
+
## Related resources
|
|
95
|
+
|
|
96
|
+
- [Audit logging overview](./audit-logging.mdx) — why audit logging matters and
|
|
97
|
+
how the options compare
|
|
98
|
+
- [Zuplo Audit Logs](./audit-logs.mdx) — the built-in feature with portal
|
|
99
|
+
viewing and a query API
|
|
@@ -180,7 +180,8 @@ outbound filter policy goes in the `outbound` array:
|
|
|
180
180
|
## Example repository
|
|
181
181
|
|
|
182
182
|
For a complete, runnable setup, see the
|
|
183
|
-
[GraphQL API with Zuplo example repository](https://github.com/zuplo/
|
|
183
|
+
[GraphQL API with Zuplo example repository](https://github.com/zuplo-samples/graphql).
|
|
184
|
+
You can [deploy it to your own account in one click](./graphql.mdx).
|
|
184
185
|
|
|
185
186
|
## Next steps
|
|
186
187
|
|
|
@@ -12,6 +12,14 @@ Zuplo has rich support for GraphQL. Pass your requests through the gateway,
|
|
|
12
12
|
attach policies, track operations with analytics, and publish documentation for
|
|
13
13
|
your schema in the Dev Portal. This guide walks you through setting it up.
|
|
14
14
|
|
|
15
|
+
<ZupIt repoUrl="https://github.com/zuplo-samples/graphql">
|
|
16
|
+
|
|
17
|
+
Want to see it working first? This example proxies a public GraphQL API with
|
|
18
|
+
edge caching, query depth limiting, and analytics already wired up — deploy it
|
|
19
|
+
to your own Zuplo account in one click.
|
|
20
|
+
|
|
21
|
+
</ZupIt>
|
|
22
|
+
|
|
15
23
|
:::tip{title="TL;DR"}
|
|
16
24
|
|
|
17
25
|
- [ ] Proxy your GraphQL endpoint through a POST `/graphql` route with the URL
|
|
@@ -7,10 +7,9 @@ Zuplo ships with an OpenTelemetry plugin (`@zuplo/otel`) that instruments your
|
|
|
7
7
|
API and exports traces and logs in OpenTelemetry format. The quickest way to use
|
|
8
8
|
it is Zuplo's built-in tracing: add the plugin and your traces are stored by
|
|
9
9
|
Zuplo and shown in the portal's **Observability** tab, with no collector to run
|
|
10
|
-
or backend to host.
|
|
11
|
-
both at
|
|
12
|
-
|
|
13
|
-
<EnterpriseFeature name="OpenTelemetry" />
|
|
10
|
+
or backend to host. Built-in tracing is available on every plan. You can also
|
|
11
|
+
export to your own OpenTelemetry backend (an Enterprise feature), or to both at
|
|
12
|
+
once.
|
|
14
13
|
|
|
15
14
|
## Tracing
|
|
16
15
|
|
|
@@ -68,7 +67,8 @@ Deploy your project and open the **Observability** tab to see traces.
|
|
|
68
67
|
Each trace is tagged with the account, project, deployment, and environment it
|
|
69
68
|
ran in, plus the request ID (the `zp-rid` value) that also appears on your
|
|
70
69
|
[logs](#logging), so you can move between a request's logs and its trace. How
|
|
71
|
-
long traces are kept depends on your plan
|
|
70
|
+
long traces are kept depends on your plan — see
|
|
71
|
+
[data retention](../analytics/access-and-entitlements.md#data-retention).
|
|
72
72
|
|
|
73
73
|
:::note
|
|
74
74
|
|
|
@@ -81,6 +81,8 @@ still run.
|
|
|
81
81
|
|
|
82
82
|
### Export to Your Own Backend
|
|
83
83
|
|
|
84
|
+
<EnterpriseFeature name="Exporting to your own OpenTelemetry backend" />
|
|
85
|
+
|
|
84
86
|
To send traces to an OpenTelemetry service such as
|
|
85
87
|
[Honeycomb](https://honeycomb.io), [Middleware](https://middleware.io/),
|
|
86
88
|
[Dynatrace](https://dynatrace.com), [Jaeger](https://www.jaegertracing.io/), or
|
|
@@ -30,11 +30,38 @@ gateways, and Zuplo can verify it's connecting to the correct backend service.
|
|
|
30
30
|
|
|
31
31
|
Before you begin, you need:
|
|
32
32
|
|
|
33
|
-
- A client certificate and private key generated from a
|
|
34
|
-
(CA) that your backend trusts
|
|
33
|
+
- A PEM-encoded client certificate and matching private key generated from a
|
|
34
|
+
Certificate Authority (CA) that your backend trusts
|
|
35
35
|
- Your backend service configured to require and validate client certificates
|
|
36
36
|
- The Zuplo CLI installed (see [CLI documentation](../cli/overview.mdx))
|
|
37
37
|
|
|
38
|
+
## Client certificate requirements
|
|
39
|
+
|
|
40
|
+
The certificate uploaded to Zuplo is the client, or leaf, certificate that the
|
|
41
|
+
gateway presents to your backend. It should have the following properties:
|
|
42
|
+
|
|
43
|
+
- X.509 version 3
|
|
44
|
+
- `Basic Constraints: critical, CA:FALSE`
|
|
45
|
+
- `Key Usage: critical, Digital Signature`
|
|
46
|
+
- `Extended Key Usage: TLS Web Client Authentication` (`clientAuth`)
|
|
47
|
+
- An RSA key between 2048 and 8192 bits, or an ECDSA key using P-256, P-384, or
|
|
48
|
+
P-521
|
|
49
|
+
- A SHA-256 or stronger signature
|
|
50
|
+
- A subject that uniquely identifies the gateway credential
|
|
51
|
+
- A validity period appropriate for your certificate rotation policy
|
|
52
|
+
|
|
53
|
+
The issuing CA certificate must be X.509 version 3 with
|
|
54
|
+
`Basic Constraints: critical, CA:TRUE` and a key usage that includes
|
|
55
|
+
`Certificate Sign` and `CRL Sign`. Your backend's trust store must contain the
|
|
56
|
+
CA certificates needed to build a path from the client certificate to a trusted
|
|
57
|
+
root. When the trusted CA directly signs the client certificate, you do not need
|
|
58
|
+
a client certificate-chain bundle. If an intermediate CA signs it, follow your
|
|
59
|
+
backend's requirements for presenting and trusting the intermediate chain.
|
|
60
|
+
|
|
61
|
+
The private key must match the public key in the client certificate. Keep it
|
|
62
|
+
secret and limit access to it. The key must be unencrypted when uploaded to
|
|
63
|
+
Zuplo so the gateway can use it without a passphrase.
|
|
64
|
+
|
|
38
65
|
## 1/ Upload Your Certificate
|
|
39
66
|
|
|
40
67
|
Use the Zuplo CLI to upload your client certificate and private key to your
|
|
@@ -229,10 +256,72 @@ For local development, consider:
|
|
|
229
256
|
|
|
230
257
|
### Certificate Validation Errors
|
|
231
258
|
|
|
232
|
-
|
|
259
|
+
Inspect the certificate and confirm its subject, issuer, validity, and client
|
|
260
|
+
authentication purpose:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
openssl x509 \
|
|
264
|
+
-in client.crt \
|
|
265
|
+
-noout \
|
|
266
|
+
-subject \
|
|
267
|
+
-issuer \
|
|
268
|
+
-serial \
|
|
269
|
+
-dates \
|
|
270
|
+
-purpose
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
`SSL client` should report `Yes`. To inspect all extensions, run
|
|
274
|
+
`openssl x509 -in client.crt -noout -text` and confirm the certificate reports
|
|
275
|
+
`CA:FALSE`, `Digital Signature`, and `TLS Web Client Authentication`.
|
|
276
|
+
|
|
277
|
+
Check that the certificate will remain valid for at least seven days:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
openssl x509 -in client.crt -noout -checkend 604800
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Validate the certificate path against the same CA bundle your backend trusts:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
openssl verify \
|
|
287
|
+
-verbose \
|
|
288
|
+
-purpose sslclient \
|
|
289
|
+
-x509_strict \
|
|
290
|
+
-show_chain \
|
|
291
|
+
-CAfile backend-client-ca-bundle.pem \
|
|
292
|
+
client.crt
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The expected result is `client.crt: OK`. Common errors include:
|
|
296
|
+
|
|
297
|
+
- `unable to get local issuer certificate`: The issuing CA or an intermediate CA
|
|
298
|
+
is missing from the backend's trust bundle.
|
|
299
|
+
- `unsupported certificate purpose`: The client certificate is missing the
|
|
300
|
+
`clientAuth` extended key usage.
|
|
301
|
+
- `certificate has expired`: The client certificate is outside its validity
|
|
302
|
+
period.
|
|
303
|
+
- `invalid CA certificate`: An issuing certificate is missing valid CA
|
|
304
|
+
extensions.
|
|
305
|
+
- `key usage does not include certificate signing`: An issuing CA does not have
|
|
306
|
+
the `keyCertSign` key usage.
|
|
307
|
+
|
|
308
|
+
Confirm that the certificate and private key contain the same public key:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
CERT_KEY_HASH=$(openssl x509 -in client.crt -noout -pubkey | openssl sha256)
|
|
312
|
+
PRIVATE_KEY_HASH=$(openssl pkey -in client.key -pubout | openssl sha256)
|
|
313
|
+
|
|
314
|
+
test "$CERT_KEY_HASH" = "$PRIVATE_KEY_HASH" &&
|
|
315
|
+
echo "Certificate and private key match" ||
|
|
316
|
+
echo "ERROR: Certificate and private key do not match"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
If your backend still rejects the certificate, verify:
|
|
233
320
|
|
|
234
321
|
- The certificate is signed by a CA that your backend trusts
|
|
235
322
|
- The certificate hasn't expired
|
|
323
|
+
- The certificate has the required key usage and extended key usage
|
|
324
|
+
- The certificate and private key match
|
|
236
325
|
- The certificate name in your code matches the uploaded certificate name
|
|
237
326
|
|
|
238
327
|
### Connection Failures
|
|
@@ -240,9 +240,10 @@ For the most detailed view of where time is spent in your request pipeline,
|
|
|
240
240
|
enable [OpenTelemetry tracing](./opentelemetry.mdx). The OpenTelemetry plugin
|
|
241
241
|
automatically instruments your API and provides span-level timing for each stage
|
|
242
242
|
of the request lifecycle — including inbound policies, the handler, outbound
|
|
243
|
-
policies, and any subrequests made via `fetch` in custom code.
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
policies, and any subrequests made via `fetch` in custom code. Built-in tracing
|
|
244
|
+
is available on every plan; see
|
|
245
|
+
[data retention](../analytics/access-and-entitlements.md#data-retention) for how
|
|
246
|
+
much trace history you can query.
|
|
246
247
|
|
|
247
248
|
With tracing enabled, you can see exactly how long each policy and handler takes
|
|
248
249
|
to execute, making it straightforward to identify which component is adding
|
|
@@ -179,7 +179,9 @@ const response = await fetch("https://api.example.com/data", {
|
|
|
179
179
|
The Zuplo Portal provides real-time log viewing for deployed environments. Open
|
|
180
180
|
the **Observability** tab in your project — the **Logs** view opens by default —
|
|
181
181
|
then use the **Environment** filter to select the deployed environment and see
|
|
182
|
-
live request logs and any messages logged with `context.log`.
|
|
182
|
+
live request logs and any messages logged with `context.log`. How far back you
|
|
183
|
+
can search depends on your plan — see
|
|
184
|
+
[Access and entitlements](../analytics/access-and-entitlements.md#data-retention).
|
|
183
185
|
|
|
184
186
|
### Using context.log
|
|
185
187
|
|
package/docs/policies/_index.md
CHANGED
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
| request-size-limit-inbound | Request Size Limit | Enforces a maximum size in bytes of the incoming request. | api-gateway |
|
|
92
92
|
| request-validation-inbound | Request Validation | Validates incoming requests against your OpenAPI specification. Checks query parameters, path parameters, headers, and request body to ensure they match the defined schema before processing. | api-gateway |
|
|
93
93
|
| require-origin-inbound | Require Origin | Sets an allow-list for an origin header | api-gateway |
|
|
94
|
+
| require-user-claims-inbound | Require User Claims | Authorizes requests by validating claims on the authenticated user (`request.user`) against a configurable rule of `and`/`or` combinators and per-claim `eq`, `in`, and `startsWith` checks. Run it after any authentication policy that populates `request.user` — a JWT auth policy, API key auth, mTLS, and so on — to allow only specific callers (service accounts, OAuth clients, tenants, groups) without writing custom code. Every check fails closed: a missing or non-primitive claim never matches, comparisons are strict and type-sensitive, and requests without an authenticated user receive a 401 response. Denied requests receive a 403 response that does not echo claim values or expected values; the failing checks are written to the request log instead. Validation of the options runs lazily inside the policy constructor, which the runtime caches per policy name. Misconfigured options therefore fail on first use with a customer-facing `ConfigurationError` instead of failing at module load. | api-gateway |
|
|
94
95
|
| secret-masking-outbound | Secret Masking | Masks common secrets like Zuplo API keys, GitHub tokens, or SSH private key in the response body. | api-gateway |
|
|
95
96
|
| semantic-cache-inbound | Semantic Cache | Respond to matched incoming requests with semantically cached content The Semantic Cache Inbound policy caches responses based on semantic similarity of cache keys rather than exact matches. This allows for more flexible caching where similar requests can return cached responses even if the cache key is not exactly the same. The policy uses Large Language Model (LLM) embeddings to determine semantic similarity between cache keys based on a configurable similarity tolerance. Options: - semanticTolerance: The semantic similarity threshold for semantic cache matches (0-1, default: 0.2). Values closer to 0 require higher similarity. Can be overridden by custom functions. - expirationSecondsTtl: The timeout of the cache in seconds (default: 3600, 1 hour). Can be overridden by custom functions. - namespace: Optional namespace to isolate cache entries (default: "default"). Useful for multi-tenant scenarios or different cache contexts. - cacheBy: Determines how cache keys are generated: 'function' for custom logic or 'propertyPath' to extract from JSON body. | ai-gateway |
|
|
96
97
|
| set-body-inbound | Set Body | Sets the body of the request in the inbound pipeline - make sure to convert a GET/HEAD request to another method when using this policy. | api-gateway |
|
|
@@ -103,6 +104,8 @@
|
|
|
103
104
|
| traffic-splitting-inbound | Traffic Splitting | Splits traffic randomly across a set of weighted base paths. On each request one base path is selected (weighted by `weight`) and written to the request custom context at `customOutputProperty`. Reference it from a later URL Rewrite `rewritePattern` or URL Forward `baseUrl`, e.g. `${context.custom.trafficSplitting.basePath}`. | api-gateway |
|
|
104
105
|
| transform-body-inbound | Transform Request Body | Transform the body of an incoming request. | api-gateway |
|
|
105
106
|
| transform-body-outbound | Transform Response Body | Transform the body of an outgoing response. | api-gateway |
|
|
107
|
+
| upstream-aws-federated-auth-inbound | Upstream AWS Federated Auth | Resolves AWS credentials with STS AssumeRoleWithWebIdentity using Zuplo's ambient OIDC identity — no AWS keys are stored anywhere. The role's trust policy must trust the Zuplo OIDC identity provider. Resolved credentials are registered on the request context for the AWS Lambda handler and custom code to sign upstream requests with `AwsClient.fromContext`. This policy does not itself sign or forward the request. | api-gateway |
|
|
108
|
+
| upstream-aws-service-auth-inbound | Upstream AWS Service Auth | Resolves AWS credentials from static access keys (optionally exchanged for an IAM role's temporary credentials via STS AssumeRole) and registers them on the request context. The AWS Lambda handler and custom code read them with `AwsClient.fromContext` to sign upstream requests. This policy does not itself sign or forward the request. | api-gateway |
|
|
106
109
|
| upstream-azure-ad-service-auth-inbound | Upstream Azure AD Service Auth | Uses Azure Active Directory to add an Authorization header to the request in order to authenticate requests using Azure identity. | api-gateway |
|
|
107
110
|
| upstream-firebase-admin-auth-inbound | Upstream Firebase Admin Auth | Creates a Firebase Admin token and attaches it to the outgoing request. Useful when calling Firebase services as an administrator. | api-gateway |
|
|
108
111
|
| upstream-firebase-user-auth-inbound | Upstream Firebase User Auth | Creates a Firebase custom user token and attaches it to the outgoing request. Useful when calling Firebase services as user. | api-gateway |
|
|
@@ -16,14 +16,14 @@ requests).
|
|
|
16
16
|
## Controlling What's Logged
|
|
17
17
|
|
|
18
18
|
Audit events can contain personal or sensitive data. To keep audit logging
|
|
19
|
-
compliant with your own data-handling and PII policies, use the `include`
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
compliant with your own data-handling and PII policies, use the `include` option
|
|
20
|
+
to turn individual fields off. Everything is captured by default; set a flag to
|
|
21
|
+
`false` to omit it:
|
|
22
22
|
|
|
23
23
|
- `queryParams` — the request's query-string parameters (in the logged URL).
|
|
24
|
-
- `user` — the authenticated user / actor identity (subject, email,
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
- `user` — the authenticated user / actor identity (subject, email, connection).
|
|
25
|
+
The `user` vs `anonymous` classification is always kept, but the identifying
|
|
26
|
+
values are omitted when disabled.
|
|
27
27
|
- `ipAddress` — the caller's IP address.
|
|
28
28
|
- `geolocation` — the caller's country, region, and city.
|
|
29
29
|
|
|
@@ -87,7 +87,8 @@ export async function deleteAccount(
|
|
|
87
87
|
The event object passed to `log()` supports the following fields. Only `type` is
|
|
88
88
|
required.
|
|
89
89
|
|
|
90
|
-
- `type` — the event type, in reverse-DNS form (e.g.
|
|
90
|
+
- `type` — the event type, in reverse-DNS form (e.g.
|
|
91
|
+
`com.acme.account.deleted`).
|
|
91
92
|
- `subject` — the primary entity the event is about.
|
|
92
93
|
- `resources` — an array of `{ type, id, metadata? }` describing the resources
|
|
93
94
|
the event affected.
|
|
@@ -95,9 +96,8 @@ required.
|
|
|
95
96
|
- `data` — any additional structured data to attach to the event.
|
|
96
97
|
- `actor` — override the automatically-derived actor
|
|
97
98
|
(`{ sub, type, email, connection }`).
|
|
98
|
-
- `country`, `region`, `city` — override the caller's geolocation. These
|
|
99
|
-
|
|
100
|
-
them.
|
|
99
|
+
- `country`, `region`, `city` — override the caller's geolocation. These default
|
|
100
|
+
to the current request's location, so you normally don't need to set them.
|
|
101
101
|
|
|
102
102
|
Audit logging is best-effort: `log()` never throws and never blocks or fails the
|
|
103
103
|
request, even if an event cannot be recorded.
|
|
@@ -134,4 +134,9 @@ pass, and the remaining fields are populated from the request context.
|
|
|
134
134
|
|
|
135
135
|
## Viewing Audit Logs
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
Audit logs are available in the [Zuplo portal](https://portal.zuplo.com) under
|
|
138
|
+
your project's Audit Log service, where you can browse and search the events
|
|
139
|
+
recorded by this policy.
|
|
140
|
+
|
|
141
|
+
You can also query audit logs programmatically using the
|
|
142
|
+
[Zuplo API](https://zuplo.com/docs/api).
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
},
|
|
43
43
|
"frontendApiUrl": {
|
|
44
44
|
"type": "string",
|
|
45
|
-
"examples": ["https://
|
|
46
|
-
"description": "Your Clerk
|
|
45
|
+
"examples": ["https://verb-noun-00.clerk.accounts.dev"],
|
|
46
|
+
"description": "Your Clerk Frontend API URL, i.e. `https://verb-noun-00.clerk.accounts.dev`. Can be found in the Clerk portal: https://dashboard.clerk.com/last-active?path=api-keys."
|
|
47
47
|
},
|
|
48
48
|
"oAuthResourceMetadataEnabled": {
|
|
49
49
|
"type": "boolean",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"module": "$import(@zuplo/runtime)",
|
|
60
60
|
"options": {
|
|
61
61
|
"allowUnauthenticatedRequests": false,
|
|
62
|
-
"frontendApiUrl": "https://
|
|
62
|
+
"frontendApiUrl": "https://verb-noun-00.clerk.accounts.dev",
|
|
63
63
|
"oAuthResourceMetadataEnabled": false
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
{
|
|
101
101
|
"type": "object",
|
|
102
102
|
"additionalProperties": false,
|
|
103
|
-
"required": ["enabled"
|
|
103
|
+
"required": ["enabled"],
|
|
104
104
|
"properties": {
|
|
105
105
|
"enabled": {
|
|
106
106
|
"const": true,
|
|
@@ -109,21 +109,24 @@
|
|
|
109
109
|
"trustedIssuers": {
|
|
110
110
|
"type": "array",
|
|
111
111
|
"minItems": 1,
|
|
112
|
-
"description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata.",
|
|
112
|
+
"description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
|
|
113
113
|
"items": {
|
|
114
114
|
"type": "object",
|
|
115
115
|
"additionalProperties": false,
|
|
116
|
-
"
|
|
116
|
+
"dependentRequired": {
|
|
117
|
+
"issuer": ["jwksUrl"],
|
|
118
|
+
"jwksUrl": ["issuer"]
|
|
119
|
+
},
|
|
117
120
|
"properties": {
|
|
118
121
|
"issuer": {
|
|
119
122
|
"type": "string",
|
|
120
123
|
"format": "uri",
|
|
121
|
-
"description": "Exact issuer URL expected in the ID-JAG iss claim."
|
|
124
|
+
"description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
|
|
122
125
|
},
|
|
123
126
|
"jwksUrl": {
|
|
124
127
|
"type": "string",
|
|
125
128
|
"format": "uri",
|
|
126
|
-
"description": "JWKS URL used to verify ID-JAG signatures from this issuer."
|
|
129
|
+
"description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
|
|
127
130
|
},
|
|
128
131
|
"expectedClientIds": {
|
|
129
132
|
"type": "array",
|
|
@@ -82,6 +82,84 @@
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
+
"idJag": {
|
|
86
|
+
"description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
|
|
87
|
+
"oneOf": [
|
|
88
|
+
{
|
|
89
|
+
"type": "object",
|
|
90
|
+
"additionalProperties": false,
|
|
91
|
+
"required": ["enabled"],
|
|
92
|
+
"properties": {
|
|
93
|
+
"enabled": {
|
|
94
|
+
"const": false,
|
|
95
|
+
"description": "Disable ID-JAG support."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "object",
|
|
101
|
+
"additionalProperties": false,
|
|
102
|
+
"required": ["enabled"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"enabled": {
|
|
105
|
+
"const": true,
|
|
106
|
+
"description": "Enable ID-JAG support."
|
|
107
|
+
},
|
|
108
|
+
"trustedIssuers": {
|
|
109
|
+
"type": "array",
|
|
110
|
+
"minItems": 1,
|
|
111
|
+
"description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
|
|
112
|
+
"items": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"additionalProperties": false,
|
|
115
|
+
"dependentRequired": {
|
|
116
|
+
"issuer": ["jwksUrl"],
|
|
117
|
+
"jwksUrl": ["issuer"]
|
|
118
|
+
},
|
|
119
|
+
"properties": {
|
|
120
|
+
"issuer": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"format": "uri",
|
|
123
|
+
"description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
|
|
124
|
+
},
|
|
125
|
+
"jwksUrl": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"format": "uri",
|
|
128
|
+
"description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
|
|
129
|
+
},
|
|
130
|
+
"expectedClientIds": {
|
|
131
|
+
"type": "array",
|
|
132
|
+
"items": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"minLength": 1
|
|
135
|
+
},
|
|
136
|
+
"description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
|
|
137
|
+
},
|
|
138
|
+
"subjectMapping": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"enum": [
|
|
141
|
+
"iss_prefix",
|
|
142
|
+
"iss_tenant_prefix",
|
|
143
|
+
"sub_id_only"
|
|
144
|
+
],
|
|
145
|
+
"default": "iss_prefix",
|
|
146
|
+
"description": "How the ID-JAG subject is mapped into the gateway subject ID."
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"authorizationDetailsTypesAllowed": {
|
|
152
|
+
"type": "array",
|
|
153
|
+
"items": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"minLength": 1
|
|
156
|
+
},
|
|
157
|
+
"description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
85
163
|
"browserLoginOverrides": {
|
|
86
164
|
"type": "object",
|
|
87
165
|
"description": "Optional overrides for the derived browser-login settings.",
|
|
@@ -98,6 +98,84 @@
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
|
+
"idJag": {
|
|
102
|
+
"description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
|
|
103
|
+
"oneOf": [
|
|
104
|
+
{
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": false,
|
|
107
|
+
"required": ["enabled"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"enabled": {
|
|
110
|
+
"const": false,
|
|
111
|
+
"description": "Disable ID-JAG support."
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": false,
|
|
118
|
+
"required": ["enabled"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"enabled": {
|
|
121
|
+
"const": true,
|
|
122
|
+
"description": "Enable ID-JAG support."
|
|
123
|
+
},
|
|
124
|
+
"trustedIssuers": {
|
|
125
|
+
"type": "array",
|
|
126
|
+
"minItems": 1,
|
|
127
|
+
"description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
|
|
128
|
+
"items": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"dependentRequired": {
|
|
132
|
+
"issuer": ["jwksUrl"],
|
|
133
|
+
"jwksUrl": ["issuer"]
|
|
134
|
+
},
|
|
135
|
+
"properties": {
|
|
136
|
+
"issuer": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"format": "uri",
|
|
139
|
+
"description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
|
|
140
|
+
},
|
|
141
|
+
"jwksUrl": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"format": "uri",
|
|
144
|
+
"description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
|
|
145
|
+
},
|
|
146
|
+
"expectedClientIds": {
|
|
147
|
+
"type": "array",
|
|
148
|
+
"items": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"minLength": 1
|
|
151
|
+
},
|
|
152
|
+
"description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
|
|
153
|
+
},
|
|
154
|
+
"subjectMapping": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"enum": [
|
|
157
|
+
"iss_prefix",
|
|
158
|
+
"iss_tenant_prefix",
|
|
159
|
+
"sub_id_only"
|
|
160
|
+
],
|
|
161
|
+
"default": "iss_prefix",
|
|
162
|
+
"description": "How the ID-JAG subject is mapped into the gateway subject ID."
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"authorizationDetailsTypesAllowed": {
|
|
168
|
+
"type": "array",
|
|
169
|
+
"items": {
|
|
170
|
+
"type": "string",
|
|
171
|
+
"minLength": 1
|
|
172
|
+
},
|
|
173
|
+
"description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
},
|
|
101
179
|
"browserLoginOverrides": {
|
|
102
180
|
"type": "object",
|
|
103
181
|
"description": "Optional overrides for the derived browser-login settings.",
|