Independent AI intelligence Two editions daily · ET
Fervor AI

Analysis · October 8, 2026 · repo

Docker AgentDockeragent-securityagent-infrastructuremulti-agentmcp

Docker Agent Lets You Pull an AI Agent Like an Image. Its Docs Say Not to Trust It Like One

docker/docker-agent ships signing, safety modes and a VM sandbox. The strongest protections are the ones you have to turn on.

docker agent run myorg/agent:tag is one of the most natural-looking commands an agent tool has shipped this year. It reads like docker run, and that is the point. Docker's open-source agent runtime treats an agent the way the container world treats an image: define it in a file, push it to a registry, pull it anywhere.

The interesting part is what the same project's documentation says right next to that convenience. On its permissions page: permissions are enforced client-side, they guard against accidental actions, and they "should not be relied upon as a security boundary for untrusted agents."

That is an unusually honest sentence, and it changes how you should use the tool.

What Docker Agent is

docker/docker-agent is Docker Engineering's builder and runtime for AI agents, licensed Apache-2.0. It runs as a Docker CLI plugin, so the command is docker agent. It ships preinstalled with Docker Desktop 4.63 and later, and Homebrew users can brew install docker-agent.

You describe an agent in YAML: a model, a description, an instruction, and toolsets. Agents can form teams that delegate to each other. Toolsets include built-in think, todo and memory tools, and any MCP server, whether local, remote or containerized. The provider list covers OpenAI, Anthropic, Gemini, AWS Bedrock, Mistral, xAI and Docker Model Runner for local models.

It is busy right now. The repo tagged v1.149.0 on October 7, the same day it appeared on Hacker News, and it sat at #11 on Trendshift's daily board on the morning of October 8 with roughly 4,000 stars by a cache-busted shields.io read.

One small archaeology note: the permissions docs still place global settings at ~/.config/cagent/config.yaml, which looks like a trace of an earlier name. The README does not mention it.

The convenience is the risk

Sharing works through the docker agent share subcommands, per the distribution docs:

docker agent share push ./agent.yaml docker.io/username/my-agent:latest
docker agent share pull docker.io/username/my-agent:latest

You can also skip the pull and run a registry reference directly with docker agent run <reference>.

Think about what that YAML file carries. The instruction is the agent's whole personality and judgment. The toolsets decide what it can touch: a shell, your filesystem, MCP servers that reach your accounts. Pulling an agent from a registry is pulling a stranger's prompt plus a stranger's choice of tools, and then running both with your credentials on your machine.

Container images trained a generation of developers to treat pull and run as routine. Docker Agent borrows that muscle memory on purpose. My position: keep the muscle memory for your own agents, and break it on purpose for anyone else's.

What the project gives you, and what is on by default

The good news is that Docker built real controls. The less good news is which ones are active when you type the short command.

Signing exists, and it is optional. share push --key <key> signs the agent and share pull --key <key> verifies it, refusing the artifact if the check fails. Supported keys include Ed25519, ECDSA and RSA, plus symmetric secrets. The signature covers an in-toto statement in a DSSE envelope that binds the YAML digest to the published reference, registry, repository, tag and creation date. The docs are frank about the limit: "a valid signature proves a key holder published an artifact claiming that metadata, not that the claim is true." They also warn that unsigned manifest annotations can be rewritten by anyone with push access, and that an older signed version under the same tag goes undetected, so pin digests when rollback protection matters.

Safety modes exist, and the default asks. The permissions docs describe four modes. strict prompts for every call, including reads. balanced runs safe calls and asks about the rest. restricted runs safe calls and denies everything else without prompting, which is meant for unattended runs. autonomous runs everything, and the legacy --yolo flag maps to it. A session that never sets a mode gets the historical default: read-only tools run automatically and everything else asks you. You choose with --safety <mode>. One detail to remember: pressing A at a confirmation prompt switches the session to autonomous.

On top of the modes sit allow, ask and deny pattern lists, set per agent or globally. Deny is checked first and a deny from either source wins. Here is the shape from the docs:

permissions:
  allow:
    - "read_*"
  ask:
    - "shell:cmd=git push*"
  deny:
    - "shell:cmd=sudo*"

