Skip to main content

Module local_api

Module local_api 

Source
Expand description

Always-on local HTTP API for image generation (127.0.0.1 only).

Synchronous: POST /image blocks until the engine finishes and returns the image bytes. Models come from the local Catalog, which the operator can extend at runtime via POST /models — the same ModelSource shape the studio uses. Every job is recorded into the in-app local queue.

§Security model

Binding loopback alone is not enough:

  • Browsers happily fire cross-site text/plain POSTs at 127.0.0.1 without a CORS preflight, and this API parses bodies as JSON regardless of content type — so without a guard any web page could inject catalog models (with attacker-controlled download URLs) or burn the GPU. DNS rebinding additionally lets a page read responses.
  • Any other local OS user can reach the port.

Defence, checked in order on every route except GET /healthz:

  1. Host allow-list — must be loopback (DNS-rebinding guard).
  2. Origin allow-list — when present, must be a loopback origin (CSRF guard; absent means a non-browser client and is allowed).
  3. Bearer token — Authorization: Bearer <token>, compared in constant time. The token is generated per install, persisted in config.toml, and published to local clients via the owner-only local-api.json discovery file in the worker’s config dir.

Structs§

LocalApi
The local image API server, bound but not yet serving.
ModelServices
What the local API offers besides one-off jobs: the model host, and the tokens that open streaming sessions on the LAN listener.

Constants§

MAX_BODY_BYTES
Maximum accepted request-body size. read_body used to read to string unbounded, so a single request could OOM the worker.

Functions§

remove_discovery_file
Best-effort removal of the discovery file on shutdown. A missing file is the desired end state; any other failure is warn-logged so a stale token file never vanishes silently and never lingers silently.
write_discovery_file
Publish the bound URL + bearer token for local clients, atomically and owner-only (the file carries the token). Written on every successful bind; removed again by remove_discovery_file on clean shutdown so stale files can’t point at a dead port.