Settings and configuration

The settings page holds per-user choices; the installation is configured with environment variables.

On this page

The settings page

The settings page: the appearance choice (System, Light, Dark) and how to connect clients.

Settings has your theme and how clients connect. Per-server settings live on the server: logging call payloads is on the Calls tab.

Environment variables

VariableDefaultDescription
KERVAN_STUDIO_PUBLIC_URLhttp://127.0.0.1:<port>The URL people use, e.g. https://studio.example.com. Required when not on loopback. Origin checks, cookies, the accepted Host header and the SSRF deny list derive from it.
KERVAN_STUDIO_HOST127.0.0.1Interface to listen on once an admin exists.
KERVAN_STUDIO_PORT4310
KERVAN_STUDIO_DATA_DIR./.kervan-studioHolds studio.db.
KERVAN_STUDIO_TRUST_PROXY0Number of reverse proxies that append to X-Forwarded-For. Only set it when Studio is reachable through the proxy alone (see below).
KERVAN_STUDIO_DENY_NETWORKComma-separated addresses or CIDR ranges spec tools may never reach (your internal services).
KERVAN_STUDIO_MASTER_KEY(required)[version:]base64 of 32 random bytes; encrypts stored secrets.
KERVAN_STUDIO_PREVIOUS_MASTER_KEYSversion:base64,...: older keys while rotating. Studio re-encrypts with the current key on start.
KERVAN_STUDIO_LOG_RETENTION_DAYS30How long call logs are kept.

There is deliberately no setting that lets spec tools reach private or loopback addresses.

Behind a reverse proxy

Terminate TLS at the proxy, and make Studio reachable only through it: bind Studio to 127.0.0.1 or a private interface. Then:

  • set KERVAN_STUDIO_PUBLIC_URL to the public https:// origin;
  • set KERVAN_STUDIO_TRUST_PROXY to the number of proxies in front of Studio (usually 1);
  • keep the original Host header (proxy_set_header Host $host; in nginx) and append to X-Forwarded-For (proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;).

Studio takes the client IP from the entry its outermost trusted proxy wrote. Anything a client writes into X-Forwarded-For itself is ignored.

Example: Caddy

Caddy gets and renews the TLS certificate itself. Its reverse_proxy keeps the Host header, sets X-Forwarded-For to the client’s address (it does not trust what clients send unless you configure trusted_proxies), and streams text/event-stream responses without buffering, so no flush_interval setting is needed. (Tested with Caddy 2.11 and tls internal: through the proxy, a client’s subscriptions/listen stream received list_changed about 30 ms after a publish, also after 65 seconds idle.)

caddyfile
studio.example.com {
	reverse_proxy 127.0.0.1:4310
}
sh
KERVAN_STUDIO_PUBLIC_URL=https://studio.example.com \
KERVAN_STUDIO_TRUST_PROXY=1 \
KERVAN_STUDIO_HOST=127.0.0.1 \
node --env-file=.env.studio apps/studio/bin/kervan-studio.js start

With Studio on 127.0.0.1, only processes on the same machine (Caddy) reach it. The browser must use exactly https://studio.example.com: the management API and the gateway compare the whole origin (scheme, host and port).

Until the first admin exists Studio listens on 127.0.0.1 only, and Caddy on the same machine forwards to it. Create the first admin soon after the first start: the setup token, printed on Studio’s console, is what protects a fresh install.

Warning: with KERVAN_STUDIO_TRUST_PROXY set, Studio must not be reachable except through the proxy. Firewall its port. A client that connects directly can put any address in X-Forwarded-For, which defeats per-IP rate limits and falsifies audit records.