A Cursor Agent command just removed files outside the project, or you no longer know what the terminal tool can reach.
Use a disposable code copy plus Apple Container with restricted mounts. Do not treat command blacklists, .cursorignore, or approval prompts as your only security boundary.
This guide is for you if you:
- Let Cursor Agent install dependencies, edit several files, run tests, or execute scripts.
- Need a repeatable execution boundary for a small engineering team.
- Are comparing a local container sandbox with a separate or remote Mac development environment.
Last updated: August 29, 2026. Version and command details were checked against the current Apple Container documentation and Cursor security documentation on the same date.
The boundary: Linux isolation versus full macOS access
Apple Container runs Linux containers as lightweight virtual machines on Apple Silicon Macs. It is designed for Linux build tools, scripts, tests, and services. It does not place a complete macOS desktop, Xcode GUI workflow, or native signing environment inside the container. Apple’s project currently documents Apple Silicon and macOS 26 as the supported target for the released tool. See the official Apple Container README and release page.
That distinction determines the right architecture:
| Task | Apple Container | Host Mac or separate Mac environment |
|---|---|---|
| Linux dependency installation | Good fit | Usually unnecessary |
| Node, Python, Go, Rust, or shell tests | Good fit | Possible, but broader host access |
| Code generation and compilation | Good fit when the toolchain is Linux-compatible | Needed for native macOS outputs |
| Xcode GUI projects | Not a replacement | Required |
| Apple code signing and notarization | Keep outside the container unless separately designed and tested | Required for the native workflow |
| Access to the original repository | Avoid | Only when you accept the recovery risk |
| Access to personal credentials | Do not mount by default | Keep in a reviewed host or service boundary |
The most important limitation is simple: a container cannot protect data that you deliberately expose as a writable mount. If /workspace points to your only repository, rm -rf /workspace can still destroy that repository. The virtualization boundary protects unmounted host paths, not the contents of a writable shared directory.
Cursor adds useful controls. Its Run Modes can request approval, apply allowlists, and sandbox supported shell commands. Cursor describes these controls as best-effort guardrails rather than a hard security boundary. Its .cursorignore file controls indexing and agent context, but terminal commands and MCP tools can operate outside those file-access controls. Check the Cursor Agent Security documentation, Run Modes reference, and ignore-file documentation.
Why the two-layer model matters
The first layer limits what Cursor is allowed to see and modify. The second layer limits what the executed Linux process can reach.
This solves three separate problems:
- Recovery: the agent works on a disposable copy, so the original checkout remains available.
- Reachability: Apple Container receives only the disposable project directory.
- Process control: the root filesystem is read-only, the process runs without root privileges, and the default network is disabled.
No single setting covers all three.
Preparation: a disposable workspace before the agent
Start by checking the host. Apple Container requires Apple Silicon for the current supported workflow. Confirm the architecture and operating system before spending time on the image:
uname -m
sw_vers -productVersion
container system version
container system status
You want an Apple Silicon result, macOS 26, a responding container service, and a version that matches the tagged release documentation you selected. The command reference warns that documentation for the current branch may differ from a released tag, so pin your operational notes to the release you actually install. Use the official command reference rather than copying commands from an undated forum post.
Prepare a throwaway workspace. A temporary clone is easiest:
mkdir -p "$HOME/agent-workspaces"
git clone --local "$HOME/src/example-app" \
"$HOME/agent-workspaces/example-app-agent-$(date +%Y%m%d-%H%M%S)"
If the repository uses large objects, submodules, or generated files, use a normal clone or a Git worktree instead. The rule is unchanged: Cursor must open the disposable path, not $HOME/src/example-app.
Before starting Cursor, create evidence that makes a destructive test visible:
cd "$HOME/agent-workspaces/example-app-agent-YYYYMMDD-HHMMSS"
printf 'agent-sandbox-canary\n' > CANARY_DO_NOT_DELETE.txt
git status --short
git rev-parse --show-toplevel
Keep the original repository outside the mounted path. Do not put a symlink inside the disposable copy that points back to the original checkout. A symlink can turn an apparently narrow workspace into a path back to sensitive data.
Back up uncommitted work separately. A disposable clone is not a substitute for version control. Commit known-good work, save patches, and make sure you can delete the entire agent workspace without losing irreplaceable files.
Build: a small non-root Linux image
Apple Container builds OCI images from a Dockerfile or Containerfile. The official tutorial uses container build with a Dockerfile, and the command reference documents the -t and -f options. The example below installs a compact Alpine toolset. Replace the packages with the tools your project actually needs.
Create a directory outside the project:
mkdir -p "$HOME/agent-sandbox"
cd "$HOME/agent-sandbox"
Create Dockerfile:
FROM alpine:3.22
RUN apk add --no-cache \
bash \
ca-certificates \
curl \
git \
jq \
make \
nodejs \
npm \
python3 \
py3-pip
RUN addgroup -S agent && adduser -S -G agent agent
WORKDIR /workspace
USER agent
ENV HOME=/tmp/agent-home
ENV npm_config_cache=/tmp/npm-cache
ENV PIP_CACHE_DIR=/tmp/pip-cache
CMD ["sh"]
Build it:
container system start
container build --tag machtml/cursor-agent-sandbox:latest --file Dockerfile .
The image name is only a local label. It is not a security boundary and does not make the image trustworthy. Review the base image, package sources, and build output before using it with an agent.
The image uses a non-root default user. The runtime command below also supplies the host user and group numerically. Test file ownership in your own environment. If the mounted copy is not writable by the mapped user, fix permissions on the disposable copy. Do not solve the problem by mounting the home directory or switching the container to unrestricted root access.
Runtime wrapper: read-only root, narrow mount, no network
Create sandbox-run.sh:
#!/bin/zsh
set -euo pipefail
if [[ $# -eq 0 ]]; then
print -u2 "Usage: $0 <command> [args...]"
exit 64
fi
WORKSPACE="${CURSOR_SANDBOX_WORKSPACE:-$PWD}"
if [[ ! -d "$WORKSPACE" ]]; then
print -u2 "Workspace does not exist: $WORKSPACE"
exit 66
fi
case "$WORKSPACE" in
"$HOME"/agent-workspaces/*) ;;
*)
print -u2 "Refusing to mount a non-disposable workspace."
print -u2 "Set CURSOR_SANDBOX_WORKSPACE to a path below \$HOME/agent-workspaces."
exit 77
;;
esac
exec container run \
--rm \
--read-only \
--network none \
--tmpfs /tmp:size=1G,mode=1777 \
--mount "type=bind,source=${WORKSPACE},target=/workspace" \
--workdir /workspace \
--user "$(id -u):$(id -g)" \
machtml/cursor-agent-sandbox:latest \
"$@"
Make it executable:
chmod +x sandbox-run.sh
The wrapper implements several independent controls:
--rmremoves the container after it exits.--read-onlymakes the image root filesystem read-only.--network noneremoves the container’s network attachment.--tmpfs /tmpprovides disposable writable storage for caches and temporary files.- The bind mount exposes one directory at
/workspace. --workdir /workspaceprevents accidental commands from starting in an unexpected directory.--useravoids running the task as root.
Apple’s volume documentation confirms the bind, readonly, and tmpfs mount forms, including temporary storage that disappears when the container stops. The network option is documented in the current command behavior and release history. See the Apple Container volume documentation and command reference.
Run harmless checks first:
./sandbox-run.sh sh -lc 'id && pwd && touch /tmp/check && ls -la'
./sandbox-run.sh sh -lc 'test -w /workspace && echo workspace-writable'
./sandbox-run.sh sh -lc 'test ! -w /etc && echo root-read-only'
./sandbox-run.sh sh -lc 'getent hosts example.com || true'
The last command should not provide normal DNS resolution with --network none. Treat that as an operational test, not as proof that every possible side channel has been eliminated.
A writable /workspace remains writable. That is intentional because the agent needs to edit code. It also means the disposable-copy rule is mandatory.
Configuration choices: local sandbox versus broader access
Use the smallest mount that supports the task. A source directory mounted read-only can support some code review and static analysis. A disposable clone mounted read-write supports compilation, tests, and generated files. A home directory mount is convenient and usually the wrong trade.
| Resource | Default decision | Reason |
|---|---|---|
| Disposable project copy | Read-write | Agent needs to edit and test code |
| Original repository | Never mount | Preserves rollback and recovery |
$HOME |
Never mount | Prevents broad access to personal files |
~/.ssh |
Never mount | Avoids private key exposure |
| Cloud credential files | Never mount | Prevents accidental API access |
| Keychain exports | Never mount | They are not required for ordinary Linux tests |
/tmp inside container |
Writable tmpfs | Caches disappear with the container |
| Production environment variables | Do not pass | Secrets can leak through logs or child processes |
| Dependency registry access | Disabled by default | Enable only for a reviewed installation step |
If a dependency install needs the network, do not silently change the default wrapper. Create a separate, visibly named command for the preparation phase. Run it against the disposable workspace, inspect the lockfile and changes, then return to the offline wrapper for the agent’s autonomous work.
For credentials, prefer short-lived tokens with the narrowest repository or package scope. Inject them only for the one command that needs them, and avoid writing them into files under /workspace. A token passed through an environment variable can still appear in diagnostics or child-process output, so inspect logs after the task.
Do not use a shell blacklist as the primary control. Blocking rm may stop one obvious command while allowing a script, package manager, interpreter, or generated command to perform the same operation. Mount permissions and network reachability address the broader class of failures.
Cursor integration: application guardrails on top
Open only the disposable workspace in Cursor. Then add project instructions that make the safe path the normal path:
For build, test, dependency, formatting, and script commands, use:
./../agent-sandbox/sandbox-run.sh <command>
Do not run package managers, interpreters, deployment tools, credential commands,
or filesystem cleanup directly on the host terminal.
Never access paths outside /workspace.
Ask for approval before deletion, publishing, credential use, release work,
or any host configuration change.
The exact relative path depends on where you keep sandbox-run.sh. An absolute path is clearer for a team workstation:
/Users/your-user/agent-sandbox/sandbox-run.sh npm test
Project rules help the agent choose the wrapper. They do not force every future tool call through it. Keep Cursor’s terminal approvals enabled. Use Auto-review or a narrow allowlist for routine commands, and require review for:
rm,mv,chmod,chown, and recursive filesystem operations.- Credential, cloud, deployment, release, and package-publishing commands.
- Git history rewriting or branch deletion.
- Commands containing host paths.
- Commands that request network access.
- Any use of
sudo, launch services, system settings, or keychain tools.
Cursor’s own documentation states that agents can modify workspace files, terminal tools have separate behavior from ignore files, and security controls are best-effort. That is why the wrapper and disposable copy must remain effective even when the agent ignores a project instruction.
Comparison: Apple Container, Docker, and a separate Mac
Apple Container is a strong fit when the task is Linux-oriented and local. It is a weaker fit when the task depends on macOS APIs, physical devices, GUI applications, or shared team operations.
| Requirement | Apple Container | Docker-based local setup | Separate or remote Mac |
|---|---|---|---|
| Linux build and test | Strong | Strong | Depends on environment |
| Full macOS workflow | No | No | Strong |
| Host filesystem isolation | Strong when mounts are narrow | Strong when mounts are narrow | Strong if the environment is dedicated |
| Existing Docker image reuse | Often possible, but test compatibility | Native fit | Usually indirect |
| Offline execution | Supported with --network none |
Supported with network controls | Depends on service design |
| Xcode GUI and signing | Not the right boundary | Not the right boundary | Appropriate |
| Team reset and shared policy | Requires engineering work | Mature ecosystem | Strong when centrally managed |
| Main failure mode | Unsafe writable mount or unsupported workflow | Unsafe bind mount or daemon policy | Credential, access, and cost management |
Calling Apple Container a Docker replacement without qualification creates the wrong expectation. It consumes OCI-compatible images, but image compatibility does not guarantee identical networking, storage, build, or runtime behavior. Validate the commands your project actually uses.
Acceptance: prove the boundary with destructive tests
Do not declare the sandbox safe after the first successful npm test. Test the failure modes that matter.
Run the following from the disposable workspace:
./sandbox-run.sh sh -lc '
printf "container-canary\n" > /workspace/CANARY_DO_NOT_DELETE.txt
rm -f /workspace/CANARY_DO_NOT_DELETE.txt
'
That deletion should affect only the disposable copy. Now place a second canary outside it:
printf "host-canary\n" > "$HOME/agent-host-canary.txt"
./sandbox-run.sh sh -lc '
rm -f /workspace/../agent-host-canary.txt 2>/dev/null || true
test -e /workspace/../agent-host-canary.txt
'
The host canary should remain. Also check that the original repository has no unexpected changes:
git -C "$HOME/src/example-app" status --short
git -C "$CURSOR_SANDBOX_WORKSPACE" diff --stat
Your first acceptance run should cover these checks:
- [ ] Cursor opened the disposable workspace, not the original checkout.
- [ ]
container system statusreports a healthy service. - [ ] The image runs as a non-root numeric user.
- [ ]
/etcand other image paths are not writable. - [ ]
/tmpis writable and disposable. - [ ] Only the intended workspace is mounted.
- [ ]
--network noneblocks normal outbound access. - [ ] A deletion inside
/workspacecannot alter the original repository. - [ ] A host canary outside the mount survives.
- [ ] No SSH keys, cloud credentials, or keychain exports appear in the container.
- [ ] The container disappears after exit because of
--rm. - [ ] Logs and generated files contain no secret values.
- [ ] The disposable workspace can be deleted and recreated from Git.
If any item fails, stop using the setup for autonomous execution. Recheck the mount string first. Most serious mistakes come from mounting the wrong path, following a symlink, passing an environment file, or adding a writable cache directory that contains credentials.
| Result | Decision |
|---|---|
| Original repository unchanged, host canary survives, no network, no secrets | Suitable for routine Linux build and test tasks |
| Workspace isolation passes but secrets appear in logs | Remove credential injection and rotate exposed credentials |
| Network remains available when it should be disabled | Stop and verify the installed release and exact runtime flags |
| Agent needs Xcode, signing, GUI tools, or physical devices | Move that step to the host or a dedicated Mac environment |
| Multiple developers need identical resettable environments | Evaluate a managed or remote Mac workflow |
Maintenance: keep the boundary reproducible
Record the Apple Container release, macOS version, image digest, Dockerfile, wrapper script, and acceptance output in the project’s security notes. Re-run the destructive tests after upgrading Apple Container, macOS, the base image, or Cursor.
Keep the image small. Rebuild it when the project’s toolchain changes. Do not install broad cloud CLIs merely because an agent might need them. Each additional tool expands the command surface and the number of credentials someone may eventually inject.
For a single developer, this local setup is often enough for dependency installation, code generation, compilation, unit tests, and scripted analysis. For a team, the decision changes when you need concurrent jobs, central policy, audit logs, rapid reset, remote access, or a full macOS toolchain. At that point, compare the MacHTML console workflow, the MacHTML help resources, and the MacHTML Mac environment overview.
The local approach still has three real drawbacks: you must maintain the image and wrapper, you must police disposable-copy handling, and macOS-native tasks remain outside the Linux container. A separate Mac environment removes more host exposure and is easier to reset for shared high-risk work, although it introduces access management, provisioning, and network considerations.
If your current setup gives Cursor direct access to the original repository, personal credentials, and a shared workstation, the Apple Container wrapper is a meaningful improvement but not a complete answer. Use it for temporary local execution. When the agent must handle sensitive repositories, multiple users, or repeatable high-risk automation, move that workload to a resettable Mac environment instead of widening the local mount.
Run Your Coding Agent on a Remote Mac
Use MacHTML to access a dedicated Mac environment for development, testing, and automation. Keep agent-driven experiments separate from your everyday computer with a remote workspace. Connect to your Mac through a browser-based session and manage it from wherever you work. Choose a MacHTML plan that matches your workload and start building with dependable remote Mac access.