Crescendo Lab Docs
English
Sign up

Addresses and access

Every app has a public address, a preview address per version and an internal address. You can leave it public or protect it with a password.

Last updated

The three addresses#

An address is made of the address label and your organization's name. All of them use HTTPS.

AddressWho can open itExample
Public addressAnyone; a password if the app is privatehttps://order-api--acme.hosting.agentlab.run
Version preview addressAnyone with the address; a password if the app is privateOne per version, shown next to it
Internal addressOnly your organization's apps; a browser can't open ithttps://order-api--acme.internal-hosting.agentlab.run

Address labels#

You choose the address label when you create the app. It uses lowercase letters, numbers and hyphens. Once used, a label stays with your organization, and nobody else gets it even after the app is permanently deleted.

Public or private#

Choose the app's access in its Settings:

OptionEffect
PublicAnyone with the address can view it.
PrivateEvery address of the app (the public address and each version's preview address) shows a password page first.

The console generates the password and shows it once. If it's lost, generate a new one.

Private apps are served without the CDN

That's fine for a handful of reviewers, but not for heavy traffic.

Calling another app#

Apps in the same organization call each other at their internal addresses:

  • Only your organization's apps can call it, from inside the platform. Other organizations, builds and the internet can't.
  • The certificate is publicly trusted, so a default HTTP client works.
  • A call reaches the live version.
  • The internal address has no password page. Protect sensitive endpoints in your code.

A request that arrives on the internal address carries an X-Franky-Caller-App header with the address label of the app that sent it. Trust it only when Host is the internal domain:

server.js
const internal = req.headers.host?.endsWith(".internal-hosting.agentlab.run");
const caller = internal ? req.headers["x-franky-caller-app"] : undefined;

if (req.url.startsWith("/admin") && caller !== "billing-worker") {
  res.writeHead(403).end();
  return;
}