A read-only proxy in front of the Restate admin API (default port 9070). It lets the Restate UI load and browse everything, but blocks every mutating operation.
The proxy is a method + path whitelist (default-deny):
GET/HEADon any path — the UI is served from the admin port and all its read APIs areGET.POST /query— the SQL introspection endpoint the UI uses for most reads. The engine has DDL/DML disabled (verified per query plan) and is built without file/object-store functions, so it can't write or read host files.- Optionally
POST .../serdes/{decode,encode}/...— side-effect-free payload (de)serialization, needed to render binary payloads on Restate >= 1.7.0. Off by default. - Everything else —
403.
This works because every mutating endpoint in the admin API is either POST on
a non-/query path (register deployment, modify service state, bulk invocation
ops, ...) or PATCH/PUT/DELETE. A GET + POST /query whitelist catches
them all — a verb blacklist would miss the POST-based mutations.
nginx-proxy/ — an nginx config + a Docker script for quick
local testing.
- The whitelist also allows any other
GETthe server exposes (e.g. the raw metadata store, if the server was built with the non-defaultmetadata-apifeature). That's still read-only; restrictGETby path if you want to hide it. - Add TLS / auth in front if the proxy is exposed beyond localhost — it does neither.