Skip to main content

Configure app hostnames

By default, a self-hosted Retool instance serves each published app in a sandboxed iframe. Since this iframe lacks an origin, browsers actively enforce strict security boundaries that block access to localStorage, IndexedDB, cookies, the camera, and the microphone. Many third-party scripts cannot load, and an identity-aware proxy behind which Retool operates can drop its cookie on the app's requests.

If you need access to these features, you can configure your self-hosted instance to serve apps using their own hostnames instead. This enables an app to run as a normal web page instead of an iframe, allowing access to those browser features.

After you configure app hostnames, each app gets its own hostname under an apps domain that's either a subdomain, such as apps.retool.example.com, or a separate domain entirely, such as example-apps.com. For example, with the apps domain apps.retool.example.com:

Before
https://retool.example.com/rr/app/claims
After
https://claims.apps.retool.example.com/

Before you begin​

Use this checklist as you prepare to configure app hostnames to ensure you have everything ready.

Note

This guide requires Retool Helm chart 6.13.2 or later.

Process overview​

Configuring app hostnames involves changes to the Retool instance and to each space hosted on it, including the Admin Space and every other space.

  • Once for the instance: You update the Helm configuration, and add DNS records and a certificate.
  • For each space: You turn on app hostnames in the space's settings, and choose which browser features the space supports in the app builder preview.

The configuration happens in two stages, each with its own helm upgrade. This lets you confirm that apps are served correctly from their hostnames before you change the app builder preview.

  1. First upgrade: You set up the apps domain, the domain that apps are served from, such as apps.retool.example.com. Published apps then move to their own hostnames one space at a time. They stay in the sandboxed iframe until you turn on app hostnames in the space's settings.
  2. Second upgrade: After you verify the apps domain, you move the app builder preview to its own origin. This applies to every space at once. Choose the browser features each space supports before this upgrade.

Choose the apps domain​

Apps are served from an apps domain. Retool recommends using a subdomain of your Retool instance. You can also use a separate domain, such as when your security policy requires the browser to separate the Retool instance from the apps your users build.

Instance subdomainSeparate domain
Exampleapps.retool.example.comexample-apps.com
Separation between Retool and appsRetool enforces it with host checks, __Host- cookies, and Sec-Fetch-Site checksThe browser enforces it, because the apps are on a different site
SetupOne more wildcard DNS record and certificate under your existing domainA second domain with its own DNS zone and certificates
Note

This guide uses retool.example.com as a placeholder Retool instance and apps as the chosen instance subdomain. For a separate domain, it uses example-apps.com. Replace these values with your own during configuration. The tabs in this guide show the steps for each option, and your selection applies to every tab on the page.

The instance subdomain can't match, be under, or be above the domain of any space. For example, with apps at apps.retool.example.com, a space whose domain is finance.apps.retool.example.com or example.com is rejected, but a space whose domain is finance.example.com is accepted.

Only names under the instance subdomain are served, so apps.retool.example.com itself needs no DNS record or certificate.

The app builder preview is served from a sandboxes subdomain of the instance subdomain, such as sandboxes.apps.retool.example.com. Each preview gets its own hostname under it, such as sandbox-<id>.sandboxes.apps.retool.example.com.

Configure DNS records​

App and app builder preview hostnames must resolve to the load balancer used by the Retool instance. This is usually the load balancer in front of your Kubernetes ingress controller.

If you already have a wildcard record for your Retool instance, such as *.retool.example.com, it may already cover these hostnames. A wildcard record is typically configured when spaces are enabled. You can check whether a wildcard DNS record covers them by running dig with an example fully qualified domain name (FQDN):

Check DNS
dig +short test.apps.retool.example.com
dig +short test.sandboxes.apps.retool.example.com

If dig returns your load balancer's address for both names, no change is needed. If either command returns no value or a different address, add a record for each name that failed: *.apps.retool.example.com or *.sandboxes.apps.retool.example.com.

note

An existing wildcard stops covering these names once any record exists at or under apps.retool.example.com. Certificate validation records are the usual cause. For example, AWS Certificate Manager validates *.apps.retool.example.com with a permanent CNAME at _<hash>.apps.retool.example.com. Run the dig checks again after you issue the certificate.

Add a wildcard certificate​

Unlike a DNS wildcard record, a certificate wildcard matches one label only.

For example, a *.retool.example.com certificate would not cover *.apps.retool.example.com. You must add a wildcard certificate for the instance subdomain, such as *.apps.retool.example.com, and one for the app builder preview, *.sandboxes.apps.retool.example.com. A single certificate can include both names.

If you use cert-manager, you must use an issuer that solves DNS-01 challenges, as HTTP-01 challenges cannot issue wildcard certificates. Annotate the Ingress in the next section. Otherwise, create the certificate yourself and store it in a TLS secret.

Update Helm configuration​

The next step is to update your instance's configuration so it can support app hostnames. Add the following to your Helm values. Keep the values for the app builder preview commented out so that only published app hostnames are applied first. Once you verify that published apps are being served correctly, you can then move the app builder preview.

values.yaml
rr:
appServingLayer:
enabled: true
domain: apps.retool.example.com
separate:
enabled: false # Set to true to run the app serving layer as its own deployment.
ingress:
enabled: true
ingressClassName: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-dns # If you use cert-manager.
# The app builder keeps WebSocket connections open to the sandbox.
# nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
# nginx.ingress.kubernetes.io/proxy-send-timeout: '3600'
tls:
- secretName: retool-apps-tls
hosts:
- '*.apps.retool.example.com'
- '*.sandboxes.apps.retool.example.com' # For the app builder preview.
# agentSandbox:
# wildcardSandboxes: true

These values configure your Retool instance to:

  • Set RR_APP_DOMAIN on the Retool backend.
  • Run the app serving layer inside the existing backend pods on port 3010, behind a service named <release>-app-serving-layer.
  • Create an ingress that routes all hostnames under the apps domain to the app serving layer only.

If you want to keep the app serving layer separate from the main backend pods, set rr.appServingLayer.separate.enabled to true. Pod settings such as replicaCount, resources, and affinity go under separate.

Don't add the apps domain to the top-level ingress.hosts as this ingress adds other Retool paths to every host it serves.

Once you update the configuration, run helm upgrade to apply the changes. Apps stay in the sandboxed iframe and the app builder preview is unchanged until you make the rest of the changes.

Allow network access​

If Retool sits behind a VPN, an IP allowlist, or an identity-aware proxy such as Google IAP or Cloudflare Access, you must also apply the same protection to *.apps.retool.example.com, or to *.example-apps.com if you use a separate domain. This is necessary to prevent external access to your apps.

When a user signs in from an app, they are redirected from the app's hostname to the Retool instance, after which they're returned to the app's hostname. An identity-aware proxy must allow that round trip and accept wildcard hostnames.

Verify the setup​

To check DNS, the certificate, and routing in one request, run the following command. Any name works in place of test. If you use a separate domain, use test.example-apps.com.

Check the apps domain
curl https://test.apps.retool.example.com/api/checkHealth

A response of {"message":"serving layer is healthy"} with a valid certificate confirms that the changes were successfully applied.

Enable app hostnames for a space​

Once you've verified that apps are served from their hostnames correctly, you are ready to enable app hostnames for a space. Navigate to Settings > Beta and turn on Enable app hostnames.

The setting only applies to the current space and has no effect unless the instance has an apps domain configured. Repeat this in each space whose apps you want to serve from their hostnames, including the Admin Space. You can do this in any order, so you can verify the changes using one space first.

User-facing changes​

After you enable app hostnames for a space, the following changes take effect:

  • Existing apps work at their own hostnames without being republished.
  • Old links such as https://retool.example.com/rr/app/claims/page2?x=1 redirect to https://claims.apps.retool.example.com/page2?x=1, keeping the path and any URL parameters.
  • Shareable preview links are served from a hostname under the apps domain, such as a1b2c3d4e5f6.apps.retool.example.com. Older preview links continue to work.
  • The View button, share links, and preview links in the app builder show the hostname URLs.
  • Users only need to sign in to Retool to open apps in a space to which they have access. Each app's hostname keeps its own session which Retool automatically creates. On the first visit, the browser initially redirects the user through Retool and then returns with no sign-in prompt. Users who aren't signed in to Retool arrive at the sign-in page, as expected.

Move the app builder preview​

