Skip to content

Docker Sandbox on Linux: agent cannot create new files in workspace via virtiofs #1561

@mattgodbolt-molty

Description

@mattgodbolt-molty

Note

This issue was filed by an LLM (Claude Code) acting on behalf of @mattgodbolt, who encountered and investigated this problem. All testing and analysis below was performed on Matt's machine.

Description

Docker sandbox on Linux cannot create new files in the mounted workspace. The agent can read files and modify existing files, but any open(O_CREAT), mkdir, or mknod fails with EPERM: Operation not permitted. This makes the sandbox unusable for AI coding agents, which need to create files as part of their work.

The macOS/Windows implementation uses file synchronization rather than virtiofs (per the architecture docs), so we believe this is Linux-specific, but we have not verified on macOS.

Environment

  • Docker Engine 29.3.0
  • Docker Sandbox v0.12.0
  • Host: Linux 6.17.0-14-generic (Ubuntu)
  • Host user: uid 1001, gid 992

Steps to reproduce

# Host user is NOT uid 1000
id
# uid=1001(molty) gid=992(kvm) ...

# Create a workspace with some files
mkdir -p /tmp/sandbox-test
echo "hello" > /tmp/sandbox-test/existing.txt

# Launch a sandbox
docker sandbox run claude /tmp/sandbox-test

Inside the sandbox:

# Reading works
cat /tmp/sandbox-test/existing.txt  # OK

# Modifying existing files works
echo "world" >> /tmp/sandbox-test/existing.txt  # OK

# Creating new files fails with EPERM (not EACCES)
touch /tmp/sandbox-test/new-file.txt
# touch: cannot touch ...: Permission denied

python3 -c "open('/tmp/sandbox-test/new.txt', 'w')"
# PermissionError: [Errno 1] Operation not permitted

# mkdir also fails
mkdir /tmp/sandbox-test/newdir
# mkdir: cannot create directory ...: Permission denied

# Interestingly, hardlinks work
ln /tmp/sandbox-test/existing.txt /tmp/sandbox-test/hardlink  # OK

Key finding: UID matching does not help

Even after changing the sandbox agent's uid and gid to match the host user exactly:

# Inside sandbox, as root:
groupmod -g 1002 docker    # free up gid 1001
groupmod -g 1001 agent
usermod -u 1001 agent
# Verify: uid=1001(agent) gid=1001(agent)

File creation still fails with EPERM. This rules out a simple UID mismatch — the virtiofs passthrough layer itself is blocking create operations regardless of credential matching.

The krun VM host process runs as the correct host uid:

# On host:
ps aux | grep krun
molty  1722585 ... /home/molty/.container-platform/com.docker.krun

cat /proc/1722585/status | grep Uid
Uid: 1001 1001 1001 1001

The host user can create files in the same directory directly — the issue is specifically in the virtiofs path from VM to host.

Analysis

On Linux, Docker sandbox uses libkrun microVMs with virtiofs:

virtiofs0 on /tmp/sandbox-test type virtiofs (rw,nosuid,nodev,relatime,ignore_atime,no_xattr,keep_cache)

The standard virtiofsd uses uid_map/gid_map and unix_credentials_guard() to temporarily switch credentials via setfsuid/setfsgid before host filesystem operations. libkrun's virtiofs server passes guest credentials through via Context::from(in_header), but create operations fail even when guest and host UIDs match — suggesting the credential switching isn't reaching the host filesystem layer correctly.

The no_xattr mount option also prevents POSIX ACLs from being used as a workaround.

Expected behaviour

The sandbox workflows documentation states:

"Agents can create and modify any files in your mounted workspace"

And the architecture page states:

"This is file synchronization, not volume mounting. Files are copied between host and VM."

On macOS/Windows, file synchronization is used, which works correctly. On Linux, virtiofs direct mounting is used instead, and file creation is broken.

Impact

File creation is broken for Linux sandbox users regardless of UID. The sandbox is limited to reading and modifying existing files, which makes it unusable for AI coding agents that routinely need to create new files.

Thank you for building this — the sandbox concept is exactly what we need for safe AI agent execution, and we're looking forward to it working fully on Linux!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions