Skip to content

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    # unmount

The 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 back

A 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:

  1. 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
  2. MinIO + Postgres beside the daemon:
    sh
    sudo bash deploy/workspace-setup.sh      # prints the --workspace-* settings
  3. Turn it on — add the printed workspace-* settings to /etc/hopbox/hopboxd.yaml and systemctl restart hopboxd. See the workspace flags.

juicefs is baked into every catalog image (and installed host-side by the provisioner).

Instant isolated compute — for humans and AIs