Settings and configuration
The settings page holds per-user choices; the installation is configured with environment variables.
On this page
The settings page

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
| Variable | Default | Description |
|---|---|---|
KERVAN_STUDIO_PUBLIC_URL | http://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_HOST | 127.0.0.1 | Interface to listen on once an admin exists. |
KERVAN_STUDIO_PORT | 4310 | |
KERVAN_STUDIO_DATA_DIR | ./.kervan-studio | Holds studio.db. |
KERVAN_STUDIO_TRUST_PROXY | 0 | Number 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_NETWORK | Comma-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_KEYS | version:base64,...: older keys while rotating. Studio re-encrypts with the current key on start. | |
KERVAN_STUDIO_LOG_RETENTION_DAYS | 30 | How 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_URLto the publichttps://origin; - set
KERVAN_STUDIO_TRUST_PROXYto the number of proxies in front of Studio (usually1); - keep the original
Hostheader (proxy_set_header Host $host;in nginx) and append toX-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.)
studio.example.com {
reverse_proxy 127.0.0.1:4310
}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 startWith 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_PROXYset, Studio must not be reachable except through the proxy. Firewall its port. A client that connects directly can put any address inX-Forwarded-For, which defeats per-IP rate limits and falsifies audit records.