zanith

studio / launch · 01 — Three shapes

One binary. Three boundaries.

Studio runs against any connection your engine has. Bind it to localhost for solo work, hand a teammate the read-only token, or open it on a VPN for the team. Same command, different flags.

devno auth · 127.0.0.1

Local dev

$ zanith studio --allow-sql
staffadmin token · full access

Shared staff

$ zanith studio --auth-token "$ADMIN"
viewerviewer token · safe GETs

Read-only

$ zanith studio --read-only-auth-token "$RO"
3 modessame binarytoken-gated mutationsappend-only audit logv0.2 · shipped

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

03 — Audit

Every mutation, written down.

Pass --audit-log and every write request appends a JSON line to disk. Default location lives under the workspace data dir; pass a path to put it where your log shipper can read.

~/.zanith/audit.ndjsonappend-only
ts2026-05-01T11:30:22.184Z
actorops · admin@…
ip10.0.5.4
methodPATCH
path/api/models/users/rows/a4c8…
result200
row_diff{ "active": false → true }

Combined with the engine's _zanith_migration_steps audit table, this gives you both the row-level change and the request that caused it.

04 — Hardening

Conservative defaults. Explicit unlocks.

Bind to 127.0.0.1

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

Bearer tokens

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

Read-only mode

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

Append-only audit

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

Prod-confirm dialogs

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

No persistent sessions

Tokens are checked per request. Refresh on rotate, no logout flow needed.