Appearance
Shared workspace (/wrk)
A workspace is a persistent drive shared across all of an owner's boxes at once — mount /wrk in any box and see the same files. Unlike a box's persistent home (one per box) or the box's own rootfs (per box), a workspace is a shared network drive: write from one box, read it from another.
/wrk is not backed up
Its data lives in the MinIO hopbox-wrk bucket and its metadata in Postgres (JuiceFS) — two systems that must stay consistent with each other. The daemon's off-host backup covers the control-plane state (box ownership, accounts, the SSH host key) but deliberately excludes /wrk. Treat it as scratch space shared across your boxes, not storage of record.
Use it
Inside any box (when the host has the workspace enabled):
sh
box-guest workspace mount # mount your shared drive at /wrk
echo hi > /wrk/notes.txt # …then from any other box of yours:
box-guest workspace mount && cat /wrk/notes.txt # → hi
box-guest workspace info # show the mount details
box-guest workspace umount # unmountThe same files appear in every box you own — a scratch space that follows you across the fleet, independent of any single box's lifecycle.
Over HTTP
The same /wrk is reachable over the HTTP API when the daemon runs --api-addr — read, write, list, and delete without a shell, for agents and scripts. It's authenticated by the same hbx_ key as everything else, so you only ever see your own workspace:
sh
H='Authorization: Bearer hbx_…'
curl -H "$H" -X PUT --data-binary @report.md https://box.hopbox.dev/v1/wrk/report.md
curl -H "$H" https://box.hopbox.dev/v1/wrk/ # JSON listing of /wrk
curl -H "$H" https://box.hopbox.dev/v1/wrk/report.md # the file backA file written over HTTP is immediately visible in every box's /wrk, and vice versa — it's one drive, two front doors.
On a host started with --workspace-automount, /wrk is mounted for you automatically at box startup (no mount step). It's off by default — on a public front door you don't want every visitor's key to accrue a volume, so there boxes mount explicitly. Browser-terminal boxes never get a workspace.
Isolation is per owner. Beyond the Postgres metadata isolation, each owner's volume uses its own object-store credential scoped to its own prefix — so even a credential extracted from inside a box can't reach another owner's data.
How it works
The workspace is a JuiceFS filesystem over S3-compatible object storage (self-hosted MinIO by default), one volume per owner:
- Data lives in the object store; metadata lives in Postgres.
- Isolation is per owner, enforced by Postgres: each owner's JuiceFS metadata is a schema owned by that owner's own login role — a role cannot read another owner's schema. A box is handed only its owner's scoped metadata DSN, and JuiceFS reads the object-store config from that metadata, so no shared credential ever enters a box.
- A box reaches the metadata engine + object store over the box-network gateway; the egress fence allows exactly those ports and nothing else.
Enabling it on a host
The workspace is off by default. It needs three things beside hopboxd:
- A FUSE-capable guest kernel — JuiceFS is a FUSE filesystem, and the prebuilt firecracker kernels ship without it. Build one once:sh
sudo systemd-run --unit=kbuild --collect /bin/bash deploy/build-fuse-kernel.sh - MinIO + Postgres beside the daemon:sh
sudo bash deploy/workspace-setup.sh # prints the --workspace-* settings - Turn it on — add the printed
workspace-*settings to/etc/hopbox/hopboxd.yamlandsystemctl restart hopboxd. See the workspace flags.
juicefs is baked into every catalog image (and installed host-side by the provisioner).