The sandbox
Where an app runs, what it can touch, and why default-deny egress means one bad generation or one prompt injection cannot post your data anywhere.
An app is code that an agent wrote. It may be wrong, or it may be steered by text it reads. So Qaldy treats every app as untrusted and puts the limits outside the code, where the code cannot change them.
Where it runs#
Apps run in isolates on Cloudflare's Dynamic Workers, loaded by the Qaldy runtime host (rt.qaldy.com). An isolate is a small, fast sandbox: the app's code and a handful of bindings, and nothing else. There is no shell, no file system you can see, and no network of the app's own. An app starts when a request arrives, runs, and goes away; it scales per request and sleeps when idle.
The bundle that runs is the bundle that was approved. The runtime host recomputes its hash before loading it and refuses a mismatch, and a published version's permissions cannot be edited in place: wider access needs a new version, a new Trust Score and a new approval.
What the isolate holds#
- The app's code, and the platform's small SDK.
- A binding to the app's own data, built per app by the host. App A cannot open app B's store.
- No secrets. The environment of the isolate has no keys. Not in variables, not in globals, not in the bundle. A check searches the bundle, the environment, the global scope and every reply for the bytes of a test key, and fails if it finds one.
- One way out. All outbound traffic from the isolate goes to the runtime host's egress entrypoint and from there to the gate. A raw socket from the isolate fails.
Default-deny egress#
The gate allows an outbound call only if it is on the version's list:
- a connector action the app declared ("send a Telegram message to #roastery"), and only that action;
- an internet address the app declared with a reason a person read and approved. HTTPS only, port 443, an exact host name. No wildcards, no raw IP addresses.
Everything else is refused with 403 egress_blocked, recorded in the audit log, and drawn in the City as a barrier. The reason is on the run.
The gate also guards against being turned against its own network. It resolves DNS itself, refuses loopback, private, link-local and cloud-metadata ranges, and connects to the address it checked, so a name that is made to resolve somewhere else a moment later cannot redirect a call. It does not follow redirects: each hop is checked again.
What an app can still do#
Be clear about the edge of the guarantee. An app that is allowed to send messages to a chat can send any message to that chat. An app allowed to post rows to a CRM can post any rows. The sandbox cannot tell a good message from a bad one. What it does is make the destination explicit: it is a sentence in the plan, and the plan needs a person's approval. Apps that reach the internet, use AI or send messages through a connector are always approved in the console.
What is not built yet#
- Defence in depth against a flaw in the isolate itself comes from Cloudflare's own layers in the global cell. A dedicated microVM per tenant for a sovereign cell is Planned.
- Per-run and per-connector rate caps at the gate beyond the plan's concurrency are Planned.
- The scaling policy you can set per app (warm instances, concurrency, region pins) is saved and shown, and not yet applied by the runtime. It is labelled Preview where you set it.