After you verify the apps domain and enable app hostnames for at least one space, you then move the app builder preview to its own origin. This preview then runs at sandbox-<id>.sandboxes.apps.retool.example.com for every space at once. There's no per-space configuration.

If you use a separate domain, replace sandboxes.apps.retool.example.com with sandboxes.example-apps.com in this section. The app builder preview then runs on a different site from the app builder, so its sandbox cookie is a third-party cookie that Retool sets as a partitioned cookie (Partitioned).

Before you continue:

  • Confirm that each space's domain matches rr.agentSandbox.proxy.backendDomainSuffixes. A space's app builder preview calls the space's own domain, and this setting lists the hosts the sandbox proxy treats as Retool. If your space domains sit under your Retool host, one suffix covers all of them.
  • If Retool sits behind a VPN, an IP allowlist, or a firewall, allow traffic to *.sandboxes.apps.retool.example.com.

Choose browser features​

The iframe allows some browser features by default, such as clipboard-write and geolocation. After the app builder preview moves to its own origin, the browser blocks these and other permission-gated features unless the space explicitly allows them. Enable the features your apps use so that nothing stops working when the preview moves.

To specify which browser features to support in the app builder:

  1. Navigate to Settings > Beta and enable Permissions Policy settings.
  2. Navigate to Settings > App security > Permissions Policy.
  3. Enable each feature you want to support.
  4. Repeat these steps in every space, including the Admin Space.

These settings only apply to the app builder preview, and only once the preview moves to its own origin. Until then, the permissions already allowed by the iframe remain in place. After that, when a user grants a browser permission such as camera access in the app builder, every app in that space can use it without asking again. Published apps aren't affected by these settings. They run as separate web pages, so the browser asks for permission for each one independently.

Enable the preview in Helm​

In your Helm values, uncomment the preview values that were added earlier.

values.yaml
rr:
appServingLayer:
ingress:
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
nginx.ingress.kubernetes.io/proxy-send-timeout: '3600'
agentSandbox:
wildcardSandboxes: true

These values configure your Retool instance to:

  • Serve the app builder preview from sandboxes.apps.retool.example.com, behind a service named <release>-agent-sandbox-proxy on port 3019.
  • Route *.sandboxes.apps.retool.example.com to the sandbox proxy through the same ingress as the apps domain.
  • Keep the WebSocket connections that the app builder holds open to the sandbox from timing out.

If rr.agentSandbox.networkPolicy.enabled is on, allow the ingress controller to reach the sandbox proxy:

values.yaml
rr:
agentSandbox:
networkPolicy:
extraIngressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx

Run helm upgrade to apply the changes. The preview then moves to its own origin for every space. Sandboxes that are already running keep their old address until they shut down, and the next sandbox for that branch starts at an address under sandboxes.apps.retool.example.com.

Verify the preview​

To check DNS, the certificate, and routing for the preview domain in one request, run the following command. Any name works in place of test.

Check the preview domain
curl https://test.sandboxes.apps.retool.example.com/livez

The command returns {"status":"ok"} with a valid certificate.

Manage spaces​

Apps in a space are served at <hostname ID>--<app>.<apps domain>. For example:

finance--claims.apps.retool.example.com

Each space has a hostname ID that appears in every app URL in the space:

  • When you create a space in Settings > Spaces, a Hostname ID field appears once the instance serves apps on hostnames. Leave it blank to use the first label of the space's domain. For example, finance.example.com gives finance. If that ID is taken, the space gets finance2, and so on.
  • Existing spaces get an ID automatically the first time the instance starts with an apps domain. The ID is derived the same way, and the oldest space keeps the plain name when two would clash.
  • An ID is 1 to 40 lowercase letters, digits, and single hyphens. apps, sandboxes, and retool-probe are reserved.
  • You can't change an ID after it's set, because it's part of every app URL in the space.

A hostname label is at most 63 characters, so <hostname ID>--<app> must fit. When a space gets its ID, Retool shortens any published app name that no longer fits. In the Admin Space, Retool renames apps that use a reserved name, such as apps to apps2.

  • Old links with the old name, such as https://finance.example.com/rr/app/<old name>, keep working and redirect to the app's hostname.
  • An app created later can't take another app's old name.
  • If the app is connected to Source Control, sync keeps working with the old name in package.json.