Expose a Web UI
Every service with a browser interface needs at least one HTTP interface. This is the most basic networking pattern — bind a port, create an interface descriptor, and export it.
Solution
In setupInterfaces(), create a MultiHost with sdk.MultiHost.of(effects, 'ui'), bind an HTTP port with multi.bindPort(port, { protocol: 'http', preferredExternalPort: 80 }), create a 'ui' type interface with sdk.createInterface() setting masked: false, and export it. Return the receipt array.
Reference: Interfaces
Authentication
StartOS does not authenticate a bound port. Binding an interface exposes it; nothing gates it unless you say so. There are exactly two ways to gate it, and they are not interchangeable.
Prefer the app’s own login. When upstream ships one, feed it the credential it expects — an env var (SALTED_PASS, QBT_PW_HASH) or its config file — and persist only the hash. Follow Prompt User to Create Admin Credentials: the action is the sole writer of the credential, it returns the value rather than storing it in cleartext, and the user rotates it by re-running the action. Reference implementations: qbittorrent (QBT_PW_HASH) and changedetection (SALTED_PASS).
Fall back to the OS gate only when the app has no auth of its own. addSsl.auth makes the OS reverse proxy challenge every request to that binding’s port, so REST endpoints, RSS feeds, and webhooks are gated along with the browser UI, and any client that can’t send an Authorization header is locked out. Reference implementation: searxng.
Warning
Do not derive an app-native login from
searxng-startos. It is the OS-gate reference only. It stores the password in cleartext because the reverse proxy needs the cleartext to configure basic auth, and it takes the credentialwithInputbecause the user is choosing public-vs-private. Neither property transfers to an app-native login — copying them puts a plaintext password at rest. Searching foraddSsl.authlands you in searxng first; that answers “how does StartOS gate a port,” not “how do I wire up the app’s own login.”
Examples
See startos/interfaces.ts in: hello-world, actual-budget, filebrowser, uptime-kuma, spliit