Secure Tunnel

Connect to Tunnel Services

Enterprise Feature

Secure tunneling is available as an add-on as part of an enterprise plan. If you would like to purchase this feature, please contact us at sales@zuplo.com or reach out to your account manager.

Most enterprise features can be used in a trial mode for a limited time. Feel free to use enterprise features for development and testing purposes.

Once a tunnel exposes a service, your gateway calls it like any other backend — with a URL. Tunnel services use the service:// scheme instead of a hostname, so a service named payments-api is reachable at service://payments-api.

This page covers the service configuration file, and the three places you use a service:// URL: handler code, route configuration, and environment variables. To create a tunnel first, see Set up a tunnel.

Service configuration reference

You define services in a JSON file and upload it with zuplo tunnel services update. Each upload replaces the tunnel's entire configuration.

JSONtunnel-config.json
{ "version": 1, "services": [ { "name": "payments-api-prod", "endpoint": "http://payments.internal:8080", "configurations": [ { "project": "my-project", "accessibleBy": ["production"] }, { "project": "my-other-project", "accessibleBy": ["production"] } ] }, { "name": "payments-api-staging", "endpoint": "http://payments-staging.internal:8080", "configurations": [ { "project": "my-project", "accessibleBy": ["preview", "working-copy"] } ] } ] }
PropertyTypeDescription
versionnumberConfiguration format version. Use 1.
servicesarrayThe services this tunnel exposes.
services[].namestringThe service name your gateway calls, used as service://<name>.
services[].endpointstringThe internal URL the tunnel forwards to, resolvable from the tunnel host. For example, http://payments.internal:8080.
services[].configurationsarrayWhich projects and environments can call this service. A project that isn't listed can't reach the service.
configurations[].projectstringThe name of the Zuplo project.
configurations[].accessibleBystring[]The environments allowed to call the service. Valid values are production, preview, and working-copy.

Use accessibleBy to keep environments apart. A service listed only under production can't be reached from a preview build, even by a developer on your own team.

To see the configuration a tunnel currently has, run zuplo tunnel services describe.

Call a service from code

Pass the service:// URL to fetch exactly as you would a public URL:

TypeScriptCode
import { ZuploContext, ZuploRequest } from "@zuplo/runtime"; export default async function (request: ZuploRequest, context: ZuploContext) { const response = await fetch("service://payments-api-prod/v1/charges"); if (!response.ok) { context.log.error(`Payments API returned ${response.status}`); return new Response("Upstream error", { status: 502 }); } return response; }

Paths, query strings, headers, and request methods all work the way they do for a normal fetch. The tunnel appends the path to the service's configured endpoint.

Call a service from route configuration

Any route property that accepts a URL accepts a service:// URL, including the URL Rewrite handler:

JSONconfig/routes.oas.json
{ "paths": { "/v1/charges": { "get": { "x-zuplo-route": { "handler": { "export": "urlRewriteHandler", "module": "$import(@zuplo/runtime)", "options": { "rewritePattern": "service://payments-api-prod/v1/charges" } } } } } } }

You can also set the rewrite URL in the Rewrite URL field of the route editor in the Zuplo Portal.

Switch services per environment

Most teams run a separate internal service for each environment. Rather than changing code or route configuration per environment, store the service URL in an environment variable and set a different value in each Zuplo environment.

In your production environment, point the variable at the production service:

Code
TUNNEL_BASE_URL=service://payments-api-prod

In preview and working-copy environments, point it at staging:

Code
TUNNEL_BASE_URL=service://payments-api-staging

Read the variable in handler code:

TypeScriptCode
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime"; export default async function (request: ZuploRequest, context: ZuploContext) { return fetch(`${environment.TUNNEL_BASE_URL}/v1/charges`); }

Environment variables work in route configuration too. The following URL Rewrite handler combines the variable with a path parameter:

The Request Handler pane of the Zuplo route editor, with Handler set to URL Rewrite and Rewrite URL set to a value that combines the TUNNEL_BASE_URL environment variable with a path parameter

Next steps

Last modified on