zanith

studio / launch

Local by default.
Shared on purpose.

Three deployment shapes, each a flag away — and the unsafe ones are opt-in, never the default. Localhost bind, bearer tokens, read-only, audited.

launching zanith studio — viewer mode
dev

you, on localhost

everything

staff

the team, shared

writes, confirm-gated

viewer

anyone with the link

reads only

localhost by default·bearer tokens·read-only mode·append-only audit

02 — Mode boundaries

What each role can do.

Reads are universal. Writes are gated by mode. Staff can mutate but every write triggers a typed confirm. Viewers cannot mutate at all.

Capabilitydevstaffviewer
Browse rowsyesyesyes
Run SELECT in SQLyesyesyes
Edit / insert / delete rowsyeswith confirmno
Run DDL (alter / drop)yeswith confirmno
Apply migrationsyeswith confirmno
Restore artifactsyeswith confirmno
Manage connectionsyesyesno
studio.ndjson — append-onlywriting
PATCHadmin@opsusers/a4c8…200

{ active: false → true }

DELETEadmin@opssessions/91f2…200

{ revoked: true }

POSTmei@engorgs201

{ +1 row }

PATCHbob@supusers/c702…403

read-only · refused

UPDATEadmin@opsusers (×3)200

{ role → viewer }

Audit

Every write,
on the record.

Every mutation, captured. Actor, IP, method, path, result, and the row-level diff — one line per write.

NDJSON on disk. Append-only, one JSON object per line. Tail it, grep it, ship it to your SIEM.

Refusals logged too. A read-only viewer's blocked PATCH lands in the log as a 403 — not silently dropped.

04 — Hardening

Conservative defaults. Explicit unlocks.

Every dangerous capability is off until you turn it on with a flag. The safe path is the path of least resistance.

Bind to 127.0.0.1

Studio binds to localhost by default. Use --host only when you mean it.

Bearer tokens

Admin or read-only token required for any non-localhost bind. No token, no service.

Read-only mode

GETs plus probe / explain / refresh only. Nothing that mutates.

Append-only audit

NDJSON to disk. Every write request captured with actor, IP, and diff.

Prod-confirm dialogs

Tag a connection 'prod' and every mutation needs a typed confirmation.

No persistent sessions

Tokens are checked per request. Rotate freely — there's no logout flow to manage.