a2a-wrapper logoa2a-wrapper
Guides

Security guide

Deploy a2a-wrapper agents safely: network exposure, permission and sandbox modes, workspace hygiene, and a pre-flight checklist.

This page is generated from docs/security.md and stays in sync with the repository.

An a2a-* wrapper turns a coding agent — one that can read files, edit files and often run shell commands — into an HTTP service. Treat it like exposing a shell, not like exposing a chatbot. This page describes what the wrappers do and do not protect you from, so you can deploy them safely.

Found a vulnerability? Please report it privately — see SECURITY.md.

The short version

  1. The A2A endpoint has no built-in authentication. The server is built with UserBuilder.noAuthentication (see packages/core/src/server/factory.ts). Anyone who can reach the port can send the agent tasks.
  2. The default bind address is 0.0.0.0 (all interfaces). Change it unless you mean to expose the agent.
  3. Put the agent in a workspace you can afford to lose — a scratch clone, a container, or a VM — and keep secrets out of it.
  4. Use the narrowest permission / sandbox mode that still does the job.

1. Network exposure

SituationDo this
Local development, agents only talk to each other on one machineSet "server": { "hostname": "127.0.0.1" } in the agent config
Agents on different hostsKeep the agent on a private network and put a reverse proxy in front that enforces authentication (bearer token, mTLS, or your SSO) and TLS
Public internetDon't expose the agent directly. If you must, authenticate at a gateway first

server.hostname controls the bind address. server.advertiseHost / advertiseProtocol only change the URLs written into the agent card; they do not restrict who can connect.

Outbound calls are a separate matter: when a wrapper calls another A2A agent (sub-agents), you can attach headers such as Authorization: Bearer ${TOKEN} from the environment. Keep tokens in environment variables, not in config files.

2. What the agent is allowed to do

Each wrapper has its own guardrails. They limit what the backend may do inside the workspace; they are not a substitute for network controls.

WrapperControlSafe choiceDangerous choice
a2a-claudeclaude.permissionModeplan (read-only), or the default acceptEditsbypassPermissions (needs dangerouslyAllowBypassPermissions: true; logs a warning at startup). default and auto are rejected because headless runs can't prompt a human
a2a-codexcodex.sandboxModeread-only, or workspace-write with networkAccessEnabled: falsedanger-full-access
a2a-copilotBackend tool permissionsRun in a container with a scratch workspaceMounting your home directory or real credentials
a2a-opencode--auto-approve / AUTO_APPROVE (on by default)--no-auto-approve where a human can approve, otherwise a container with a scratch workspaceLeaving auto-approve on with a real workspace and a network-reachable port
a2a-antigravitypolicies (see "Command Policy and run_command" in its README)Keep run_command disabled unless the workspace is trustedEnabling run_command on untrusted input

See each package README for the exact options.

3. Workspace and secrets hygiene

  • Point WORKSPACE_DIR at a dedicated checkout, not at ~ and not at a repo holding production credentials.
  • Never store credentials in config files. Use ${ENV_VAR} placeholders, as the shipped examples do.
  • Assume prompt injection. An agent reading untrusted files, web pages or issue text can be steered by that content. Combined with shell access, this is the main real-world risk. Don't point an agent with write access at untrusted input and then let it touch anything valuable.
  • Keep your own API keys private. Anyone who can reach an unauthenticated agent spends your model quota.
  • Prefer containers. Most wrappers ship a Dockerfile; run them with a read-only root filesystem where possible and mount only the workspace.

4. Multi-agent setups

In a planner → implementer → tester chain, each agent is another entry point. Give every agent its own workspace or branch, bind them all to loopback or a private network, and remember that an injected instruction in one agent's output becomes input to the next.

Checklist before you expose an agent

  • Bound to 127.0.0.1 or behind an authenticating proxy
  • Runs in a container or disposable workspace
  • Narrowest permission / sandbox mode that works
  • No secrets in the workspace or config files
  • Model-provider key has a spending limit

On this page