Skip to content

feat(cli): add --volume flag for host directory bind mounts in Docker sandboxes#1348

Open
ericcurtin wants to merge 1 commit into
NVIDIA:mainfrom
ericcurtin:sandbox-volume-mounts/ecurtin
Open

feat(cli): add --volume flag for host directory bind mounts in Docker sandboxes#1348
ericcurtin wants to merge 1 commit into
NVIDIA:mainfrom
ericcurtin:sandbox-volume-mounts/ecurtin

Conversation

@ericcurtin
Copy link
Copy Markdown
Contributor

Summary

Add a --volume HOST_PATH[:SANDBOX_PATH][:ro] flag to openshell sandbox create that bind-mounts a host directory into a Docker-backed sandbox at create time. This is the live-edit alternative to --upload: changes inside the sandbox are immediately visible on the host and vice versa, with no upload/download cycle.

Related Issue

N/A (new feature, discovered gap during development workflow research)

Changes

  • Proto: adds SandboxMount / DriverSandboxMount messages (host_path, sandbox_path, read_only) and mounts fields to SandboxTemplate (field 11) and DriverSandboxTemplate (field 12)
  • CLI: --volume HOST_PATH[:SANDBOX_PATH][:ro], repeatable; parses docker-style spec; rejects unknown options; no short flag (avoids collision with -v/--verbose)
  • Docker driver: appends user mounts to build_binds() as host:sandbox[:ro] bind strings; validates host_path non-empty; accepts multiple mounts
  • K8s driver: rejects non-empty mounts at ValidateSandboxCreate time — cloud gateway nodes don't have the local host path
  • VM driver: same rejection
  • Server: when mounts are present, injects each sandbox_path into the persisted FilesystemPolicy, seeded from restrictive_default_policy() so the supervisor receives a complete Landlock allowlist rather than a sparse policy that locks it out of system paths
  • Landlock (openshell-sandbox): Docker Desktop on macOS uses a proprietary fakeowner filesystem for host bind mounts. Landlock rules for fakeowner directories are added successfully but the kernel-side ReadDir enforcement fails at access time, causing ls to return EACCES even with a rule present. Fix: exclude ReadDir from the Landlock restriction mask so directory listing is unrestricted while all file-level access controls (ReadFile, WriteFile, Execute, write operations) remain fully enforced
  • Validation: max 32 mounts per sandbox, path length ≤ 4096 bytes
  • Skill reference: updated cli-reference.md with --volume flag

Testing

  • mise run pre-commit passes
  • Unit tests added/updated (Docker driver tests, integration tests updated for new volumes param)
  • E2E tests added/updated (not applicable — local Docker-only feature)
  • Manually tested end-to-end: ls and cat of files in a bind-mounted repo directory succeed inside the sandbox

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)

@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 13, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@ericcurtin
Copy link
Copy Markdown
Contributor Author

ericcurtin commented May 13, 2026

This is for the simple coding agent use case ($PWD == /Users/ecurtin/git/OpenShell):

openshell sandbox create --volume $PWD:/sandbox -- opencode

so we don't have to upload/download code in and out of the sandbox, which is not so pragmatic, it's tempting to create "openshell run" that's shorthand for above:

openshell run opencode

… sandboxes

Add a new --volume HOST_PATH[:SANDBOX_PATH][:ro] flag to sandbox create
that bind-mounts a host directory into the sandbox at create time.

This is the live-edit alternative to --upload: changes made inside the
sandbox are immediately visible on the host and vice versa, with no
upload/download cycle required.

Key design decisions:

- Only supported by local Docker-backed gateways. Kubernetes and VM
  drivers reject a non-empty mounts list at ValidateSandboxCreate time
  with a clear error pointing to sandbox upload as the alternative.

- Proto: adds SandboxMount / DriverSandboxMount messages (host_path,
  sandbox_path, read_only) and mounts fields to SandboxTemplate (field
  11) and DriverSandboxTemplate (field 12).

- Server: when mounts are present, automatically injects each
  sandbox_path into the persisted FilesystemPolicy (seeded from
  restrictive_default_policy so the supervisor receives a complete
  Landlock allowlist rather than a sparse one that locks it out of
  system paths).

- Landlock: Docker Desktop on macOS uses a fakeowner filesystem for
  host bind mounts whose ReadDir enforcement is incompatible with
  Landlock rules (rules are applied but the kernel-side lookup fails
  at access time). Fix by excluding ReadDir from the Landlock
  restriction mask so directory listing is unrestricted while all
  file-level access controls remain enforced.

- Validation: max 32 mounts per sandbox, path length <= 4096 bytes.

Tested end-to-end: ls and cat of files in the bind-mounted repo
directory work correctly inside the sandbox.
@ericcurtin ericcurtin force-pushed the sandbox-volume-mounts/ecurtin branch from ce0e72f to b359953 Compare May 13, 2026 00:53
@ericcurtin
Copy link
Copy Markdown
Contributor Author

ericcurtin commented May 13, 2026

Oh GitHub, let me run CI without approval every time 😅

@drew
Copy link
Copy Markdown
Collaborator

drew commented May 13, 2026

We've been hesitant to add this in for a few reasons

  1. It's not broadly compatible with all sandbox implementations (eg Kubernetes).
  2. It opens a new surface area from the host that could be exploited. We'd need to add controls for enterprise to restrict what is allowed to be mounted vs not.
  3. Differences in volume mounts on mac (host) vs linux (guest) can sometimes cause unexpected problems.

This is still an area of exploration/research, but our current thinking is to lean in on providers for getting data in and out of sandboxes. For example, if you want to work on a Git repository you could pull or push using a remote and the Github/Gitlab provider.

@ericcurtin
Copy link
Copy Markdown
Contributor Author

ericcurtin commented May 13, 2026

We've been hesitant to add this in for a few reasons

  1. It's not broadly compatible with all sandbox implementations (eg Kubernetes).

It's the docker/podman local single-node use-case this is useful for. I wouldn't recommend users do this for k8s, even if it was possible.

  1. It opens a new surface area from the host that could be exploited. We'd need to add controls for enterprise to restrict what is allowed to be mounted vs not.
  2. Differences in volume mounts on mac (host) vs linux (guest) can sometimes cause unexpected problems.

This is still an area of exploration/research, but our current thinking is to lean in on providers for getting data in and out of sandboxes. For example, if you want to work on a Git repository you could pull or push using a remote and the Github/Gitlab provider.

I think the push/pull technique is fine for a "Remote Kubernetes cluster" as defined in this document:

https://docs.nvidia.com/openshell/about/how-it-works

For the "local machine" coding agent use case, OpenShell becomes unsuitable for that use case for many if it's a requirement to push/pull full git repos in and out of the sandbox. It's important iterations are quick for that use case. It's simply too slow for development to push/pull iteratively and continue being useful.

I'm ok with this being shot down. If OpenShell is prioritising k8s, with local machines an afterthought I think it's ok to shoot this down.

But for local machines, I think people will look for other sandboxing tools if they can't do this at least optionally, openshell won't be popular there if people have to push/pull whole repos to use it locally.

@benoitf
Copy link
Copy Markdown
Contributor

benoitf commented May 13, 2026

hello, IMHO I think podman and VM drivers ( the one providing local experience) should have the support of this as for local machine experience you need access to your local directories. ( Upload is not really working as there is no sync back)
it could be turn on/off when starting the driver but each VM/container having its own mount, the hint about the volume still need to go on the cli / sandbox create time

would it be possible that arguments are possible or not based on what the driver authorize or not ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants