zuplo 6.67.32 → 6.68.0
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/README.md +9 -0
- package/docs/_index.md +44 -0
- package/docs/ai-gateway/apps.mdx +28 -0
- package/docs/ai-gateway/custom-providers.mdx +54 -0
- package/docs/ai-gateway/getting-started.mdx +224 -0
- package/docs/ai-gateway/guardrails.mdx +65 -0
- package/docs/ai-gateway/integrations/ai-sdk.mdx +109 -0
- package/docs/ai-gateway/integrations/claude-code.mdx +49 -0
- package/docs/ai-gateway/integrations/codex.mdx +78 -0
- package/docs/ai-gateway/integrations/goose.mdx +104 -0
- package/docs/ai-gateway/integrations/langchain.mdx +66 -0
- package/docs/ai-gateway/integrations/openai.mdx +99 -0
- package/docs/ai-gateway/introduction.mdx +85 -0
- package/docs/ai-gateway/managing-apps.mdx +46 -0
- package/docs/ai-gateway/managing-providers.mdx +66 -0
- package/docs/ai-gateway/managing-teams.mdx +63 -0
- package/docs/ai-gateway/policies/akamai-ai-firewall.mdx +125 -0
- package/docs/ai-gateway/policies/comet-opik-tracing.mdx +139 -0
- package/docs/ai-gateway/policies/galileo-tracing.mdx +147 -0
- package/docs/ai-gateway/providers.mdx +32 -0
- package/docs/ai-gateway/teams.mdx +38 -0
- package/docs/ai-gateway/universal-api.mdx +43 -0
- package/docs/ai-gateway/usage-limits.mdx +89 -0
- package/docs/api-management/introduction.md +127 -0
- package/docs/articles/accounts/audit-logs.mdx +227 -0
- package/docs/articles/accounts/billing.mdx +25 -0
- package/docs/articles/accounts/default-api-key.mdx +30 -0
- package/docs/articles/accounts/delete-account.mdx +36 -0
- package/docs/articles/accounts/enterprise-sso.mdx +116 -0
- package/docs/articles/accounts/managing-account-members.mdx +45 -0
- package/docs/articles/accounts/managing-project-members.mdx +37 -0
- package/docs/articles/accounts/members-and-roles.mdx +21 -0
- package/docs/articles/accounts/roles-and-permissions.mdx +115 -0
- package/docs/articles/accounts/zuplo-api-keys.mdx +94 -0
- package/docs/articles/add-api-to-backstage.mdx +216 -0
- package/docs/articles/advanced-path-matching.mdx +139 -0
- package/docs/articles/api-key-administration.mdx +47 -0
- package/docs/articles/api-key-api.mdx +220 -0
- package/docs/articles/api-key-authentication.mdx +195 -0
- package/docs/articles/api-key-buckets.mdx +61 -0
- package/docs/articles/api-key-end-users.mdx +52 -0
- package/docs/articles/api-key-leak-detection.mdx +75 -0
- package/docs/articles/api-key-management.mdx +100 -0
- package/docs/articles/api-key-react-component.mdx +90 -0
- package/docs/articles/api-key-service-limits.mdx +14 -0
- package/docs/articles/archiving-requests-to-storage.mdx +119 -0
- package/docs/articles/branch-based-deployments.mdx +184 -0
- package/docs/articles/bypass-policy-for-testing.mdx +117 -0
- package/docs/articles/check-ip-address.mdx +17 -0
- package/docs/articles/ci-cd-azure/basic-deployment.mdx +49 -0
- package/docs/articles/ci-cd-azure/deploy-and-test.mdx +47 -0
- package/docs/articles/ci-cd-azure/local-testing.mdx +59 -0
- package/docs/articles/ci-cd-azure/multi-stage-deployment.mdx +88 -0
- package/docs/articles/ci-cd-azure/pr-preview-environments.mdx +50 -0
- package/docs/articles/ci-cd-azure/tag-based-releases.mdx +37 -0
- package/docs/articles/ci-cd-bitbucket/basic-deployment.mdx +27 -0
- package/docs/articles/ci-cd-bitbucket/deploy-and-test.mdx +41 -0
- package/docs/articles/ci-cd-bitbucket/local-testing.mdx +34 -0
- package/docs/articles/ci-cd-bitbucket/multi-stage-deployment.mdx +52 -0
- package/docs/articles/ci-cd-bitbucket/pr-preview-environments.mdx +46 -0
- package/docs/articles/ci-cd-bitbucket/tag-based-releases.mdx +27 -0
- package/docs/articles/ci-cd-circleci/basic-deployment.mdx +34 -0
- package/docs/articles/ci-cd-circleci/deploy-and-test.mdx +44 -0
- package/docs/articles/ci-cd-circleci/local-testing.mdx +50 -0
- package/docs/articles/ci-cd-circleci/multi-stage-deployment.mdx +82 -0
- package/docs/articles/ci-cd-circleci/pr-preview-environments.mdx +47 -0
- package/docs/articles/ci-cd-circleci/tag-based-releases.mdx +38 -0
- package/docs/articles/ci-cd-github/basic-deployment.mdx +48 -0
- package/docs/articles/ci-cd-github/cleanup-on-branch-delete.mdx +123 -0
- package/docs/articles/ci-cd-github/deploy-and-test.mdx +82 -0
- package/docs/articles/ci-cd-github/local-testing.mdx +102 -0
- package/docs/articles/ci-cd-github/multi-stage-deployment.mdx +136 -0
- package/docs/articles/ci-cd-github/pr-preview-environments.mdx +106 -0
- package/docs/articles/ci-cd-github/tag-based-releases.mdx +99 -0
- package/docs/articles/ci-cd-gitlab/basic-deployment.mdx +28 -0
- package/docs/articles/ci-cd-gitlab/deploy-and-test.mdx +44 -0
- package/docs/articles/ci-cd-gitlab/local-testing.mdx +39 -0
- package/docs/articles/ci-cd-gitlab/mr-preview-environments.mdx +52 -0
- package/docs/articles/ci-cd-gitlab/multi-stage-deployment.mdx +64 -0
- package/docs/articles/ci-cd-gitlab/tag-based-releases.mdx +28 -0
- package/docs/articles/composite-policy-reference.mdx +284 -0
- package/docs/articles/configuring-auth0-for-mcp-auth.mdx +186 -0
- package/docs/articles/configuring-okta-for-mcp-auth.mdx +208 -0
- package/docs/articles/convert-urls-to-openapi.mdx +62 -0
- package/docs/articles/cors.mdx +447 -0
- package/docs/articles/custom-audit-log-policy.mdx +95 -0
- package/docs/articles/custom-ci-cd-azure.mdx +81 -0
- package/docs/articles/custom-ci-cd-bitbucket.mdx +80 -0
- package/docs/articles/custom-ci-cd-circleci.mdx +78 -0
- package/docs/articles/custom-ci-cd-github.mdx +99 -0
- package/docs/articles/custom-ci-cd-gitlab.mdx +79 -0
- package/docs/articles/custom-ci-cd.mdx +82 -0
- package/docs/articles/custom-code-patterns.md +418 -0
- package/docs/articles/custom-domains.mdx +258 -0
- package/docs/articles/custom-logging-example.mdx +139 -0
- package/docs/articles/ddos-protection.mdx +138 -0
- package/docs/articles/development-options.mdx +49 -0
- package/docs/articles/environment-variables.mdx +134 -0
- package/docs/articles/environments.mdx +143 -0
- package/docs/articles/fastly-zuplo-host-setup.mdx +41 -0
- package/docs/articles/github-deployment-testing.mdx +101 -0
- package/docs/articles/gke-with-upstream-auth-policy.mdx +192 -0
- package/docs/articles/graphql-security.mdx +180 -0
- package/docs/articles/handling-form-data.mdx +61 -0
- package/docs/articles/health-checks.mdx +109 -0
- package/docs/articles/hosting-options.mdx +70 -0
- package/docs/articles/lazy-load-configuration-into-cache.mdx +92 -0
- package/docs/articles/limits.mdx +98 -0
- package/docs/articles/local-development-debugging.mdx +44 -0
- package/docs/articles/local-development-env-variables.mdx +23 -0
- package/docs/articles/local-development-installing-packages.mdx +23 -0
- package/docs/articles/local-development-routes-designer.mdx +27 -0
- package/docs/articles/local-development-services.mdx +40 -0
- package/docs/articles/local-development-troubleshooting.mdx +56 -0
- package/docs/articles/local-development.mdx +81 -0
- package/docs/articles/log-plugin-aws-cloudwatch.mdx +83 -0
- package/docs/articles/log-plugin-datadog.mdx +84 -0
- package/docs/articles/log-plugin-dynatrace.mdx +75 -0
- package/docs/articles/log-plugin-gcp.mdx +75 -0
- package/docs/articles/log-plugin-loki.mdx +136 -0
- package/docs/articles/log-plugin-new-relic.mdx +84 -0
- package/docs/articles/log-plugin-splunk.mdx +104 -0
- package/docs/articles/log-plugin-sumo.mdx +73 -0
- package/docs/articles/log-plugin-vmware-log-insight.mdx +154 -0
- package/docs/articles/log-request-response-data.mdx +398 -0
- package/docs/articles/logging.mdx +115 -0
- package/docs/articles/manual-mcp-oauth-testing.mdx +193 -0
- package/docs/articles/mcp-quickstart.mdx +135 -0
- package/docs/articles/metrics-plugins.mdx +371 -0
- package/docs/articles/migrate-from-apigee.md +408 -0
- package/docs/articles/migrate-from-aws-api-gateway.md +248 -0
- package/docs/articles/migrate-from-azure-apim.md +292 -0
- package/docs/articles/migrate-from-kong.md +300 -0
- package/docs/articles/migration-overview.md +81 -0
- package/docs/articles/monetization/api-access.mdx +69 -0
- package/docs/articles/monetization/billing-models.md +520 -0
- package/docs/articles/monetization/developer-portal.md +167 -0
- package/docs/articles/monetization/features.mdx +98 -0
- package/docs/articles/monetization/index.mdx +113 -0
- package/docs/articles/monetization/meters.mdx +135 -0
- package/docs/articles/monetization/monetization-policy.md +314 -0
- package/docs/articles/monetization/plan-examples.mdx +366 -0
- package/docs/articles/monetization/plans.mdx +266 -0
- package/docs/articles/monetization/pricing-models.mdx +225 -0
- package/docs/articles/monetization/private-plans.md +154 -0
- package/docs/articles/monetization/quickstart.md +355 -0
- package/docs/articles/monetization/rate-cards.mdx +171 -0
- package/docs/articles/monetization/stripe-integration.md +195 -0
- package/docs/articles/monetization/subscription-lifecycle.md +298 -0
- package/docs/articles/monetization/tax-collection.md +166 -0
- package/docs/articles/monetization/troubleshooting.md +272 -0
- package/docs/articles/monetization-custom.mdx +71 -0
- package/docs/articles/monetization-integrations.mdx +104 -0
- package/docs/articles/monitoring-your-gateway.mdx +53 -0
- package/docs/articles/monorepo-deployment.mdx +350 -0
- package/docs/articles/multiple-auth-policies.mdx +81 -0
- package/docs/articles/non-standard-ports.mdx +30 -0
- package/docs/articles/oauth-authentication.mdx +54 -0
- package/docs/articles/openapi-server-urls.mdx +60 -0
- package/docs/articles/openapi.mdx +130 -0
- package/docs/articles/opentelemetry.mdx +250 -0
- package/docs/articles/per-user-rate-limits-using-db.mdx +112 -0
- package/docs/articles/performance-testing.mdx +304 -0
- package/docs/articles/plugin-akamai-api-security.mdx +76 -0
- package/docs/articles/plugin-azure-blob.mdx +73 -0
- package/docs/articles/plugin-azure-event-hubs.mdx +64 -0
- package/docs/articles/plugin-hydrolix-traffic-peak.mdx +147 -0
- package/docs/articles/policies.mdx +33 -0
- package/docs/articles/rename-or-move-project.mdx +39 -0
- package/docs/articles/rick-and-morty-api-developer-portal-example.mdx +23 -0
- package/docs/articles/routing.mdx +193 -0
- package/docs/articles/s3-signed-url-uploads.mdx +521 -0
- package/docs/articles/secure-tunnel.mdx +84 -0
- package/docs/articles/securing-backend-mtls.mdx +268 -0
- package/docs/articles/securing-your-backend.mdx +148 -0
- package/docs/articles/security.mdx +105 -0
- package/docs/articles/sharing-code-across-projects.mdx +412 -0
- package/docs/articles/source-control-setup-azure.mdx +13 -0
- package/docs/articles/source-control-setup-bitbucket.mdx +43 -0
- package/docs/articles/source-control-setup-github.mdx +172 -0
- package/docs/articles/source-control-setup-gitlab.mdx +12 -0
- package/docs/articles/source-control.mdx +80 -0
- package/docs/articles/step-1-setup-basic-gateway-local.mdx +136 -0
- package/docs/articles/step-1-setup-basic-gateway.mdx +118 -0
- package/docs/articles/step-2-add-rate-limiting-local.mdx +126 -0
- package/docs/articles/step-2-add-rate-limiting.mdx +82 -0
- package/docs/articles/step-3-add-api-key-auth-local.mdx +199 -0
- package/docs/articles/step-3-add-api-key-auth.mdx +166 -0
- package/docs/articles/step-4-deploying-to-the-edge.mdx +220 -0
- package/docs/articles/step-5-dynamic-rate-limiting.mdx +167 -0
- package/docs/articles/support.mdx +144 -0
- package/docs/articles/terraform.mdx +114 -0
- package/docs/articles/testing-graphql.mdx +34 -0
- package/docs/articles/testing.mdx +522 -0
- package/docs/articles/troubleshooting-slow-responses.mdx +301 -0
- package/docs/articles/troubleshooting.md +302 -0
- package/docs/articles/tsconfig.mdx +105 -0
- package/docs/articles/tunnel-setup.mdx +195 -0
- package/docs/articles/tunnel-troubleshooting.mdx +50 -0
- package/docs/articles/update-zup-in-github-action.mdx +110 -0
- package/docs/articles/use-openapi-extension-data.mdx +79 -0
- package/docs/articles/users/multifactor-authentication.mdx +64 -0
- package/docs/articles/users/profile.mdx +13 -0
- package/docs/articles/versioning-on-zuplo.mdx +89 -0
- package/docs/articles/waf-ddos-akamai.md +133 -0
- package/docs/articles/waf-ddos-aws-waf-shield.mdx +85 -0
- package/docs/articles/waf-ddos-fastly.mdx +251 -0
- package/docs/articles/waf-ddos.mdx +140 -0
- package/docs/articles/zuplo-waf.mdx +156 -0
- package/docs/ask.mdx +3 -0
- package/docs/cli/authentication.mdx +56 -0
- package/docs/cli/connectivity.mdx +38 -0
- package/docs/cli/create-zuplo-api.mdx +80 -0
- package/docs/cli/delete.mdx +79 -0
- package/docs/cli/deploy.mdx +156 -0
- package/docs/cli/deploy.partial.mdx +46 -0
- package/docs/cli/dev.mdx +115 -0
- package/docs/cli/docs.mdx +66 -0
- package/docs/cli/editor.mdx +50 -0
- package/docs/cli/global-options.mdx +19 -0
- package/docs/cli/init.mdx +74 -0
- package/docs/cli/link.mdx +74 -0
- package/docs/cli/list.mdx +55 -0
- package/docs/cli/mtls-certificate-create.mdx +94 -0
- package/docs/cli/mtls-certificate-delete.mdx +55 -0
- package/docs/cli/mtls-certificate-describe.mdx +55 -0
- package/docs/cli/mtls-certificate-disable.mdx +55 -0
- package/docs/cli/mtls-certificate-list.mdx +47 -0
- package/docs/cli/mtls-certificate-update.mdx +72 -0
- package/docs/cli/openapi-convert.mdx +111 -0
- package/docs/cli/openapi-merge.mdx +138 -0
- package/docs/cli/openapi-merge.partial.mdx +29 -0
- package/docs/cli/openapi-overlay.mdx +123 -0
- package/docs/cli/overview.mdx +78 -0
- package/docs/cli/project-create.mdx +43 -0
- package/docs/cli/source-migrate.mdx +18 -0
- package/docs/cli/source-upgrade.mdx +41 -0
- package/docs/cli/test.mdx +70 -0
- package/docs/cli/test.partial.mdx +7 -0
- package/docs/cli/tunnel-create.mdx +53 -0
- package/docs/cli/tunnel-create.partial.mdx +9 -0
- package/docs/cli/tunnel-delete.mdx +35 -0
- package/docs/cli/tunnel-delete.partial.mdx +9 -0
- package/docs/cli/tunnel-describe.mdx +45 -0
- package/docs/cli/tunnel-describe.partial.mdx +5 -0
- package/docs/cli/tunnel-list.mdx +35 -0
- package/docs/cli/tunnel-list.partial.mdx +9 -0
- package/docs/cli/tunnel-rate-token.partial.mdx +9 -0
- package/docs/cli/tunnel-rotate-token.mdx +39 -0
- package/docs/cli/tunnel-services-describe.mdx +45 -0
- package/docs/cli/tunnel-services-describe.partial.mdx +9 -0
- package/docs/cli/tunnel-services-update.mdx +48 -0
- package/docs/cli/variable-create.mdx +91 -0
- package/docs/cli/variable-create.partial.mdx +5 -0
- package/docs/cli/variable-update.mdx +75 -0
- package/docs/cli/variable-update.partial.mdx +5 -0
- package/docs/concepts/api-keys.md +146 -0
- package/docs/concepts/authentication.mdx +109 -0
- package/docs/concepts/how-zuplo-works.mdx +120 -0
- package/docs/concepts/project-structure.mdx +174 -0
- package/docs/concepts/rate-limiting.md +246 -0
- package/docs/concepts/request-lifecycle.mdx +56 -0
- package/docs/concepts/source-control-and-deployment.mdx +229 -0
- package/docs/conferences/conference-prize-terms.mdx +80 -0
- package/docs/dedicated/akamai/ai-powered-applications.mdx +223 -0
- package/docs/dedicated/akamai/architecture.mdx +280 -0
- package/docs/dedicated/akamai/caching.mdx +212 -0
- package/docs/dedicated/akamai/cdn.mdx +156 -0
- package/docs/dedicated/architecture.mdx +208 -0
- package/docs/dedicated/custom-domains.mdx +31 -0
- package/docs/dedicated/federated-gateways.mdx +80 -0
- package/docs/dedicated/networking.mdx +69 -0
- package/docs/dedicated/overview.mdx +80 -0
- package/docs/dedicated/source-control.mdx +63 -0
- package/docs/dev-portal/dev-portal-create-consumer-on-auth.mdx +134 -0
- package/docs/dev-portal/introduction.mdx +65 -0
- package/docs/dev-portal/local-development.mdx +72 -0
- package/docs/dev-portal/migration.mdx +526 -0
- package/docs/dev-portal/node-modules.mdx +45 -0
- package/docs/dev-portal/updating.mdx +28 -0
- package/docs/dev-portal/zudoku/components/alert.mdx +130 -0
- package/docs/dev-portal/zudoku/components/badge.mdx +70 -0
- package/docs/dev-portal/zudoku/components/button.mdx +132 -0
- package/docs/dev-portal/zudoku/components/callout.mdx +112 -0
- package/docs/dev-portal/zudoku/components/card.mdx +104 -0
- package/docs/dev-portal/zudoku/components/checkbox.mdx +72 -0
- package/docs/dev-portal/zudoku/components/client-only.mdx +79 -0
- package/docs/dev-portal/zudoku/components/code-tabs.mdx +179 -0
- package/docs/dev-portal/zudoku/components/dialog.mdx +167 -0
- package/docs/dev-portal/zudoku/components/head.mdx +199 -0
- package/docs/dev-portal/zudoku/components/icons.mdx +27 -0
- package/docs/dev-portal/zudoku/components/input.mdx +96 -0
- package/docs/dev-portal/zudoku/components/label.mdx +86 -0
- package/docs/dev-portal/zudoku/components/link.mdx +242 -0
- package/docs/dev-portal/zudoku/components/markdown.mdx +151 -0
- package/docs/dev-portal/zudoku/components/mermaid.mdx +81 -0
- package/docs/dev-portal/zudoku/components/playground.mdx +87 -0
- package/docs/dev-portal/zudoku/components/secret.mdx +78 -0
- package/docs/dev-portal/zudoku/components/select.mdx +176 -0
- package/docs/dev-portal/zudoku/components/shadcn.mdx +73 -0
- package/docs/dev-portal/zudoku/components/slider.mdx +108 -0
- package/docs/dev-portal/zudoku/components/slot.mdx +119 -0
- package/docs/dev-portal/zudoku/components/stepper.mdx +138 -0
- package/docs/dev-portal/zudoku/components/switch.mdx +96 -0
- package/docs/dev-portal/zudoku/components/syntax-highlight.mdx +602 -0
- package/docs/dev-portal/zudoku/components/textarea.mdx +78 -0
- package/docs/dev-portal/zudoku/components/tooltip.mdx +195 -0
- package/docs/dev-portal/zudoku/components/typography.mdx +61 -0
- package/docs/dev-portal/zudoku/configuration/ai-assistants.md +64 -0
- package/docs/dev-portal/zudoku/configuration/api-catalog.md +108 -0
- package/docs/dev-portal/zudoku/configuration/api-reference.md +397 -0
- package/docs/dev-portal/zudoku/configuration/authentication-auth0.md +173 -0
- package/docs/dev-portal/zudoku/configuration/authentication-azure-ad.md +238 -0
- package/docs/dev-portal/zudoku/configuration/authentication-clerk.md +110 -0
- package/docs/dev-portal/zudoku/configuration/authentication-firebase.md +61 -0
- package/docs/dev-portal/zudoku/configuration/authentication-pingfederate.md +136 -0
- package/docs/dev-portal/zudoku/configuration/authentication-supabase.md +225 -0
- package/docs/dev-portal/zudoku/configuration/authentication.md +199 -0
- package/docs/dev-portal/zudoku/configuration/build-configuration.mdx +147 -0
- package/docs/dev-portal/zudoku/configuration/docs.md +282 -0
- package/docs/dev-portal/zudoku/configuration/footer.mdx +214 -0
- package/docs/dev-portal/zudoku/configuration/llms.md +89 -0
- package/docs/dev-portal/zudoku/configuration/navigation.mdx +408 -0
- package/docs/dev-portal/zudoku/configuration/overview.md +380 -0
- package/docs/dev-portal/zudoku/configuration/protected-routes.md +149 -0
- package/docs/dev-portal/zudoku/configuration/search.md +169 -0
- package/docs/dev-portal/zudoku/configuration/sentry.mdx +44 -0
- package/docs/dev-portal/zudoku/configuration/site.md +124 -0
- package/docs/dev-portal/zudoku/configuration/slots.mdx +124 -0
- package/docs/dev-portal/zudoku/configuration/vite-config.md +18 -0
- package/docs/dev-portal/zudoku/custom-plugins.md +287 -0
- package/docs/dev-portal/zudoku/customization/colors-theme.mdx +275 -0
- package/docs/dev-portal/zudoku/customization/fonts.md +110 -0
- package/docs/dev-portal/zudoku/extending/events.md +124 -0
- package/docs/dev-portal/zudoku/guides/custom-pages.md +106 -0
- package/docs/dev-portal/zudoku/guides/environment-variables.md +99 -0
- package/docs/dev-portal/zudoku/guides/mermaid.mdx +70 -0
- package/docs/dev-portal/zudoku/guides/navigation-migration.md +87 -0
- package/docs/dev-portal/zudoku/guides/navigation-rules.mdx +197 -0
- package/docs/dev-portal/zudoku/guides/processors.mdx +234 -0
- package/docs/dev-portal/zudoku/guides/static-files.md +55 -0
- package/docs/dev-portal/zudoku/guides/transforming-examples.md +156 -0
- package/docs/dev-portal/zudoku/guides/using-multiple-apis.md +87 -0
- package/docs/dev-portal/zudoku/markdown/admonitions.md +128 -0
- package/docs/dev-portal/zudoku/markdown/code-blocks.md +196 -0
- package/docs/dev-portal/zudoku/markdown/frontmatter.md +172 -0
- package/docs/dev-portal/zudoku/markdown/mdx.md +68 -0
- package/docs/dev-portal/zudoku/markdown/overview.md +275 -0
- package/docs/dev-portal/zudoku/plugins.md +5 -0
- package/docs/dev-portal/zudoku/writing.mdx +72 -0
- package/docs/errors/bad-request.mdx +39 -0
- package/docs/errors/build-error.mdx +45 -0
- package/docs/errors/fatal-project-error.mdx +39 -0
- package/docs/errors/gateway-timeout.mdx +33 -0
- package/docs/errors/get-head-body-error.mdx +41 -0
- package/docs/errors/main-mod-error.mdx +40 -0
- package/docs/errors/no-project-set.mdx +41 -0
- package/docs/errors/not-found.mdx +43 -0
- package/docs/errors/rate-limit-exceeded.mdx +31 -0
- package/docs/errors/schema-validation-failed.mdx +51 -0
- package/docs/errors/system-configuration-error.mdx +44 -0
- package/docs/errors/unauthorized.mdx +50 -0
- package/docs/errors/unknown-error.mdx +42 -0
- package/docs/errors.mdx +14 -0
- package/docs/guides/canary-routing-for-employees.mdx +385 -0
- package/docs/guides/geolocation-backend-routing.mdx +404 -0
- package/docs/guides/modify-openapi-paths.mdx +371 -0
- package/docs/guides/openapi-overlays.mdx +492 -0
- package/docs/guides/overview.mdx +12 -0
- package/docs/guides/user-based-backend-routing.mdx +437 -0
- package/docs/handlers/aws-lambda.mdx +201 -0
- package/docs/handlers/custom-handler.mdx +112 -0
- package/docs/handlers/legacy-dev-portal-handler.mdx +135 -0
- package/docs/handlers/mcp-server.mdx +730 -0
- package/docs/handlers/openapi.mdx +78 -0
- package/docs/handlers/redirect.mdx +115 -0
- package/docs/handlers/system-handlers.mdx +41 -0
- package/docs/handlers/url-forward.mdx +204 -0
- package/docs/handlers/url-rewrite.mdx +224 -0
- package/docs/handlers/websocket-handler.mdx +154 -0
- package/docs/home.mdx +6 -0
- package/docs/managed-edge/overview.md +78 -0
- package/docs/mcp-server/configuration-migration-guide.mdx +344 -0
- package/docs/mcp-server/custom-tools.mdx +487 -0
- package/docs/mcp-server/graphql.mdx +241 -0
- package/docs/mcp-server/introduction.mdx +122 -0
- package/docs/mcp-server/openai-apps-sdk.mdx +160 -0
- package/docs/mcp-server/prompts.mdx +283 -0
- package/docs/mcp-server/resources.mdx +288 -0
- package/docs/mcp-server/testing.mdx +53 -0
- package/docs/mcp-server/tools.mdx +306 -0
- package/docs/policies/_index.md +92 -0
- package/docs/policies/ab-test-inbound/intro.md +8 -0
- package/docs/policies/ab-test-inbound/policy.ts +14 -0
- package/docs/policies/ab-test-inbound/schema.json +27 -0
- package/docs/policies/ab-test-outbound/intro.md +8 -0
- package/docs/policies/ab-test-outbound/policy.ts +26 -0
- package/docs/policies/ab-test-outbound/schema.json +27 -0
- package/docs/policies/acl-policy-inbound/intro.md +5 -0
- package/docs/policies/acl-policy-inbound/policy.ts +32 -0
- package/docs/policies/acl-policy-inbound/schema.json +52 -0
- package/docs/policies/akamai-ai-firewall/schema.json +98 -0
- package/docs/policies/amberflo-metering-inbound/doc.md +183 -0
- package/docs/policies/amberflo-metering-inbound/intro.md +20 -0
- package/docs/policies/amberflo-metering-inbound/schema.json +108 -0
- package/docs/policies/api-key-inbound/doc.md +77 -0
- package/docs/policies/api-key-inbound/intro.md +30 -0
- package/docs/policies/api-key-inbound/schema.json +84 -0
- package/docs/policies/archive-request-aws-s3-inbound/intro.md +4 -0
- package/docs/policies/archive-request-aws-s3-inbound/policy.ts +58 -0
- package/docs/policies/archive-request-aws-s3-inbound/schema.json +68 -0
- package/docs/policies/archive-request-azure-storage-inbound/doc.md +31 -0
- package/docs/policies/archive-request-azure-storage-inbound/intro.md +4 -0
- package/docs/policies/archive-request-azure-storage-inbound/policy.ts +54 -0
- package/docs/policies/archive-request-azure-storage-inbound/schema.json +53 -0
- package/docs/policies/archive-request-gcp-storage-inbound/doc.md +63 -0
- package/docs/policies/archive-request-gcp-storage-inbound/intro.md +4 -0
- package/docs/policies/archive-request-gcp-storage-inbound/policy.ts +68 -0
- package/docs/policies/archive-request-gcp-storage-inbound/schema.json +47 -0
- package/docs/policies/archive-response-aws-s3-outbound/intro.md +2 -0
- package/docs/policies/archive-response-aws-s3-outbound/policy.ts +59 -0
- package/docs/policies/archive-response-aws-s3-outbound/schema.json +68 -0
- package/docs/policies/archive-response-azure-storage-outbound/doc.md +31 -0
- package/docs/policies/archive-response-azure-storage-outbound/intro.md +3 -0
- package/docs/policies/archive-response-azure-storage-outbound/policy.ts +54 -0
- package/docs/policies/archive-response-azure-storage-outbound/schema.json +53 -0
- package/docs/policies/audit-log-inbound/doc.md +78 -0
- package/docs/policies/audit-log-inbound/intro.md +10 -0
- package/docs/policies/audit-log-inbound/schema.json +81 -0
- package/docs/policies/auth0-jwt-auth-inbound/doc.md +125 -0
- package/docs/policies/auth0-jwt-auth-inbound/intro.md +17 -0
- package/docs/policies/auth0-jwt-auth-inbound/schema.json +74 -0
- package/docs/policies/authzen-inbound/doc.md +24 -0
- package/docs/policies/authzen-inbound/intro.md +31 -0
- package/docs/policies/authzen-inbound/schema.json +126 -0
- package/docs/policies/axiomatics-authz-inbound/doc.md +144 -0
- package/docs/policies/axiomatics-authz-inbound/intro.md +11 -0
- package/docs/policies/axiomatics-authz-inbound/schema.json +161 -0
- package/docs/policies/basic-auth-inbound/intro.md +9 -0
- package/docs/policies/basic-auth-inbound/schema.json +99 -0
- package/docs/policies/bot-detection-inbound/intro.md +4 -0
- package/docs/policies/bot-detection-inbound/schema.json +56 -0
- package/docs/policies/brownout-inbound/doc.md +55 -0
- package/docs/policies/brownout-inbound/intro.md +12 -0
- package/docs/policies/brownout-inbound/schema.json +115 -0
- package/docs/policies/caching-inbound/doc.md +209 -0
- package/docs/policies/caching-inbound/intro.md +23 -0
- package/docs/policies/caching-inbound/schema.json +98 -0
- package/docs/policies/change-method-inbound/schema.json +56 -0
- package/docs/policies/clear-headers-inbound/schema.json +59 -0
- package/docs/policies/clear-headers-outbound/schema.json +59 -0
- package/docs/policies/clerk-jwt-auth-inbound/doc.md +85 -0
- package/docs/policies/clerk-jwt-auth-inbound/intro.md +4 -0
- package/docs/policies/clerk-jwt-auth-inbound/schema.json +68 -0
- package/docs/policies/cognito-jwt-auth-inbound/intro.md +7 -0
- package/docs/policies/cognito-jwt-auth-inbound/schema.json +74 -0
- package/docs/policies/comet-opik-tracing-inbound/schema.json +65 -0
- package/docs/policies/complex-rate-limit-inbound/doc.md +20 -0
- package/docs/policies/complex-rate-limit-inbound/intro.md +23 -0
- package/docs/policies/complex-rate-limit-inbound/schema.json +142 -0
- package/docs/policies/composite-inbound/doc.md +69 -0
- package/docs/policies/composite-inbound/intro.md +15 -0
- package/docs/policies/composite-inbound/schema.json +59 -0
- package/docs/policies/composite-outbound/intro.md +6 -0
- package/docs/policies/composite-outbound/schema.json +59 -0
- package/docs/policies/curity-phantom-token-inbound/doc.md +109 -0
- package/docs/policies/curity-phantom-token-inbound/intro.md +3 -0
- package/docs/policies/curity-phantom-token-inbound/schema.json +68 -0
- package/docs/policies/custom-code-inbound/doc.md +267 -0
- package/docs/policies/custom-code-inbound/intro.md +2 -0
- package/docs/policies/custom-code-inbound/schema.json +48 -0
- package/docs/policies/custom-code-outbound/doc.md +235 -0
- package/docs/policies/custom-code-outbound/intro.md +2 -0
- package/docs/policies/custom-code-outbound/schema.json +43 -0
- package/docs/policies/firebase-jwt-inbound/intro.md +6 -0
- package/docs/policies/firebase-jwt-inbound/schema.json +68 -0
- package/docs/policies/formdata-to-json-inbound/schema.json +60 -0
- package/docs/policies/galileo-tracing-inbound/schema.json +65 -0
- package/docs/policies/geo-filter-inbound/doc.md +33 -0
- package/docs/policies/geo-filter-inbound/schema.json +108 -0
- package/docs/policies/graphql-complexity-limit-inbound/doc.md +48 -0
- package/docs/policies/graphql-complexity-limit-inbound/intro.md +2 -0
- package/docs/policies/graphql-complexity-limit-inbound/schema.json +90 -0
- package/docs/policies/graphql-disable-introspection-inbound/doc.md +66 -0
- package/docs/policies/graphql-disable-introspection-inbound/intro.md +15 -0
- package/docs/policies/graphql-disable-introspection-inbound/schema.json +48 -0
- package/docs/policies/graphql-introspection-filter-outbound/doc.md +148 -0
- package/docs/policies/graphql-introspection-filter-outbound/schema.json +79 -0
- package/docs/policies/hmac-auth-inbound/doc.md +30 -0
- package/docs/policies/hmac-auth-inbound/intro.md +10 -0
- package/docs/policies/hmac-auth-inbound/policy.ts +70 -0
- package/docs/policies/hmac-auth-inbound/schema.json +53 -0
- package/docs/policies/http-deprecation-outbound/doc.md +73 -0
- package/docs/policies/http-deprecation-outbound/schema.json +83 -0
- package/docs/policies/ip-restriction-inbound/intro.md +8 -0
- package/docs/policies/ip-restriction-inbound/policy.ts +40 -0
- package/docs/policies/ip-restriction-inbound/schema.json +58 -0
- package/docs/policies/jwt-scopes-inbound/schema.json +59 -0
- package/docs/policies/ldap-auth-inbound/schema.json +56 -0
- package/docs/policies/mock-api-inbound/schema.json +72 -0
- package/docs/policies/moesif-inbound/doc.md +44 -0
- package/docs/policies/moesif-inbound/intro.md +6 -0
- package/docs/policies/moesif-inbound/schema.json +68 -0
- package/docs/policies/monetization-inbound/doc.md +87 -0
- package/docs/policies/monetization-inbound/intro.md +6 -0
- package/docs/policies/monetization-inbound/schema.json +102 -0
- package/docs/policies/mtls-auth-inbound/intro.md +6 -0
- package/docs/policies/mtls-auth-inbound/schema.json +68 -0
- package/docs/policies/okta-fga-authz-inbound/doc.md +181 -0
- package/docs/policies/okta-fga-authz-inbound/intro.md +20 -0
- package/docs/policies/okta-fga-authz-inbound/schema.json +104 -0
- package/docs/policies/okta-jwt-auth-inbound/intro.md +7 -0
- package/docs/policies/okta-jwt-auth-inbound/schema.json +74 -0
- package/docs/policies/open-id-jwt-auth-inbound/doc.md +58 -0
- package/docs/policies/open-id-jwt-auth-inbound/intro.md +30 -0
- package/docs/policies/open-id-jwt-auth-inbound/schema.json +128 -0
- package/docs/policies/openfga-authz-inbound/doc.md +207 -0
- package/docs/policies/openfga-authz-inbound/intro.md +17 -0
- package/docs/policies/openfga-authz-inbound/schema.json +191 -0
- package/docs/policies/openmeter-inbound/doc.md +163 -0
- package/docs/policies/openmeter-inbound/intro.md +18 -0
- package/docs/policies/openmeter-inbound/schema.json +183 -0
- package/docs/policies/prompt-injection-outbound/doc.md +106 -0
- package/docs/policies/prompt-injection-outbound/intro.md +4 -0
- package/docs/policies/prompt-injection-outbound/schema.json +74 -0
- package/docs/policies/propel-auth-jwt-inbound/doc.md +88 -0
- package/docs/policies/propel-auth-jwt-inbound/intro.md +4 -0
- package/docs/policies/propel-auth-jwt-inbound/schema.json +74 -0
- package/docs/policies/query-param-to-header-inbound/doc.md +70 -0
- package/docs/policies/query-param-to-header-inbound/intro.md +5 -0
- package/docs/policies/query-param-to-header-inbound/schema.json +74 -0
- package/docs/policies/quota-inbound/doc.md +235 -0
- package/docs/policies/quota-inbound/intro.md +7 -0
- package/docs/policies/quota-inbound/schema.json +133 -0
- package/docs/policies/rate-limit-inbound/doc.md +78 -0
- package/docs/policies/rate-limit-inbound/intro.md +30 -0
- package/docs/policies/rate-limit-inbound/schema.json +134 -0
- package/docs/policies/rbac-policy-inbound/intro.md +3 -0
- package/docs/policies/rbac-policy-inbound/policy.ts +42 -0
- package/docs/policies/rbac-policy-inbound/schema.json +52 -0
- package/docs/policies/readme-metrics-inbound/doc.md +1 -0
- package/docs/policies/readme-metrics-inbound/intro.md +3 -0
- package/docs/policies/readme-metrics-inbound/schema.json +84 -0
- package/docs/policies/remove-headers-inbound/schema.json +59 -0
- package/docs/policies/remove-headers-outbound/schema.json +59 -0
- package/docs/policies/remove-query-params-inbound/schema.json +59 -0
- package/docs/policies/replace-string-outbound/schema.json +69 -0
- package/docs/policies/request-size-limit-inbound/schema.json +60 -0
- package/docs/policies/request-validation-inbound/doc.md +72 -0
- package/docs/policies/request-validation-inbound/intro.md +24 -0
- package/docs/policies/request-validation-inbound/schema.json +98 -0
- package/docs/policies/require-origin-inbound/intro.md +12 -0
- package/docs/policies/require-origin-inbound/schema.json +65 -0
- package/docs/policies/secret-masking-outbound/doc.md +41 -0
- package/docs/policies/secret-masking-outbound/intro.md +13 -0
- package/docs/policies/secret-masking-outbound/schema.json +65 -0
- package/docs/policies/semantic-cache-inbound/doc.md +63 -0
- package/docs/policies/semantic-cache-inbound/intro.md +4 -0
- package/docs/policies/semantic-cache-inbound/schema.json +179 -0
- package/docs/policies/set-body-inbound/intro.md +7 -0
- package/docs/policies/set-body-inbound/schema.json +56 -0
- package/docs/policies/set-headers-inbound/doc.md +41 -0
- package/docs/policies/set-headers-inbound/intro.md +2 -0
- package/docs/policies/set-headers-inbound/schema.json +83 -0
- package/docs/policies/set-headers-outbound/schema.json +83 -0
- package/docs/policies/set-query-params-inbound/schema.json +83 -0
- package/docs/policies/set-status-outbound/schema.json +62 -0
- package/docs/policies/sleep-inbound/schema.json +56 -0
- package/docs/policies/stripe-webhook-verification-inbound/intro.md +2 -0
- package/docs/policies/stripe-webhook-verification-inbound/schema.json +60 -0
- package/docs/policies/supabase-jwt-auth-inbound/doc.md +29 -0
- package/docs/policies/supabase-jwt-auth-inbound/intro.md +12 -0
- package/docs/policies/supabase-jwt-auth-inbound/schema.json +86 -0
- package/docs/policies/transform-body-inbound/intro.md +8 -0
- package/docs/policies/transform-body-inbound/policy.ts +16 -0
- package/docs/policies/transform-body-inbound/schema.json +27 -0
- package/docs/policies/transform-body-outbound/intro.md +8 -0
- package/docs/policies/transform-body-outbound/policy.ts +19 -0
- package/docs/policies/transform-body-outbound/schema.json +27 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/doc.md +82 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/intro.md +20 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +84 -0
- package/docs/policies/upstream-firebase-admin-auth-inbound/intro.md +10 -0
- package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +68 -0
- package/docs/policies/upstream-firebase-user-auth-inbound/intro.md +2 -0
- package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +113 -0
- package/docs/policies/upstream-gcp-federated-auth-inbound/doc.md +139 -0
- package/docs/policies/upstream-gcp-federated-auth-inbound/intro.md +21 -0
- package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +96 -0
- package/docs/policies/upstream-gcp-jwt-inbound/intro.md +10 -0
- package/docs/policies/upstream-gcp-jwt-inbound/schema.json +62 -0
- package/docs/policies/upstream-gcp-service-auth-inbound/doc.md +132 -0
- package/docs/policies/upstream-gcp-service-auth-inbound/intro.md +25 -0
- package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +95 -0
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/doc.md +213 -0
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/intro.md +16 -0
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +101 -0
- package/docs/policies/validate-json-schema-inbound/doc.md +129 -0
- package/docs/policies/validate-json-schema-inbound/intro.md +7 -0
- package/docs/policies/validate-json-schema-inbound/schema.json +56 -0
- package/docs/policies/web-bot-auth-inbound/doc.md +104 -0
- package/docs/policies/web-bot-auth-inbound/intro.md +16 -0
- package/docs/policies/web-bot-auth-inbound/schema.json +76 -0
- package/docs/policies/xml-to-json-outbound/doc.md +71 -0
- package/docs/policies/xml-to-json-outbound/intro.md +4 -0
- package/docs/policies/xml-to-json-outbound/schema.json +117 -0
- package/docs/programmable-api/audit-log.mdx +74 -0
- package/docs/programmable-api/background-dispatcher.mdx +124 -0
- package/docs/programmable-api/background-loader.mdx +104 -0
- package/docs/programmable-api/cache.mdx +186 -0
- package/docs/programmable-api/compatibility-dates.mdx +201 -0
- package/docs/programmable-api/console-logging.mdx +48 -0
- package/docs/programmable-api/context-data.mdx +127 -0
- package/docs/programmable-api/custom-cors-policy.mdx +64 -0
- package/docs/programmable-api/environment.mdx +328 -0
- package/docs/programmable-api/hooks.mdx +569 -0
- package/docs/programmable-api/http-problems.mdx +385 -0
- package/docs/programmable-api/jwt-service-plugin.mdx +420 -0
- package/docs/programmable-api/logger.mdx +223 -0
- package/docs/programmable-api/memory-zone-read-through-cache.mdx +96 -0
- package/docs/programmable-api/node-modules.mdx +67 -0
- package/docs/programmable-api/not-found-handler.mdx +47 -0
- package/docs/programmable-api/oauth-protected-resource-plugin.mdx +46 -0
- package/docs/programmable-api/overview.mdx +213 -0
- package/docs/programmable-api/problem-response-formatter.mdx +183 -0
- package/docs/programmable-api/request-user.mdx +289 -0
- package/docs/programmable-api/reusing-code.mdx +26 -0
- package/docs/programmable-api/route-raw.mdx +55 -0
- package/docs/programmable-api/runtime-behaviors.mdx +25 -0
- package/docs/programmable-api/runtime-errors.mdx +246 -0
- package/docs/programmable-api/runtime-extensions.mdx +340 -0
- package/docs/programmable-api/safely-clone-a-request-or-response.mdx +57 -0
- package/docs/programmable-api/streaming-zone-cache.mdx +155 -0
- package/docs/programmable-api/web-crypto-apis.mdx +219 -0
- package/docs/programmable-api/web-standard-apis.mdx +109 -0
- package/docs/programmable-api/zone-cache.mdx +131 -0
- package/docs/programmable-api/zp-body-removed.mdx +32 -0
- package/docs/programmable-api/zuplo-context.mdx +414 -0
- package/docs/programmable-api/zuplo-id-token.mdx +90 -0
- package/docs/programmable-api/zuplo-json.mdx +91 -0
- package/docs/programmable-api/zuplo-request.mdx +200 -0
- package/docs/sample-apis.mdx +78 -0
- package/docs/self-hosted/overview.md +60 -0
- package/package.json +6 -5
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Custom Code Patterns
|
|
3
|
+
sidebar_label: Custom Code
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Zuplo is fully programmable. You can write custom TypeScript code for inbound
|
|
7
|
+
policies, outbound policies, and request handlers to extend every part of your
|
|
8
|
+
API gateway. This guide covers the function signatures, common patterns, and
|
|
9
|
+
best practices for writing custom code.
|
|
10
|
+
|
|
11
|
+
## Custom Inbound Policy
|
|
12
|
+
|
|
13
|
+
An inbound policy runs before the request handler. It receives the incoming
|
|
14
|
+
request and can modify it, pass it along, or short-circuit the pipeline by
|
|
15
|
+
returning a `Response`.
|
|
16
|
+
|
|
17
|
+
### Function Signature
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
export type InboundPolicyHandler<TOptions = any> = (
|
|
21
|
+
request: ZuploRequest,
|
|
22
|
+
context: ZuploContext,
|
|
23
|
+
options: TOptions,
|
|
24
|
+
policyName: string,
|
|
25
|
+
) => Promise<ZuploRequest | Response>;
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Return a `ZuploRequest` to continue the pipeline.
|
|
29
|
+
- Return a `Response` to short-circuit and respond immediately.
|
|
30
|
+
|
|
31
|
+
### Example: Validate a Custom Header
|
|
32
|
+
|
|
33
|
+
```ts title="modules/require-tenant-header.ts"
|
|
34
|
+
import { ZuploContext, ZuploRequest, HttpProblems } from "@zuplo/runtime";
|
|
35
|
+
|
|
36
|
+
interface PolicyOptions {
|
|
37
|
+
headerName: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default async function (
|
|
41
|
+
request: ZuploRequest,
|
|
42
|
+
context: ZuploContext,
|
|
43
|
+
options: PolicyOptions,
|
|
44
|
+
policyName: string,
|
|
45
|
+
): Promise<ZuploRequest | Response> {
|
|
46
|
+
const value = request.headers.get(options.headerName);
|
|
47
|
+
|
|
48
|
+
if (!value) {
|
|
49
|
+
return HttpProblems.badRequest(request, context, {
|
|
50
|
+
detail: `Missing required header '${options.headerName}'.`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Store the value for downstream consumption
|
|
55
|
+
context.custom.tenantId = value;
|
|
56
|
+
|
|
57
|
+
return request;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Policy Configuration
|
|
62
|
+
|
|
63
|
+
Register the policy in `config/policies.json` and reference it on your routes:
|
|
64
|
+
|
|
65
|
+
```json title="config/policies.json"
|
|
66
|
+
{
|
|
67
|
+
"name": "require-tenant-header",
|
|
68
|
+
"policyType": "custom-code-inbound",
|
|
69
|
+
"handler": {
|
|
70
|
+
"export": "default",
|
|
71
|
+
"module": "$import(./modules/require-tenant-header)",
|
|
72
|
+
"options": {
|
|
73
|
+
"headerName": "x-tenant-id"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For details on wiring policies to routes, see
|
|
80
|
+
[Policy Fundamentals](./policies.md).
|
|
81
|
+
|
|
82
|
+
## Custom Outbound Policy
|
|
83
|
+
|
|
84
|
+
An outbound policy runs after the handler returns a response. It can inspect or
|
|
85
|
+
transform the response before it reaches the client.
|
|
86
|
+
|
|
87
|
+
:::note
|
|
88
|
+
|
|
89
|
+
Outbound policies only execute when the response status code is in the 200-299
|
|
90
|
+
range (`response.ok === true`).
|
|
91
|
+
|
|
92
|
+
:::
|
|
93
|
+
|
|
94
|
+
### Function Signature
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
export type OutboundPolicyHandler<TOptions = any> = (
|
|
98
|
+
response: Response,
|
|
99
|
+
request: ZuploRequest,
|
|
100
|
+
context: ZuploContext,
|
|
101
|
+
options: TOptions,
|
|
102
|
+
policyName: string,
|
|
103
|
+
) => Promise<Response>;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Example: Add Custom Response Headers
|
|
107
|
+
|
|
108
|
+
```ts title="modules/add-response-headers.ts"
|
|
109
|
+
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
110
|
+
|
|
111
|
+
export default async function (
|
|
112
|
+
response: Response,
|
|
113
|
+
request: ZuploRequest,
|
|
114
|
+
context: ZuploContext,
|
|
115
|
+
): Promise<Response> {
|
|
116
|
+
// Create a new response to get mutable headers
|
|
117
|
+
const newResponse = new Response(response.body, {
|
|
118
|
+
status: response.status,
|
|
119
|
+
headers: response.headers,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
newResponse.headers.set("x-request-id", context.requestId);
|
|
123
|
+
newResponse.headers.set("x-tenant-id", context.custom.tenantId ?? "unknown");
|
|
124
|
+
|
|
125
|
+
return newResponse;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Register outbound policies the same way as inbound, using `custom-code-outbound`
|
|
130
|
+
as the `policyType`. See
|
|
131
|
+
[Custom Code Outbound Policy](../policies/custom-code-outbound.mdx) for the full
|
|
132
|
+
reference.
|
|
133
|
+
|
|
134
|
+
## Custom Request Handler
|
|
135
|
+
|
|
136
|
+
A request handler is the function that produces the response for a route. Use a
|
|
137
|
+
custom handler when you need to orchestrate calls, build a BFF
|
|
138
|
+
(backend-for-frontend), or return a fully custom response.
|
|
139
|
+
|
|
140
|
+
### Function Signature
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
export type RequestHandler = (
|
|
144
|
+
request: ZuploRequest,
|
|
145
|
+
context: ZuploContext,
|
|
146
|
+
) => Promise<any>;
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Returning a plain object or string automatically serializes the response as JSON
|
|
150
|
+
with a `content-type: application/json` header.
|
|
151
|
+
|
|
152
|
+
### Example: Aggregate Two Backend Calls
|
|
153
|
+
|
|
154
|
+
```ts title="modules/aggregate-handler.ts"
|
|
155
|
+
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
|
|
156
|
+
|
|
157
|
+
export default async function (
|
|
158
|
+
request: ZuploRequest,
|
|
159
|
+
context: ZuploContext,
|
|
160
|
+
): Promise<Response> {
|
|
161
|
+
const baseUrl = environment.BACKEND_URL;
|
|
162
|
+
|
|
163
|
+
// Run requests in parallel
|
|
164
|
+
const [usersRes, ordersRes] = await Promise.all([
|
|
165
|
+
fetch(`${baseUrl}/users/${request.params.userId}`),
|
|
166
|
+
fetch(`${baseUrl}/users/${request.params.userId}/orders`),
|
|
167
|
+
]);
|
|
168
|
+
|
|
169
|
+
if (!usersRes.ok || !ordersRes.ok) {
|
|
170
|
+
return new Response("Upstream error", { status: 502 });
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const user = await usersRes.json();
|
|
174
|
+
const orders = await ordersRes.json();
|
|
175
|
+
|
|
176
|
+
return new Response(JSON.stringify({ user, orders }), {
|
|
177
|
+
status: 200,
|
|
178
|
+
headers: { "content-type": "application/json" },
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
For the complete handler reference, see
|
|
184
|
+
[Function Handler](../handlers/custom-handler.mdx).
|
|
185
|
+
|
|
186
|
+
## Accessing Policy Options
|
|
187
|
+
|
|
188
|
+
Both inbound and outbound policies receive an `options` parameter populated from
|
|
189
|
+
the `handler.options` object in `config/policies.json`. Define a TypeScript
|
|
190
|
+
interface for type safety:
|
|
191
|
+
|
|
192
|
+
```ts title="modules/rate-limit-by-plan.ts"
|
|
193
|
+
import { ZuploContext, ZuploRequest, HttpProblems } from "@zuplo/runtime";
|
|
194
|
+
|
|
195
|
+
interface PolicyOptions {
|
|
196
|
+
defaultLimit: number;
|
|
197
|
+
premiumLimit: number;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export default async function (
|
|
201
|
+
request: ZuploRequest,
|
|
202
|
+
context: ZuploContext,
|
|
203
|
+
options: PolicyOptions,
|
|
204
|
+
policyName: string,
|
|
205
|
+
): Promise<ZuploRequest | Response> {
|
|
206
|
+
const plan = request.user?.data?.plan ?? "free";
|
|
207
|
+
const limit =
|
|
208
|
+
plan === "premium" ? options.premiumLimit : options.defaultLimit;
|
|
209
|
+
|
|
210
|
+
context.custom.rateLimit = limit;
|
|
211
|
+
context.log.info(`Applying rate limit of ${limit} for plan '${plan}'`);
|
|
212
|
+
|
|
213
|
+
return request;
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```json title="config/policies.json"
|
|
218
|
+
{
|
|
219
|
+
"name": "rate-limit-by-plan",
|
|
220
|
+
"policyType": "custom-code-inbound",
|
|
221
|
+
"handler": {
|
|
222
|
+
"export": "default",
|
|
223
|
+
"module": "$import(./modules/rate-limit-by-plan)",
|
|
224
|
+
"options": {
|
|
225
|
+
"defaultLimit": 100,
|
|
226
|
+
"premiumLimit": 10000
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
You can also reference environment variables in policy options using the
|
|
233
|
+
`$env(VARIABLE_NAME)` syntax:
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"options": {
|
|
238
|
+
"apiKey": "$env(BACKEND_API_KEY)"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Passing Data Between Pipeline Stages
|
|
244
|
+
|
|
245
|
+
Use `context.custom` to share data between policies and the request handler
|
|
246
|
+
within a single request. It is a mutable object that lives for the lifetime of
|
|
247
|
+
the request.
|
|
248
|
+
|
|
249
|
+
```ts title="modules/auth-policy.ts"
|
|
250
|
+
// Inbound policy: attach metadata
|
|
251
|
+
export default async function (
|
|
252
|
+
request: ZuploRequest,
|
|
253
|
+
context: ZuploContext,
|
|
254
|
+
): Promise<ZuploRequest | Response> {
|
|
255
|
+
context.custom.userId = request.user?.sub;
|
|
256
|
+
context.custom.plan = request.user?.data?.plan ?? "free";
|
|
257
|
+
context.custom.requestStart = Date.now();
|
|
258
|
+
return request;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```ts title="modules/my-handler.ts"
|
|
263
|
+
// Handler: read metadata set by the policy
|
|
264
|
+
export default async function (
|
|
265
|
+
request: ZuploRequest,
|
|
266
|
+
context: ZuploContext,
|
|
267
|
+
): Promise<Response> {
|
|
268
|
+
const userId = context.custom.userId;
|
|
269
|
+
const plan = context.custom.plan;
|
|
270
|
+
|
|
271
|
+
context.log.info(`Handling request for user ${userId} on plan ${plan}`);
|
|
272
|
+
|
|
273
|
+
// ...build your response
|
|
274
|
+
return new Response(JSON.stringify({ userId, plan }), {
|
|
275
|
+
status: 200,
|
|
276
|
+
headers: { "content-type": "application/json" },
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
For the full `ZuploContext` reference, see
|
|
282
|
+
[ZuploContext](../programmable-api/zuplo-context.mdx).
|
|
283
|
+
|
|
284
|
+
## Accessing Environment Variables
|
|
285
|
+
|
|
286
|
+
Import `environment` from `@zuplo/runtime` to read environment variables in any
|
|
287
|
+
custom module:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { environment } from "@zuplo/runtime";
|
|
291
|
+
|
|
292
|
+
const apiKey = environment.API_KEY; // string | undefined
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Always validate required variables early to surface configuration errors at
|
|
296
|
+
startup rather than at request time:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
import { environment, ConfigurationError } from "@zuplo/runtime";
|
|
300
|
+
|
|
301
|
+
const apiKey = environment.API_KEY;
|
|
302
|
+
if (!apiKey) {
|
|
303
|
+
throw new ConfigurationError("API_KEY environment variable is not set");
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
For more information on setting and managing environment variables, see
|
|
308
|
+
[Configuring Environment Variables](./environment-variables.mdx) and the
|
|
309
|
+
[Environment Variables API](../programmable-api/environment.mdx).
|
|
310
|
+
|
|
311
|
+
## Common Patterns
|
|
312
|
+
|
|
313
|
+
### Forward User Metadata as Headers
|
|
314
|
+
|
|
315
|
+
Pass authenticated user information to your backend as headers so backend
|
|
316
|
+
services don't need to re-validate tokens:
|
|
317
|
+
|
|
318
|
+
```ts title="modules/forward-user-headers.ts"
|
|
319
|
+
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
320
|
+
|
|
321
|
+
export default async function (
|
|
322
|
+
request: ZuploRequest,
|
|
323
|
+
context: ZuploContext,
|
|
324
|
+
): Promise<ZuploRequest | Response> {
|
|
325
|
+
if (!request.user) {
|
|
326
|
+
return request;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const newRequest = new ZuploRequest(request);
|
|
330
|
+
newRequest.headers.set("x-user-id", request.user.sub);
|
|
331
|
+
|
|
332
|
+
if (request.user.data?.email) {
|
|
333
|
+
newRequest.headers.set("x-user-email", request.user.data.email);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (request.user.data?.plan) {
|
|
337
|
+
newRequest.headers.set("x-user-plan", request.user.data.plan);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return newRequest;
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Conditional Logic Based on Plan or Metadata
|
|
345
|
+
|
|
346
|
+
Route or transform requests differently based on the authenticated user's plan
|
|
347
|
+
or custom metadata:
|
|
348
|
+
|
|
349
|
+
```ts title="modules/plan-based-routing.ts"
|
|
350
|
+
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
|
|
351
|
+
|
|
352
|
+
export default async function (
|
|
353
|
+
request: ZuploRequest,
|
|
354
|
+
context: ZuploContext,
|
|
355
|
+
): Promise<ZuploRequest | Response> {
|
|
356
|
+
const plan = request.user?.data?.plan ?? "free";
|
|
357
|
+
|
|
358
|
+
if (plan === "enterprise") {
|
|
359
|
+
context.custom.backendUrl = environment.ENTERPRISE_BACKEND_URL;
|
|
360
|
+
} else {
|
|
361
|
+
context.custom.backendUrl = environment.DEFAULT_BACKEND_URL;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return request;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Custom Response Transformation
|
|
369
|
+
|
|
370
|
+
Reshape a backend response before returning it to the client:
|
|
371
|
+
|
|
372
|
+
```ts title="modules/transform-response.ts"
|
|
373
|
+
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
374
|
+
|
|
375
|
+
export default async function (
|
|
376
|
+
response: Response,
|
|
377
|
+
request: ZuploRequest,
|
|
378
|
+
context: ZuploContext,
|
|
379
|
+
): Promise<Response> {
|
|
380
|
+
if (response.status !== 200) {
|
|
381
|
+
return response;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const data = await response.json();
|
|
385
|
+
|
|
386
|
+
// Wrap the response in an envelope
|
|
387
|
+
const envelope = {
|
|
388
|
+
success: true,
|
|
389
|
+
data,
|
|
390
|
+
metadata: {
|
|
391
|
+
requestId: context.requestId,
|
|
392
|
+
timestamp: new Date().toISOString(),
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
return new Response(JSON.stringify(envelope), {
|
|
397
|
+
status: 200,
|
|
398
|
+
headers: { "content-type": "application/json" },
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## When to Use Policy vs Handler vs Hook
|
|
404
|
+
|
|
405
|
+
Zuplo provides three extension points for custom code. Choose the right one
|
|
406
|
+
based on your use case:
|
|
407
|
+
|
|
408
|
+
| Extension Point | Use When |
|
|
409
|
+
| ------------------- | ---------------------------------------------------------------------------------------------- |
|
|
410
|
+
| **Inbound Policy** | You need to inspect, validate, or modify the request before it reaches the handler. |
|
|
411
|
+
| **Outbound Policy** | You need to inspect or transform the response after the handler runs. |
|
|
412
|
+
| **Request Handler** | You need to produce the response -- call backends, aggregate data, or return custom responses. |
|
|
413
|
+
| **Hook** | You need cross-cutting logic that applies globally, such as logging or tracing. |
|
|
414
|
+
|
|
415
|
+
Policies are configured per-route and are reusable across multiple routes. Hooks
|
|
416
|
+
are registered globally in `zuplo.runtime.ts` and run on every request. For a
|
|
417
|
+
detailed explanation of how these fit together, see
|
|
418
|
+
[Request Lifecycle](../concepts/request-lifecycle.mdx).
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Custom Domains
|
|
3
|
+
sidebar_label: Overview
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This guide will walk you through the process of setting up a custom domain for
|
|
7
|
+
your project's edge deployment environment. You can manage all domain settings
|
|
8
|
+
related to a project in the **Custom Domains** section of **Settings** for your
|
|
9
|
+
project. Custom Domains are available on
|
|
10
|
+
[Builder plans and above](https://zuplo.com/pricing).
|
|
11
|
+
|
|
12
|
+
## Types of Custom Domains
|
|
13
|
+
|
|
14
|
+
Zuplo supports two types of custom domains that can be configured separately:
|
|
15
|
+
|
|
16
|
+
1. **API Gateway Custom Domain**: For your API endpoints (for example,
|
|
17
|
+
`api.example.com`). This domain uses the CNAME `cname.zuplo.app`.
|
|
18
|
+
|
|
19
|
+
2. **Developer Portal Custom Domain**: For your developer documentation site
|
|
20
|
+
(for example, `docs.example.com`). This domain uses the CNAME
|
|
21
|
+
`cname.zuplodocs.com`. Learn more about the Developer Portal in the
|
|
22
|
+
[Developer Portal documentation](/docs/dev-portal/introduction).
|
|
23
|
+
|
|
24
|
+
Both types of custom domains can be managed from the same Custom Domains section
|
|
25
|
+
in your project settings and follow a similar configuration process.
|
|
26
|
+
|
|
27
|
+
:::note
|
|
28
|
+
|
|
29
|
+
Custom domains can't be added to development environments. You can tell if an
|
|
30
|
+
environment is development if the domain ends with `zuplo.dev`.
|
|
31
|
+
|
|
32
|
+
:::
|
|
33
|
+
|
|
34
|
+
## Adding a new custom domain
|
|
35
|
+
|
|
36
|
+
The following steps will guide you on how to add and configure a custom domain
|
|
37
|
+
for your Zuplo project.
|
|
38
|
+
|
|
39
|
+
### 1. Navigate to your project's Custom Domain Settings
|
|
40
|
+
|
|
41
|
+
Go to your project in the Zuplo portal, click **Settings** (1), then select
|
|
42
|
+
**Custom Domains** (2) and click the **Add New Custom Domain** button to open
|
|
43
|
+
the `New Custom Domain` configuration modal.
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
### 2. Add your domain
|
|
48
|
+
|
|
49
|
+
Then, select the type of custom domain (API Gateway or Developer Portal), pick
|
|
50
|
+
the environment you want to assign the domain to, and enter your apex domain
|
|
51
|
+
(for example `example.com`) or subdomain (for example api.example.com or
|
|
52
|
+
docs.example.com).
|
|
53
|
+
|
|
54
|
+
<ModalScreenshot size="md">
|
|
55
|
+

|
|
56
|
+
</ModalScreenshot>
|
|
57
|
+
|
|
58
|
+
Once saved, you will be provided with a `CNAME` configuration that you'll use in
|
|
59
|
+
the next step. The CNAME value depends on the domain type:
|
|
60
|
+
|
|
61
|
+
**For API Gateway domains:**
|
|
62
|
+
|
|
63
|
+
```txt
|
|
64
|
+
CNAME api.example.com cname.zuplo.app
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**For Developer Portal domains:**
|
|
68
|
+
|
|
69
|
+
```txt
|
|
70
|
+
CNAME docs.example.com cname.zuplodocs.com
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. Configure your DNS
|
|
74
|
+
|
|
75
|
+
Once you have added your custom domain to your Zuplo project, you will need to
|
|
76
|
+
configure the DNS records of your domain with your registrar.
|
|
77
|
+
|
|
78
|
+
Using the CNAME configuration provided at the end of the previous step, you will
|
|
79
|
+
create that record on your DNS registrar. Cloudflare will then query your domain
|
|
80
|
+
[periodically](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/start/hostname-verification-backoff-schedule/)
|
|
81
|
+
until it can verify everything. If everything is configured correctly, it should
|
|
82
|
+
take a few minutes for your production API to start responding to traffic on
|
|
83
|
+
your custom domain. On the other hand, if a misconfiguration (typo) occurs and
|
|
84
|
+
you need to make changes, Cloudflare could take up to 4 hours to retry the
|
|
85
|
+
verification. Please be patient if this happens.
|
|
86
|
+
|
|
87
|
+
By default, you can also use the url on `zuploapp.com` although, if you prefer
|
|
88
|
+
that to be removed contact support and we can disable it for you.
|
|
89
|
+
|
|
90
|
+
:::caution
|
|
91
|
+
|
|
92
|
+
If you use Cloudflare as your DNS provider, you MUST enable Cloudflare Proxy on
|
|
93
|
+
your custom domain.
|
|
94
|
+
|
|
95
|
+

|
|
96
|
+
|
|
97
|
+
:::
|
|
98
|
+
|
|
99
|
+
### 4. Redeploy
|
|
100
|
+
|
|
101
|
+
Some changes, like the domain set in your developer portal, only get picked up
|
|
102
|
+
on the deployment. After you set a custom domain it's a good idea to redeploy
|
|
103
|
+
your environment to ensure everything is applied correctly.
|
|
104
|
+
|
|
105
|
+
## Cloudflare Customers
|
|
106
|
+
|
|
107
|
+
Zuplo uses Cloudflare for routing custom domain traffic to our servers. If you
|
|
108
|
+
use Cloudflare on your domain, there are a few limitations to be aware of. In
|
|
109
|
+
general, these shouldn't be a problem as we handle all the complexities for you.
|
|
110
|
+
|
|
111
|
+
For host names managed by Zuplo, you can't control some Cloudflare settings for
|
|
112
|
+
your Zuplo subdomain (for example `api.example.com`). Examples include:
|
|
113
|
+
|
|
114
|
+
- Wildcard DNS
|
|
115
|
+
- Spectrum
|
|
116
|
+
- Argo
|
|
117
|
+
- Page Shield
|
|
118
|
+
|
|
119
|
+
See
|
|
120
|
+
[Cloudflare's documentation](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/#limitations)
|
|
121
|
+
for more details.
|
|
122
|
+
|
|
123
|
+
Other Cloudflare features that are configured on your Cloudflare Account such as
|
|
124
|
+
Firewall or WAF rules will function normally.
|
|
125
|
+
|
|
126
|
+
At this time, to use a wildcard domain or other complex custom domain for your
|
|
127
|
+
environment you will need to contact
|
|
128
|
+
[support@zuplo.com](mailto:support@zuplo.com).
|
|
129
|
+
|
|
130
|
+
## CAA Records
|
|
131
|
+
|
|
132
|
+
:::info
|
|
133
|
+
|
|
134
|
+
In most cases this isn't required. You only need to modify CAA records if you
|
|
135
|
+
already have them set on your DNS.
|
|
136
|
+
|
|
137
|
+
:::
|
|
138
|
+
|
|
139
|
+
If you have a CAA DNS record set on your domain, you must add either Google
|
|
140
|
+
Trust Services or Let's Encrypt as an authorized certificate authority.
|
|
141
|
+
|
|
142
|
+
You don't need to add both of these, just add one. The Google Trust Services
|
|
143
|
+
(pki.goog) is the recommended Authority as it has slightly better compatibility
|
|
144
|
+
with clients. Zuplo will use Google Trust Services by default unless only the
|
|
145
|
+
Let's Encrypt record is set.
|
|
146
|
+
|
|
147
|
+
```txt
|
|
148
|
+
CAA 0 issue "pki.goog"
|
|
149
|
+
CAA 0 issue "letsencrypt.org"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Managed SSL Certificates
|
|
153
|
+
|
|
154
|
+
By default Zuplo will automatically manage SSL certificates for your custom
|
|
155
|
+
domain. If you prefer to manage your own SSL certificates, please contact
|
|
156
|
+
[support@zuplo.com](mailto:support@zuplo.com).
|
|
157
|
+
|
|
158
|
+
Certificates are issued by either Google Trust Services or Let's Encrypt. If you
|
|
159
|
+
have a preference, please let us know, but we recommend (and default to) Google
|
|
160
|
+
Trust Services as it has slightly better compatibility with clients.
|
|
161
|
+
|
|
162
|
+
Certificates are issued for 90 days and are automatically renewed approximately
|
|
163
|
+
30 days before they expire. No action is required on your part.
|
|
164
|
+
|
|
165
|
+
:::warning{title="Certificate Pinning"}
|
|
166
|
+
|
|
167
|
+
Certificate pinning isn't recommended for Zuplo APIs as the certificates are
|
|
168
|
+
issued for short periods of time and renewed automatically. If you or your end
|
|
169
|
+
clients require certificate pinning, it's recommended you use a custom,
|
|
170
|
+
long-lived SSL certificate. (Although this is
|
|
171
|
+
[not recommended](https://scotthelme.co.uk/why-we-need-to-do-more-to-reduce-certificate-lifetimes/)
|
|
172
|
+
for most use cases.)
|
|
173
|
+
|
|
174
|
+
:::
|
|
175
|
+
|
|
176
|
+
For alternatives to certificate pinning, consider using
|
|
177
|
+
[HSTS headers](https://https.cio.gov/hsts/) or adding CAA records to your DNS.
|
|
178
|
+
The CAA records required for Zuplo are shown below (depending on what authority
|
|
179
|
+
your domain is configured to use)
|
|
180
|
+
|
|
181
|
+
```txt
|
|
182
|
+
# CAA records added by Let's Encrypt
|
|
183
|
+
0 issue "letsencrypt.org"
|
|
184
|
+
0 issuewild "letsencrypt.org"
|
|
185
|
+
|
|
186
|
+
# CAA records added by Google Trust Services
|
|
187
|
+
0 issue "pki.goog; cansignhttpexchanges=yes"
|
|
188
|
+
0 issuewild "pki.goog; cansignhttpexchanges=yes"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## TLS Versions
|
|
192
|
+
|
|
193
|
+
Zuplo supports issuing certificates with TLS versions 1.0, 1.1, 1.2 and 1.3. By
|
|
194
|
+
default certificates are issued with versions 1.2 and 1.3 enabled. If you
|
|
195
|
+
require a specific version, please contact
|
|
196
|
+
[support@zuplo.com](mailto:support@zuplo.com).
|
|
197
|
+
|
|
198
|
+
:::note{title="Legacy TLS Versions"}
|
|
199
|
+
|
|
200
|
+
Early Zuplo customers may have certificates issued with TLS 1.0 and greater
|
|
201
|
+
enabled. If you wish to upgrade to a higher TLS version, please contact
|
|
202
|
+
[support@zuplo.com](mailto:support@zuplo.com).
|
|
203
|
+
|
|
204
|
+
:::
|
|
205
|
+
|
|
206
|
+
## Alias Domains
|
|
207
|
+
|
|
208
|
+
<EnterpriseFeature name="Alias Domains" />
|
|
209
|
+
|
|
210
|
+
Sometimes your API Gateway might be running behind another service such as a
|
|
211
|
+
CDN, WAF or load balancer. In this case, your API Gateway's domain may not be
|
|
212
|
+
the same as the domain your clients use to access your API. In this case, you
|
|
213
|
+
can add an alias domain to your Zuplo project. An alias domain will configure
|
|
214
|
+
your API and documentation to use the alias domain for any public facing URLs
|
|
215
|
+
such as those in your OpenAPI files or developer portal.
|
|
216
|
+
|
|
217
|
+
To add an alias domain, simply add a new custom domain per the instructions
|
|
218
|
+
above, but select **Alias Domain** option when creating the domain.
|
|
219
|
+
|
|
220
|
+
Do note that domains can't be "converted" from a custom domain to an alias
|
|
221
|
+
domain or vice versa. If you need to change a domain from one type to another,
|
|
222
|
+
you will need to delete the existing domain and create a new one with the
|
|
223
|
+
desired type.
|
|
224
|
+
|
|
225
|
+
## Validation Error
|
|
226
|
+
|
|
227
|
+
If you receive a notification or email that your domain has a validation error
|
|
228
|
+
the likely causes of the issue listed below. If you are unable to resolve the
|
|
229
|
+
issue or have any questions, please contact
|
|
230
|
+
[support@zuplo.com](mailto:support@zuplo.com).
|
|
231
|
+
|
|
232
|
+
### No DNS Record or Invalid Record
|
|
233
|
+
|
|
234
|
+
Your DNS isn't configured correctly. Ensure that your domain is configured with
|
|
235
|
+
a `CNAME` record pointing to the correct target based on your domain type:
|
|
236
|
+
|
|
237
|
+
**For API Gateway domains:**
|
|
238
|
+
|
|
239
|
+
```txt
|
|
240
|
+
CNAME api.example.com cname.zuplo.app
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**For Developer Portal domains:**
|
|
244
|
+
|
|
245
|
+
```txt
|
|
246
|
+
CNAME docs.example.com cname.zuplodocs.com
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### CAA Record Error
|
|
250
|
+
|
|
251
|
+
Your DNS has been configured with CAA records that don't authorize Google Trust
|
|
252
|
+
Services to issue certificates for your domain. To resolve add the following DNS
|
|
253
|
+
records:
|
|
254
|
+
|
|
255
|
+
```txt
|
|
256
|
+
0 issue "pki.goog; cansignhttpexchanges=yes"
|
|
257
|
+
0 issuewild "pki.goog; cansignhttpexchanges=yes"
|
|
258
|
+
```
|