services: vulnerable-server: build: ./vulnerable-server networks: [lab-net] ports: - "127.0.0.1:5050:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 secure-server: build: ./secure-server networks: [lab-net] ports: - "127.0.0.1:5053:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 xss-server: build: ./xss-server networks: [lab-net] ports: - "127.0.0.1:5051:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 access-control-server: build: ./access-control-server networks: [lab-net] ports: - "127.0.0.1:5052:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 misconfig-server: build: ./misconfig-server networks: [lab-net] ports: - "127.0.0.1:5054:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 auth-server: build: ./auth-server networks: [lab-net] ports: - "127.0.0.1:5055:5000" environment: FLASK_ENV: development HOST: 0.0.0.0 PORT: 5000 healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/health', timeout=2)"] interval: 5s timeout: 3s retries: 10 scanner-agent: build: ./scanner-agent networks: [lab-net] depends_on: vulnerable-server: condition: service_healthy environment: TARGET_URL: http://vulnerable-server:5000 SCAN_PROFILE: sql ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan - scan-sql scanner-agent-secure-sql: build: ./scanner-agent networks: [lab-net] depends_on: secure-server: condition: service_healthy environment: TARGET_URL: http://secure-server:5000 SCAN_PROFILE: sql ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan-secure-sql scanner-agent-xss: build: ./scanner-agent networks: [lab-net] depends_on: xss-server: condition: service_healthy environment: TARGET_URL: http://xss-server:5000 SCAN_PROFILE: xss ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan-xss scanner-agent-access-control: build: ./scanner-agent networks: [lab-net] depends_on: access-control-server: condition: service_healthy environment: TARGET_URL: http://access-control-server:5000 SCAN_PROFILE: access-control ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan-access-control scanner-agent-misconfig: build: ./scanner-agent networks: [lab-net] depends_on: misconfig-server: condition: service_healthy environment: TARGET_URL: http://misconfig-server:5000 SCAN_PROFILE: misconfig ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan-misconfig scanner-agent-auth: build: ./scanner-agent networks: [lab-net] depends_on: auth-server: condition: service_healthy environment: TARGET_URL: http://auth-server:5000 SCAN_PROFILE: auth ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 profiles: - scan-auth scanner-agent-llm: build: ./scanner-agent networks: [lab-net, llm-egress-net] depends_on: vulnerable-server: condition: service_healthy environment: TARGET_URL: ${LLM_TARGET_URL:-http://vulnerable-server:5000} SCAN_LLM: "true" SCAN_LLM_MAX_PROBES: ${SCAN_LLM_MAX_PROBES:-30} SCAN_LLM_MAX_ITERS: ${SCAN_LLM_MAX_ITERS:-12} OPENAI_BASE_URL: ${OPENAI_BASE_URL:-http://host.docker.internal:3001/api/build-nvidia/v1} OPENAI_API_KEY: ${OPENAI_API_KEY:-not-needed} LLM_MODEL: ${LLM_MODEL:-moonshotai/kimi-k2-instruct} ALLOWED_TARGET_HOSTS: vulnerable-server,secure-server,xss-server,access-control-server,misconfig-server,auth-server,localhost,127.0.0.1,::1 extra_hosts: - "host.docker.internal:host-gateway" profiles: - scan-llm networks: lab-net: internal: true # Non-internal egress network used ONLY by scanner-agent-llm so it can # reach the host-side toolkit LLM proxy (host.docker.internal:3001). # Lab servers are NOT attached to this network. llm-egress-net: driver: bridge