Security Model
Radhflow runs untrusted code. SQL from users. CLI tools from package managers. Code generated by AI. The security model treats every node as potentially hostile and isolates it accordingly.
Three isolation tiers
Section titled “Three isolation tiers”Each node type gets the minimum sandbox it needs. Tighter isolation for more dangerous operations.
Tier 1: SQL nodes — DuckDB sandbox
Section titled “Tier 1: SQL nodes — DuckDB sandbox”SQL nodes run inside DuckDB’s query engine. DuckDB is an in-process database with no server, no daemon, no open ports.
| Capability | Allowed |
|---|---|
| Read input tables | Yes |
| Write output tables | Yes |
| Filesystem access | No |
| Network access | No |
| Execute commands | No |
| Access environment variables | No |
SQL nodes cannot escape the query engine. They see only the Tables wired to their input ports. This is the tightest sandbox — and covers the majority of data transform operations.
Tier 2: Platform CLI nodes — nix-shell + bubblewrap
Section titled “Tier 2: Platform CLI nodes — nix-shell + bubblewrap”CLI nodes run shell commands. They need filesystem access (to read/write files) and access to tools (ffmpeg, imagemagick, jq). Radhflow sandboxes them with two layers:
nix-shell declares exactly which tools the node can use. No global PATH. No ambient system packages. The Nix expression is part of the node spec and is auditable.
{ pkgs }: pkgs.mkShell { buildInputs = [ pkgs.jq pkgs.curl pkgs.imagemagick ];}bubblewrap provides Linux namespace isolation:
| Capability | Default |
|---|---|
| Filesystem | Read-only root, read-write workspace only |
| Network | None (blocked by default) |
| Processes | Isolated PID namespace |
| Users | Unprivileged, mapped UID |
| IPC | Isolated |
To grant network access, the node spec must explicitly declare it:
sandbox: network: true # default: falsePlatform nodes — the vetted CLI nodes shipped with Radhflow — have pre-approved sandbox configurations. Custom CLI nodes default to maximum restriction.
Tier 3: Agent-generated code — Firecracker microVMs (v0.5)
Section titled “Tier 3: Agent-generated code — Firecracker microVMs (v0.5)”Code generated by AI agents runs in the most restrictive environment. On local execution, users approve generated code before it runs. On hosted execution (v0.5), generated code runs inside Firecracker microVMs.
Firecracker provides hardware-level isolation:
| Property | Detail |
|---|---|
| Isolation | Separate Linux kernel per execution |
| Boot time | ~125ms |
| Memory | Dedicated, no sharing with host |
| Filesystem | Ephemeral, destroyed after execution |
| Network | None unless explicitly configured |
Each pipeline execution gets a fresh microVM. No state leaks between runs. No state leaks between customers.
License whitelist (hosted)
Section titled “License whitelist (hosted)”On the hosted service, node dependencies must pass a license audit. This prevents pipelines from pulling in code with incompatible obligations.
| Tier | Licenses | Policy |
|---|---|---|
| Green | MIT, BSD-2, BSD-3, ISC, Apache-2.0 | Allowed unconditionally |
| Amber | LGPL, MPL, GPL (subprocess only) | Allowed with restrictions |
| Red | AGPL, SSPL, patent-encumbered | Blocked |
The license check runs at pipeline creation time. Dependencies with red licenses are rejected before any code is generated.
Local execution has no license restrictions. Your machine, your rules.
No customer code in cloud
Section titled “No customer code in cloud”The hosted service never stores customer-generated code beyond execution. Pipeline definitions (YAML + specs) are stored for scheduling. Generated artifacts (NDJSON, output files) are stored in customer-owned S3 buckets. Node code is loaded, executed, and discarded.
Customer data does not train models. Customer pipelines are not shared. The hosted service is infrastructure, not a platform that monetizes your work.
Security boundaries summary
Section titled “Security boundaries summary” ┌──────────────────────────────────────────────┐ │ Docker Container │ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ DuckDB sandbox (Tier 1) │ │ │ │ SQL nodes — no FS, no net, no exec │ │ │ └─────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ bubblewrap + nix-shell (Tier 2) │ │ │ │ CLI nodes — isolated FS, no net (def.) │ │ │ └─────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ Firecracker microVM (Tier 3, v0.5) │ │ │ │ AI-generated code — full isolation │ │ │ └─────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────┘Docker is the outer boundary for all three tiers. On local, the Docker container runs on your machine. On hosted, the Docker container runs on EU infrastructure. The same image, the same boundaries.