177 lines
5.8 KiB
YAML
177 lines
5.8 KiB
YAML
version: "3.9"
|
|
|
|
# ThreeGate infrastructure skeleton
|
|
#
|
|
# Notes:
|
|
# - This compose file is intentionally conservative and minimal.
|
|
# - Images are placeholders; pin by digest in production.
|
|
# - Network isolation is part of the security model; do not “simplify” it away.
|
|
# - Egress must be enforced both here (networks) and on the host (DOCKER-USER chain).
|
|
|
|
name: threegate
|
|
|
|
services:
|
|
# ------------------------------------------------------------
|
|
# CORE: analysis & writing (NO INTERNET)
|
|
# ------------------------------------------------------------
|
|
core:
|
|
image: threegate/core:0.1
|
|
container_name: threegate-core
|
|
networks:
|
|
- llmnet
|
|
environment:
|
|
- THREEGATE_ROLE=core
|
|
- NO_PROXY=*
|
|
volumes:
|
|
# Policy is always read-only
|
|
- ../policy:/srv/threegate/policy:ro
|
|
# CORE workspace
|
|
- ./volumes/core-workspace:/srv/threegate/core/workspace
|
|
# One-way inbound: validated packets/results only (mounted ro into CORE)
|
|
- ./volumes/handoff/inbound-to-core:/srv/threegate/handoff/inbound-to-core:ro
|
|
# Optional outbound request drafts (CORE -> human -> fetch/tool-exec)
|
|
- ./volumes/handoff/inbound-to-fetch:/srv/threegate/handoff/inbound-to-fetch
|
|
- ./volumes/tool-exec/requests_in:/srv/threegate/tool-exec/requests_in
|
|
# Optional manual PDF lane (read-only)
|
|
- ./volumes/dropbox/pdfs_in:/srv/threegate/dropbox/pdfs_in:ro
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- rolemesh
|
|
|
|
# ------------------------------------------------------------
|
|
# FETCH: controlled retrieval (INTERNET ONLY VIA PROXY)
|
|
# ------------------------------------------------------------
|
|
fetch:
|
|
image: threegate/fetch:0.1
|
|
container_name: threegate-fetch
|
|
networks:
|
|
- llmnet
|
|
- fetchnet
|
|
environment:
|
|
- THREEGATE_ROLE=fetch
|
|
# Proxy is the only intended egress. Keep both set.
|
|
- http_proxy=http://proxy:3128
|
|
- https_proxy=http://proxy:3128
|
|
- HTTP_PROXY=http://proxy:3128
|
|
- HTTPS_PROXY=http://proxy:3128
|
|
- NO_PROXY=localhost,127.0.0.1,rolemesh,core
|
|
volumes:
|
|
- ../policy:/srv/threegate/policy:ro
|
|
- ./volumes/fetch-workspace:/srv/threegate/fetch/workspace
|
|
# FETCH writes packets here; validator moves accepted packets to inbound-to-core
|
|
- ./volumes/handoff/inbound-to-core:/srv/threegate/handoff/inbound-to-core
|
|
- ./volumes/handoff/quarantine:/srv/threegate/handoff/quarantine
|
|
- ./volumes/handoff/inbound-to-fetch:/srv/threegate/handoff/inbound-to-fetch:ro
|
|
- ./volumes/tools:/srv/threegate/tools:ro
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- proxy
|
|
- rolemesh
|
|
|
|
# ------------------------------------------------------------
|
|
# TOOL-EXEC: execution sandbox coordinator (ERA-backed)
|
|
# Note: This service does NOT need network by default.
|
|
# It orchestrates ERA runs and writes tool results to inbound-to-core.
|
|
# ------------------------------------------------------------
|
|
tool-exec:
|
|
image: threegate/tool-exec:0.1
|
|
container_name: threegate-tool-exec
|
|
networks:
|
|
- llmnet
|
|
environment:
|
|
- THREEGATE_ROLE=tool-exec
|
|
- ERA_BACKEND=ERA
|
|
# Default: forbid guest volumes unless explicitly enabled by operator policy
|
|
- AGENT_ENABLE_GUEST_VOLUMES=0
|
|
- NO_PROXY=*
|
|
volumes:
|
|
- ../policy:/srv/threegate/policy:ro
|
|
- ./volumes/tool-exec/requests_in:/srv/threegate/tool-exec/requests_in:ro
|
|
- ./volumes/tool-exec/results_out:/srv/threegate/tool-exec/results_out
|
|
- ./volumes/handoff/inbound-to-core:/srv/threegate/handoff/inbound-to-core
|
|
- ./volumes/handoff/quarantine:/srv/threegate/handoff/quarantine
|
|
- ./volumes/tools:/srv/threegate/tools:ro
|
|
# ERA integration will usually require host resources (e.g., /dev/kvm)
|
|
# Keep this commented until you implement TOOL-EXEC runner and review risks.
|
|
# - /dev/kvm:/dev/kvm
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- rolemesh
|
|
|
|
# ------------------------------------------------------------
|
|
# PROXY: managed egress (sole internet exit for FETCH)
|
|
# ------------------------------------------------------------
|
|
proxy:
|
|
image: docker.io/library/squid:6
|
|
container_name: threegate-proxy
|
|
networks:
|
|
- fetchnet
|
|
- egressnet
|
|
volumes:
|
|
- ./infra/proxy/squid.conf:/etc/squid/squid.conf:ro
|
|
- ./volumes/proxy-cache:/var/spool/squid
|
|
ports:
|
|
# Expose to host only if you need to debug; otherwise keep internal-only.
|
|
# - "3128:3128"
|
|
restart: unless-stopped
|
|
|
|
# ------------------------------------------------------------
|
|
# LLM Gateway: local / proxied LLM access (OpenAI-compatible)
|
|
# Placeholder for RoleMesh-Gateway; replace with your actual gateway image/config.
|
|
# ------------------------------------------------------------
|
|
rolemesh:
|
|
image: threegate/rolemesh-gateway:0.1
|
|
container_name: threegate-rolemesh
|
|
networks:
|
|
- llmnet
|
|
environment:
|
|
- THREEGATE_ROLE=llm-gateway
|
|
# Typically you will expose this only to other containers on llmnet.
|
|
# ports:
|
|
# - "8080:8080"
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
restart: unless-stopped
|
|
|
|
networks:
|
|
# Internal network: CORE/FETCH/TOOL-EXEC + gateway only
|
|
llmnet:
|
|
driver: bridge
|
|
internal: true
|
|
|
|
# Internal network between FETCH and proxy
|
|
fetchnet:
|
|
driver: bridge
|
|
internal: true
|
|
|
|
# Egress network for proxy only
|
|
egressnet:
|
|
driver: bridge
|
|
internal: false
|