This is the practical setup guide. If you want to understand how the broker works under the hood, read the technical deep dive first.
#Enabling the broker
Two ways to get Docker access inside your copilot_here sandbox:
#One-shot flag
Pass --dind to enable the broker for a single session:
The broker starts, creates a socket, mounts it into the container, and tears it down when the session ends. Nothing is persisted.
#Persistent config
Enable the broker for a project so it activates on every run:
This creates .copilot_here/docker-broker.json in your project directory with default settings. From now on, every copilot_here run in this directory starts the broker automatically. No --dind flag needed.
To disable it later:
#Adding allowed images
By default, the image allowlist is empty. That means no containers can be spawned until you explicitly add patterns. You decide what the agent is allowed to pull and run.
#Pattern syntax
Patterns use glob matching where * matches any sequence of characters (including / and :):
| Pattern | Matches | Doesn't match |
|---|---|---|
postgres:16* | postgres:16, postgres:16.2, postgres:16-alpine | postgres:15, postgres:latest |
mcr.microsoft.com/mssql/server:* | Any tag of that image | Other registries |
redis:* | Any Redis tag | bitnami/redis:latest |
Keep patterns as specific as possible. postgres:16* is better than postgres:* which is better than *:*. The broader the pattern, the weaker the allowlist.
To remove a pattern:
#Privilege controls
By default, the broker rejects containers that request privileged mode. Some test frameworks or Docker-in-Docker setups need it. You can opt in per-project:
There are also global variants that apply across all projects:
Local settings override global settings.
The privilege toggle only controls HostConfig.Privileged. The broker has four other safety checks that remain active regardless:
- Host namespace rejection — blocks
NetworkMode,PidMode,IpcMode,UsernsModeset to"host" - Forbidden bind mounts — blocks mounts targeting
/etc,/root,/var,/usr,/bin,/sbin,/proc,/sys, and the Docker socket - Dangerous capabilities — blocks
SYS_ADMIN,SYS_MODULE,SYS_PTRACE,NET_ADMIN, and others - Image allowlist — still applies regardless of privilege settings
#Config file deep dive
The broker configuration is a JSON file. Here's a fully annotated example:
#Field reference
| Field | Default | Purpose |
|---|---|---|
enabled | false | Whether the broker activates automatically (without --dind) |
inherit_default_rules | true | Merge with the 65 built-in endpoint rules. Set to false to use only your custom endpoints |
mode | "enforce" | "enforce" blocks disallowed requests. "monitor" logs but forwards everything |
enable_logging | false | Write decisions to ~/.copilot_here/logs/docker-broker.jsonl |
body_inspection.reject_privileged | true | Block Privileged: true |
body_inspection.reject_host_namespaces | true | Block NetworkMode/PidMode/IpcMode/UsernsMode: "host" |
body_inspection.reject_forbidden_binds | true | Block mounts to sensitive host paths |
body_inspection.reject_dangerous_capabilities | true | Block dangerous Linux capabilities |
body_inspection.allowed_images | [] | Glob patterns for allowed container images |
allowed_endpoints | [] | Custom endpoint rules (merged with defaults if inherit_default_rules is true) |
#Config resolution order
- Local —
.copilot_here/docker-broker.jsonin the project directory - Global —
~/.config/copilot_here/docker-broker.json - Embedded defaults — compiled into the binary (65 endpoint rules, all safety checks enabled, empty image list)
Local overrides global, global overrides embedded. When inherit_default_rules is true, your custom endpoints merge with the defaults. You only need to add new ones or override existing ones.
#Using with Airlock
DinD and Airlock can work together. When combined, the setup changes:
- The proxy container runs a
socatbridge that forwards Docker API calls to the host broker - The app container's
DOCKER_HOSTpoints attcp://proxy:2375instead of a Unix socket - Sibling containers spawned by the agent get their
NetworkModerewritten to join the airlock network - Siblings are reachable via Docker DNS and network-isolated. They can't bypass the proxy
If you're already using Airlock, adding --dind (or enabling the broker in config) is all you need. The compose template handles the rest automatically.
Known limitation: Testcontainers and similar frameworks that connect to siblings via host-mapped ports (e.g., host.docker.internal:32768) won't work in airlock mode yet (#101). The airlock's internal: true network blocks those connections. Use --dind without airlock as a workaround. The broker still enforces all API rules, you just lose the HTTP proxy network isolation.
#Viewing and editing rules
--show-docker-broker-rules outputs the fully resolved configuration after merging all layers, so you can verify what's actually active.
#Common patterns
#Testcontainers with .NET
Testcontainers needs Ryuk (its resource reaper) plus whatever database images your tests use. Set up once with persistent config, then your normal interactive sessions have Docker access:
The agent can run your integration tests during the conversation and Testcontainers will work. You can also verify the setup with a one-shot: copilot_here --dind --dotnet -p "run the integration tests".
#Postgres for integration tests
If you don't want persistent config, use --dind for a one-off session:
#Multiple services
Some test suites need several containers. Add each image you need:
#Monitor mode
If you want to see what Docker calls the agent makes before enforcing rules:
This logs every decision to ~/.copilot_here/logs/docker-broker.jsonl but forwards all requests. Good for understanding what your test suite actually needs before locking it down.
#Wrapping up
The brokered Docker socket is currently in beta. The defaults are conservative: empty image list, all safety checks on, enforce mode. Start with the minimum set of images your workflow needs and expand from there.
For the technical details on how the broker intercepts and inspects requests, read the deep dive post. For the quick overview, check the copilot_here site.
![]()
Gordon Beeming
Father • Husband • Triathlete • SSW Solution Architect
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.