docs(sandboxes): add workflow patterns page (#25228)

## Summary

Adds a new Workflows page to the sandboxes manual covering the patterns
that
don't fit cleanly in the mechanical usage reference: git strategies
(single-agent
feature branch and multi-agent parallel branches in clone mode, direct
mode),
commit signing via SSH agent forwarding, authenticated CLI tools (gh,
Docker
registry, 1Password via op read), and CI/headless use.

Generated by Claude Code

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
David Karlsson
2026-06-04 10:07:29 +02:00
committed by GitHub
parent 8c47944f28
commit 7f5d7502b1
2 changed files with 315 additions and 113 deletions
+12 -113
View File
@@ -79,19 +79,16 @@ sandbox:
- **Direct mode (default)** — the agent has read-write access to your
working tree. Changes the agent makes appear on your host immediately.
Best when you're collaborating turn-by-turn with the agent on a single
repository.
- **[Clone mode](#clone-mode) (`--clone`)** — the agent works on a private
Git clone inside the sandbox, with your host repository mounted
read-only. The sandbox exposes its clone as a Git remote on your host,
so you fetch the agent's commits the same way you'd fetch from any
other remote. Best when you want the agent isolated from your host
repository — for running multiple agents in parallel, working with
untrusted code, or keeping your working tree clean while the agent
works.
other remote.
See [Workspace isolation](security/isolation.md#workspace-isolation) for the
security model behind each mode.
For a comparison of approaches and step-by-step recipes, see
[Workflow patterns](workflows.md#git-workflows). For the security model
behind each mode, see
[Workspace isolation](security/isolation.md#workspace-isolation).
### Direct mode (default)
@@ -123,79 +120,17 @@ $ sbx run my-sandbox
```
The clone follows whichever ref your host repository has checked out at
create time. No new branch is created automatically. If you want the agent
to work on a dedicated branch, instruct it to run `git checkout -b
my-feature` inside the sandbox before it starts editing. Alternatively,
open a shell with `sbx exec` and create the branch yourself.
create time. No new branch is created automatically.
> [!NOTE]
> Clone mode is fixed at create time. To switch an existing sandbox to
> clone mode, remove it and recreate it with `sbx create --clone`.
#### Reviewing and merging the agent's commits
The CLI wires the in-sandbox clone as a `sandbox-<sandbox-name>` Git remote
on your host. Pull the agent's commits the same way you'd fetch any other
remote — no `cd` into a separate directory, no extra tooling:
```console
$ git fetch sandbox-my-sandbox
$ git log sandbox-my-sandbox/<branch>
$ git diff main..sandbox-my-sandbox/<branch>
$ git checkout -b my-feature sandbox-my-sandbox/<branch>
$ git push -u origin my-feature
$ gh pr create
```
If you asked the agent to work on a dedicated branch, `<branch>` is that
branch name. Otherwise it's whatever ref your host repository was on at
create time.
Some agents don't commit automatically. If `git log sandbox-<name>/<branch>`
shows nothing new, open a shell in the sandbox and commit from there:
```console
$ sbx exec -it my-sandbox bash
$ git commit -am "save work"
```
#### Pushing to your fork from inside the sandbox
When the sandbox starts, the CLI copies the Git remotes from your host
repository (`origin`, `upstream`, and so on) into the in-sandbox clone
with their existing URLs. The agent can push to your fork on GitHub
directly — for example, by prompting:
> Commit these changes and push them to a new branch on `origin`.
The push uses the same `git push origin ...` invocation the agent would
run on the host. This is interchangeable with fetching the commits to
your host first and pushing from there.
Local-path remotes (`file://` URLs, filesystem paths) aren't copied, since
they aren't reachable from inside the sandbox.
#### Running multiple branches in parallel
A single sandbox can hold several branches at once. Each branch the
agent commits to appears as a separate ref on the `sandbox-<name>`
remote, so you can fetch them independently from the host:
```console
$ git fetch sandbox-my-sandbox
$ git log sandbox-my-sandbox/feature-a
$ git log sandbox-my-sandbox/feature-b
```
A few common ways to have the agent start each task on its own branch:
- A subagent orchestrator such as Claude Code's
[agents view](agents/claude-code.md#agents-view) dispatches each task
to a subagent that creates its own worktree inside the clone.
- Agent-level instructions in `CLAUDE.md`, an orchestration skill, or a
system prompt include a rule to start each task on a new branch.
- For one-off tasks, ask the agent to switch to a new branch before it
starts.
The CLI copies the Git remotes from your host repository (`origin`,
`upstream`, and so on) into the in-sandbox clone. The agent can push to
your fork directly using the same remote names. Local-path remotes
(`file://` URLs, filesystem paths) aren't copied, since they aren't
reachable from inside the sandbox.
#### Sandbox lifecycle and the Git remote
@@ -230,43 +165,7 @@ rejected at create time in two cases:
You can also create a Git worktree yourself and run an agent inside it
without `--clone`, but the sandbox won't have access to the `.git`
directory in the parent repository, so the agent can't use Git at all.
Clone mode is the supported alternative for working on a separate branch.
### Signed commits
Sandboxes can sign Git commits with SSH keys from your host agent. The private
key stays on your host.
On the host, load the key into your SSH agent:
```console
$ ssh-add ~/.ssh/id_ed25519
```
Inside the sandbox, check that the forwarded agent exposes the key:
```console
$ ssh-add -L
```
Configure Git globally inside the sandbox to use SSH commit signing. This
writes to the sandbox user's Git config, not your repository's `.git/config`.
Use an inline public key instead of a key file path, because host paths such as
`~/.ssh/id_ed25519.pub` might not exist in the sandbox:
```console
$ git config --global gpg.format ssh
$ git config --global user.signingkey "key::$(ssh-add -L | head -n 1)"
```
Then commit as usual:
```console
$ git commit -S
```
For common signing failures, see
[Sandbox commits aren't signed](troubleshooting.md#sandbox-commits-arent-signed).
See [Host worktree](workflows.md#host-worktree) in Workflow patterns.
## Reconnecting and naming
+303
View File
@@ -0,0 +1,303 @@
---
title: Workflow patterns
linkTitle: Workflows
weight: 30
description: Common workflow patterns for Docker Sandboxes, covering git strategies, authenticated tools, commit signing, and CI integration.
keywords: docker sandboxes, sbx, workflows, clone mode, git, branches, commit signing, github cli, ci, headless
---
## Git workflows
Sandboxes support three approaches for working with Git repositories. The
right choice depends on whether you want branch isolation and whether you
plan to run tasks in parallel:
| | Direct mode | Clone mode (`--clone`) | Host worktree |
| ------------------------- | ---------------- | ---------------------------- | ----------------------------- |
| Branch management | You, on the host | Agent, inside the clone | You, on the host |
| Changes visible on host | Immediately | After fetch or agent push | Immediately |
| Agent can use Git | Yes | Yes | No |
| Parallelism | No | Multiple agents, one sandbox | One sandbox per parallel task |
| Mode fixed at create time | No | Yes | — |
### Direct mode
The simplest approach. The sandbox mounts your host working tree directly —
the agent edits files in place and changes appear immediately. You manage
branches yourself.
1. Check out the branch you want to work on:
```console
$ git checkout -b feat/my-feature
```
2. Start the sandbox. No special flags needed:
```console
$ sbx run claude
```
3. The agent edits files in your working tree. Review diffs, stage, and
commit as you normally would:
```console
$ git diff
$ git add -p
$ git commit
$ git push -u origin feat/my-feature
```
Because the sandbox mounts your working tree, switching branches on the host
also changes what the agent sees. This makes direct mode well-suited for
focused, single-branch work where you're collaborating with the agent
turn-by-turn.
### Clone mode
In clone mode, the sandbox gets a private Git clone. The agent manages its
own branches and commits inside that clone; your host working tree is never
touched. When the agent is done, you either fetch its branches to the host or
ask the agent to push directly to your fork.
Clone mode is designed for parallelism: a single clone-mode sandbox can hold
many branches at once, and subagent orchestrators (such as Claude Code's
[agents view](agents/claude-code.md#agents-view)) can dispatch independent
tasks to separate agents, each working on its own branch or worktree inside
the clone.
> [!NOTE]
> `--clone` is a create-time flag and cannot be changed on an existing
> sandbox. If you need to run additional non-clone sandboxes for the same
> repository, you would have to remove the clone-mode sandbox first.
> Keep a clone-mode sandbox running across multiple tasks rather than
> recreating it per task.
#### Single task
1. Start a clone-mode sandbox:
```console
$ sbx run --clone claude
```
2. Ask the agent to create a branch before it starts editing:
> Create a branch `feat/my-feature` and make the changes.
3. Fetch the agent's branch when it's done:
```console
$ git fetch sandbox-<name>
$ git log sandbox-<name>/feat/my-feature
$ git diff main..sandbox-<name>/feat/my-feature
```
4. Pull the branch to the host and push, or ask the agent to push directly:
```console
# Pull to host, then push
$ git checkout -b feat/my-feature sandbox-<name>/feat/my-feature
$ git push -u origin feat/my-feature
$ gh pr create
# Or ask the agent
# "Push feat/my-feature to origin and open a PR."
```
#### Parallel tasks
1. Start a clone-mode sandbox and open the
[agents view](agents/claude-code.md#agents-view):
```console
$ sbx run --clone claude
```
2. Dispatch each independent task to a separate subagent. Claude Code handles
branch isolation for subagents automatically in agents view. For other
agents (such as Codex), add an instruction to `AGENTS.md` to get the same
behavior:
```markdown
Always start each task on a new git branch before making changes.
```
3. Fetch all branches when the agents are done:
```console
$ git fetch sandbox-<name>
$ git log sandbox-<name>/feat/task-a
$ git log sandbox-<name>/feat/task-b
```
4. Check out the branches you want to keep and open PRs as normal.
### Host worktree
You can create a Git worktree on your host and point the sandbox at it. The
agent edits files directly in the worktree — but because the sandbox mounts
only the worktree directory (not the parent repository), it can't resolve the
`.git` pointer file and has no Git access. The agent can read and write files,
but can't commit, branch, or check status.
This is useful when you want branch isolation without the create-time
commitment of clone mode, and you're comfortable committing from the host
yourself after reviewing the changes.
1. Create the worktree on the host:
```console
$ git worktree add -b feat/my-feature ../my-feature-work
```
2. Start the sandbox with the worktree as the workspace:
```console
$ sbx run claude ../my-feature-work
```
3. The agent edits files. When it's done, commit and push from the host:
```console
$ cd ../my-feature-work
$ git diff
$ git add -p && git commit
$ git push -u origin feat/my-feature
$ gh pr create
```
## Commit signing
Sandboxes forward your host SSH agent into the sandbox, so the agent can
sign commits with your SSH key without the private key ever leaving your
host.
1. On your host, make sure the signing key is loaded in your SSH agent:
```console
$ ssh-add ~/.ssh/id_ed25519
$ ssh-add -L # confirm the key appears
```
2. Inside the sandbox, configure Git to sign with SSH. Use the forwarded key
directly rather than a file path, since host paths don't exist inside the
sandbox:
```console
$ git config --global gpg.format ssh
$ git config --global user.signingkey "key::$(ssh-add -L | head -n 1)"
```
3. Sign commits as usual:
```console
$ git commit -S -m "feat: my change"
```
To apply this configuration automatically to every sandbox, use the
[`git-ssh-sign`](https://github.com/docker/sbx-kits-contrib/tree/main/git-ssh-sign)
community kit, which handles all of the above setup. See [Kits](customize/kits.md)
if you want to package it alongside other sandbox customizations.
For troubleshooting, see
[Sandbox commits aren't signed](troubleshooting.md#sandbox-commits-arent-signed).
## Authenticated CLI tools
The sandbox proxy handles API credentials for model providers automatically,
but agents often also need credentials for tools like `gh`, `docker`, or a
secrets manager. The pattern is the same in each case: configure the
credential on your host once, and the sandbox either forwards it via the
proxy or via SSH agent forwarding.
> [!NOTE]
> The `-g` flag stores a secret globally so all future sandboxes can use it.
> Sandboxes that already exist when you run `sbx secret set -g` do not
> receive the new value. To update a running sandbox, scope the secret to
> it directly: `sbx secret set <sandbox-name> <service>`.
### GitHub CLI
Store your GitHub token as a sandbox secret. The proxy injects it into
outbound requests, so `gh` works inside the sandbox without any additional
configuration:
```console
$ echo "$(gh auth token)" | sbx secret set -g github
```
The agent can then create pull requests, open issues, comment on PRs, and
interact with the GitHub API the same way it would from your host:
```console
# Inside the sandbox
$ gh pr create --title "feat: my feature" --body "..."
$ gh issue list
```
The token is never stored in plaintext inside the sandbox. See
[GitHub token](security/credentials.md#github-token) for details.
### Docker registry
To let the agent push images it builds to a private registry, store registry
credentials on your host. The agent can then run `docker build` and
`docker push` without any extra authentication:
```console
$ gh auth token | sbx secret set --registry ghcr.io \
--username <github-username> --password-stdin
$ echo "$ACR_PASSWORD" | sbx secret set --registry myregistry.azurecr.io \
--username myuser --password-stdin
```
Images and containers built inside the sandbox run on the sandbox's private
Docker daemon, not your host's. They're deleted when the sandbox is removed.
See [Registry credentials](security/credentials.md#registry-credentials) for
the full reference.
### Sourcing credentials from 1Password
If you store credentials in 1Password, use `op read` to populate `sbx` secrets
without pasting values manually:
```console
$ op read "op://Work/GitHub/token" | sbx secret set -g github
$ op read "op://Work/Anthropic/credential" | sbx secret set -g anthropic
```
The real value stays on your host; the sandbox sees the proxy-managed
placeholder as usual.
## CI and headless use
For CI environments and scripts where a browser isn't available, authenticate
with a Docker Personal Access Token (PAT):
```console
$ echo "$DOCKER_PAT" | sbx login --username <your-docker-id> --password-stdin
```
Generate a PAT from your
[Docker account settings](https://app.docker.com/settings/personal-access-tokens)
with at least **Read** scope.
From there, the rest of the `sbx` workflow is the same as interactive use.
Create the sandbox in the background with `sbx create`, run agent tasks with
`sbx exec`, and clean up with `sbx rm`:
```console
$ sbx create --name ci-task --clone claude
$ sbx run ci-task # attach and give instructions, or use sbx exec for one-off commands
$ git fetch sandbox-ci-task
$ sbx rm ci-task
```
Agent credentials (API keys, GitHub token) can be pre-configured as global
secrets so they're available to any sandbox the CI runner creates:
```console
$ echo "$ANTHROPIC_API_KEY" | sbx secret set -g anthropic
$ echo "$GITHUB_TOKEN" | sbx secret set -g github
```