Public: anyone can read this; the crew can change it.

A cell sees an allow-list of mounts, not the pod's mounts minus a deny-list #801

shipped production is serving it opened this
opened this

Follow-up from #680 (the security review of #658). This is a blocker of #586.

Today. A cell (src/apps/contain.ts) binds the machine's root read-only. It then hides a deny-list:

  • the forge's data directory and home
  • /tmp and /run (replaced with the cell's own)
  • /run/secrets and /var/run/secrets
  • every tmpfs mount outside /dev, /proc and /sys (this is how Kubernetes mounts a secret or a service-account token)
  • anything mounted under /run or /var/run

That covers what production mounts into the forge pod today. It is still the pod's mounts minus a deny-list, and ConfigMaps, hostPath volumes, PVCs and CSI volumes are usually not tmpfs. A forge deployed with any of those would expose them to every app, preview, terminal and check.

Wanted. A cell sees an allow-list of mounts, not the pod's mounts minus a deny-list. Every mount point in /proc/self/mountinfo is hidden unless it is on a short list:

  • /, /dev, /proc and /sys (the cell's own)
  • /etc/hosts, /etc/resolv.conf and /etc/hostname
  • the runtime's own directory
  • the cell's own writable binds

The list must not break a developer's machine. On NixOS, for example, /nix/store is a mount, so the list needs an operator setting (or a rule for read-only system mounts) rather than a fixed set.

Acceptance criteria

  • A test pod mounts a ConfigMap, a hostPath and a PVC at paths outside /run. From inside a cell, each is empty or unreadable, while bun, git and DNS still work.
  • The existing cell tests in test/contain.test.ts still pass on Linux, nested inside a cell as well.
  • docs/APPS.md rule 9 describes the allow-list and the setting for extra system mounts.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs