Repository navigation
Expand file tree
/
Copy pathdocker-compose.example.yml
More file actions
114 lines (108 loc) · 4.56 KB
/
Copy pathdocker-compose.example.yml
File metadata and controls
114 lines (108 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# doubleagent - AI safety proxy sidecar
#
# Network isolation model:
# - "agent_net" is an internal Docker network with NO internet access.
# - The AI container is connected ONLY to agent_net — even if it ignores
# HTTP_PROXY, opens raw sockets, or unsets env vars, packets have nowhere
# to go because there is no gateway to the outside world.
# - doubleagent is connected to BOTH agent_net and the default bridge,
# so it can receive requests from the AI and forward them to the internet.
# - playwright-mcp is also connected to BOTH networks, so the AI can reach
# it over agent_net while the MCP server itself can still browse the web.
#
# Accessing the AI agent's web UI:
# - Since the AI container is on an internal-only network, it cannot publish
# ports to the host. Instead, doubleagent acts as a reverse proxy: it
# publishes a port on the host and forwards traffic to the AI container
# over agent_net. Configure "forward_ports" in config.json to set this up.
#
# Security note:
# - This setup reduces direct secret exposure and blocks unwanted outbound
# requests from the AI container, but it is not a perfect sandbox.
# - If you give the AI access to tools like playwright-mcp that themselves
# have internet access, the AI may still be able to leak information
# through those tools.
#
# This makes enforcement mandatory at the network topology level rather than
# relying on the AI container to cooperate via HTTP_PROXY conventions.
services:
doubleagent:
build: .
networks:
- default
- agent_net
ports:
# Forward port for the AI agent's web UI (configured in config.json
# via forward_ports). Doubleagent relays TCP traffic from the host to
# the agent over agent_net, since the agent cannot publish ports itself.
- "3000:3000"
volumes:
- certs:/certs
- ./config.json:/config/config.json:ro
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
secrets:
- github_token
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9000/healthz"]
interval: 5s
timeout: 3s
start_period: 10s
retries: 3
restart: unless-stopped
ai-agent:
image: my-ai-agent:latest
networks:
- agent_net # only internal — no internet access
depends_on:
doubleagent:
condition: service_healthy
volumes:
- certs:/certs:ro
# If the agent needs the CA in the system trust store, override the entrypoint.
# install-ca.sh is published into the certs volume automatically by doubleagent.
# It installs the CA into the OS trust store AND sets certificate env vars
# (NODE_EXTRA_CA_CERTS, REQUESTS_CA_BUNDLE, SSL_CERT_FILE, etc.) so you
# don't need to list them here. The vars are also persisted to
# /etc/environment and /etc/profile.d/ for non-root processes.
# entrypoint: ["/bin/sh", "-c", ". /certs/install-ca.sh && exec your-original-entrypoint"]
environment:
- OPENAI_API_KEY=PLACEHOLDER_OPENAI_KEY
- ANTHROPIC_API_KEY=PLACEHOLDER_ANTHROPIC_KEY
- GITHUB_TOKEN=PLACEHOLDER_GITHUB_TOKEN
# The proxy env vars tell well-behaved HTTP clients where to go.
# Even if the agent ignores them, agent_net has no internet route.
- HTTP_PROXY=http://doubleagent:8080
- HTTPS_PROXY=http://doubleagent:8080
- NO_PROXY=localhost,127.0.0.1,doubleagent,playwright-mcp
# Node.js built-in HTTP clients need this to honor the proxy env vars.
- NODE_USE_ENV_PROXY=1
# Node.js can also trust certs installed into the OS trust store.
- NODE_USE_SYSTEM_CA=1
# Example local MCP endpoint reachable by the AI over agent_net.
- PLAYWRIGHT_MCP_URL=http://playwright-mcp:8931
playwright-mcp:
image: my-playwright-mcp:latest
networks:
- default # internet access for browser automation
- agent_net # reachable by ai-agent at http://playwright-mcp:8931
expose:
- "8931"
networks:
default:
# Standard Docker bridge — has internet access.
driver: bridge
agent_net:
# Internal network — Docker does not create a gateway or NAT rules,
# so containers on this network cannot reach the internet directly.
driver: bridge
internal: true
volumes:
certs:
# Docker secrets — files are mounted read-only at /run/secrets/<name> inside
# the container. Use "value_from_file" in config.json to read them.
# See https://docs.docker.com/compose/how-tos/use-secrets/
secrets:
github_token:
environment: GITHUB_TOKEN