Security
A script is code written by people, with packages pulled from npm and PyPI. Waiso assumes any of it could misbehave and builds the defences around the run, not around trust: each run is its own sandboxed process with no network and no view of the platform, secrets reach it only as the values it was given, and everything the platform itself dials out to is checked first.
- Know what a running script can and cannot reach
- Understand how secrets are stored and delivered
- See which outbound addresses are refused and why
- Know the settings a self-hosted operator controls
Layers around every run
Your code never runs inside the worker itself. The worker keeps the database connection, the install machinery and the credentials; your code runs in a separate runner process inside a sandbox, with only its file, its inputs and its packages.
| Layer | What it stops |
|---|---|
| One process per run | A run cannot see another run’s memory, and a crash or a hang ends only that run. |
| Sandbox | The code sees a read-only system and writes only to its own temporary space, without administrator rights. |
| No network | A script has no route out — not to the internet, not to the platform’s API, editor services or database. |
| Scrubbed environment | Anything that looks like a password, token or connection string is removed before code runs. |
| Resource caps | Memory, CPU and process limits per worker, so a runaway script cannot starve the machine. |
Secrets
Secret variables and integration credentials are stored encrypted (AES-256-GCM). A run receives the values it needs as environment variables of its own process, delivered with the job — never written into a file, a log or the repository. Only admins and a project’s creator can reveal a secret’s value; everyone else may use it without reading it.
- In a flow, an input bound to a secret variable is recorded as
•••in the run’s inputs. - Tokens — sessions, API tokens, MCP tokens — are stored only as a hash and shown once, at creation.
- Logs go to the database and may be shown to your team: never print a secret.
Outbound addresses are checked
Whenever the platform dials out for you — a database connection, an SMTP server, a custom S3 endpoint, a file downloaded from a URL, a webhook, a site the AI Scraper visits — the address is checked first, and again on every redirect. Private, loopback and link-local addresses are refused with host_not_allowed, so nobody can point a connection at the server’s own internal network.
Allowing a private host on purpose
On a self-hosted installation, a database or mail server on your own network is a legitimate target. The operator lists those exact names; nothing else private is reachable.
# Private database hosts a connection may reach (exact names, comma list)
SQL_ALLOW_PRIVATE_HOSTS=db.internal,reports-db
# Private SMTP / S3 hosts the worker may reach
OUTBOUND_ALLOW_PRIVATE_HOSTS=mail.internalWhat an operator controls
WAISO_PKG_ALLOWLIST/WAISO_PKG_BLOCKLIST— which npm and PyPI packages may be installed. The blocklist always wins. Set the same values on every worker and on the editor service, or the editor offers a package the worker refuses.ISOLATION_LEVEL—sandboxby default. Turning isolation off gives scripts the worker container’s network; do it only on a machine where every script author is trusted.- Who may do what in each project is set per person on the Users tab.