The catch is in the same page. These rules live in configuration, and a pulled agent brings its own configuration. Agent-level ask: rules are advisory and yield to a user-chosen balanced, restricted or autonomous mode. And then the sentence that matters most: client-side enforcement that should not be relied upon as a security boundary for untrusted agents. For real isolation, the docs point you to sandbox mode.

The sandbox exists, and it is off. The sandbox docs say --sandbox defaults to false. Turned on, agent processes and tools run inside a sandbox VM. Only the current working directory is mounted read-write, config and staged kit are mounted read-only, and other host files are invisible. The network proxy is default-deny; it allows major model providers, and the runner also opens the models gateway, models.dev and the package hosts that auto-install needs. You add hosts with runtime.network_allowlist or docker agent sandbox allow HOST.

That is a serious isolation story. It just is not the one you get from docker agent run myorg/agent:tag.

Put this into practice

If you want to try Docker Agent this week, here is the order I would follow.

1. Start with your own agent. Run docker agent new or write a small YAML file with one model and one toolset, and run it with docker agent run agent.yaml. Learn what the confirmation prompts look like before anyone else's agent is involved.

2. For anything you did not write, pull with a key and read the file. Use docker agent share pull --key <publisher-public-key> <reference>. The pull saves a local YAML file. Open it. Read the instruction and every toolset before the first run. If the publisher offers no key, treat the agent as untrusted, because nothing ties it to them.

3. Pin what you verified. Tags move. The distribution docs say older signed versions under one tag are not detected, and advise pinning digests where rollback protection matters. Record the digest you reviewed, and when you move to a new one, read the YAML again.

4. Run untrusted agents in the sandbox with a narrow mode. docker agent run --sandbox <agent> puts the tools in a VM that sees only your working directory, behind a default-deny network. Add --safety strict while you are watching, or --safety restricted for unattended runs. Run it from a scratch directory, not your home folder or a repo with secrets in it.

5. Make the safe path the easy path. docker agent alias add safe-coder myorg/coder --sandbox bakes the sandbox into a name, so the short command is also the safe one. Teams can set runtime.sandbox: true in YAML they control.

Honest limitations

The sandbox has real requirements. It needs Docker Sandboxes installed and configured, it uses the sbx CLI when present and the docker sandbox plugin otherwise, and the tools available inside depend on the sandbox template. Named sandboxes are reused only for an identical launch configuration, and old ones are never deleted automatically, so they pile up until you clean them with sbx rm --force. Cloud sandboxes stop rather than delete on exit and may keep incurring storage charges. Secret redaction is best-effort, by the docs' own description.

The working directory is still read-write inside the sandbox. An agent that should not touch your repo should not be run from inside it. And the default-deny network still opens the package hosts that auto-install needs, so a toolset that pulls a package at install time still reaches out.

Signing proves a key holder published the agent, not that the agent is good. A signed agent from a careless publisher is still careless, and a prompt-injected instruction inside a signed YAML file is still injected.

I also could not confirm from the docs whether docker agent run <reference> performs any signature verification on its own, which is why the steps above pull with --key first and run the local file. If Docker documents verification on the direct run path, that step gets shorter.

Finally, none of this is a knock on Docker Agent alone. Plenty of agent tooling says far less about where its boundary sits. Docker Agent earns credit for writing it down.

The registry is a supply chain now

Container registries spent a decade learning to sign images, pin digests and scan layers, because docker pull turned out to be a supply chain. Docker Agent brings the same distribution model to agents, and with it the same lesson, arriving faster. An agent is a prompt and a set of permissions, and a registry makes both shareable at the speed of a tag.

Docker gave you the parts: keys, digests, safety modes, a sandbox. The short command does not assemble them for you. Write the alias that does, put it in your team's README, and make the first agent anyone on your team pulls from a stranger run inside a box.

Sources: docker/docker-agent on GitHub, Docker Agent distribution docs, permissions docs, sandbox mode docs, releases feed, Trendshift.


Medium metadata

  • Title: Docker Agent Lets You Pull an AI Agent Like an Image. Its Docs Say Not to Trust It Like One
  • Subtitle: docker/docker-agent ships signing, safety modes and a VM sandbox. The strongest protections are the ones you have to turn on.
  • Tags: Docker, AI Agents, AI Security, Open Source, DevOps
  • Canonical URL: import from the fervorai.dev post
  • Estimated read time: 8 minutes