Skip to main content
Studio is the local web UI that boots when you run arkor dev. It lives on your machine, talks to the same CLI process over loopback, and goes away when you stop the dev server. There is no separate signup, no public URL. Open it at http://localhost:4000 (configurable with arkor dev --port).

Layout

The header shows the current identity in the form <mode> · <org>[ / <project>][ · <baseUrl-host>], where mode is anonymous or auth0. The cloud-api host suffix is hidden when the CLI is pointing at the production endpoint and shown otherwise. Three pages, switched via the in-app nav:

Architecture

Three checks run on every /api/* request:
  1. Host header guard. Only 127.0.0.1 and localhost are accepted for every request, including static HTML. A victim navigated to a malicious site that DNS-rebinds onto 127.0.0.1 would still send Host: evil.com, which the server rejects with HTTP 403 before serving token-bearing HTML.
  2. Per-launch CSRF token. arkor dev generates a 32-byte token (base64url) on every launch, injects it into index.html as <meta name="arkor-studio-token">, and requires it on every /api/* call as X-Arkor-Studio-Token. The job-event stream also accepts ?studioToken= because EventSource cannot send custom headers; mutation routes do not accept query-string tokens. Cross-origin tabs cannot read the meta, so a “simple” cross-origin POST that skips preflight is still rejected. Comparison is timingSafeEqual.
  3. No CORS. The SPA is same-origin so CORS adds no value. Reflecting * would let “simple” cross-origin POSTs (text/plain, urlencoded) through; the token check is what rejects them.
The token is rotated on every arkor dev launch, so a stale tab from a previous run will fail with HTTP 403 until you reload it.

What works today

Not yet

These exist either at the SDK or HTTP-API level, but not as Studio UI today:

When not to use Studio

Studio is a development tool. It only listens on loopback, only while arkor dev is up, and rotates its CSRF token every launch. For production usage, call infer from your own application code (or whatever serving layer you ship) rather than pointing users at Studio.