Skip to main content

openclaw-awd-arena

Deploy and run automated Attack-with-Defense (AWD) competitions where LLM-powered agents compete in real-time cybersecurity challenges

Jump to install

Source facts

Repository
reason-machines/hermes-skills
Last source activity
May 17, 2026 at 14:54
Detected SKILL.md language
English
Stars
5
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
openclaw-awd-arena
description
Deploy and run automated Attack-with-Defense (AWD) competitions where LLM-powered agents compete in real-time cybersecurity challenges
triggers
["set up an AWD competition with AI agents","configure OpenClaw arena for agent battles","create an attack-defense competition platform","deploy automated security competition arena","run LLM-powered CTF competition","build AI agent cybersecurity arena","configure OpenClaw AWD match settings","troubleshoot OpenClaw arena deployment"]
# OpenClaw AWD Arena Skill > Skill by [ara.so](https://ara.so) — Hermes Skills collection. OpenClaw AWD Arena is an automated Attack-with-Defense (AWD) platform where LLM-powered agents compete in real-time cybersecurity challenges. The platform manages the entire competition lifecycle: spawning isolated Docker containers for each agent, deploying vulnerable target machines, orchestrating defense and attack phases, calculating scores, and providing a real-time spectator dashboard. ## Core Architecture The platform consists of: - **Frontend (React)**: Web UI for match configuration, template management, and live spectating - **Referee Engine (FastAPI)**: Backend core that manages match flow, scoring, and agent state monitoring - **Round Orchestrator**: Module within the Referee that dynamically creates/destroys Docker containers for each match - **Agent Containers**: Individual Docker containers running AI agents (default: `alpine/openclaw:latest`) - **Target Machines**: Vulnerable service containers (default: `openclaw/ctf-target:v1`) with flags to capture ## Installation ### Prerequisites Ensure Docker and Docker Compose are installed with at least 4 CPU cores and 8GB RAM allocated. ### Deploy the Platform ```bash # Clone the repository git clone https://github.com/LYiHub/OpenClaw-AWD-Arena.git cd OpenClaw-AWD-Arena # Build the target machine image cd target-image/ctf docker build -t openclaw/ctf-target:v1 . cd ../../ # Start core services (Frontend + Referee Engine) docker-compose up -d --build # Verify services are running docker-compose ps ``` After deployment: - **Referee Engine**: http://localhost:8000 - **Frontend**: http://localhost:80 (or localhost if using Nginx proxy) ### Security Configuration (Optional) For production or shared environments, enable API key authentication: ```yaml # docker-compose.yml services: referee: environment: - REFEREE_API_KEY=${REFEREE_API_KEY} ``` ```bash # Set the API key in your environment export REFEREE_API_KEY="your-secure-api-key" docker-compose up -d ``` ## Configuration ### Match Configuration Structure Matches are configured through the frontend or via API with the following structure: ```python # Example match configuration payload match_config = { "match_duration": 3600, # Total match time in seconds (1 hour) "defense_phase_duration": 900, # Defense phase time in seconds (15 minutes) "llm_provider": "anthropic", # or "openai" "llm_base_url": "https://api.anthropic.com", "llm_api_key": None, # Global API key (optional if per-agent keys provided) "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229", "api_key": None # Individual agent API key (overrides global if set) }, { "agent_id": "agent_2", "model": "gpt-4-turbo", "api_key": None }, { "agent_id": "agent_3", "model": "claude-3-sonnet-20240229", "api_key": None }, { "agent_id": "agent_4", "model": "gpt-4", "api_key": None } ], "target_image": "openclaw/ctf-target:v1", "agent_image": "alpine/openclaw:latest" } ``` ### Environment Variables Reference environment variables for sensitive configuration: ```python import os # LLM Configuration llm_config = { "provider": os.environ.get("OPENCLAW_LLM_PROVIDER", "anthropic"), "api_key": os.environ.get("OPENCLAW_LLM_API_KEY"), "base_url": os.environ.get("OPENCLAW_LLM_BASE_URL", "https://api.anthropic.com") } # Referee API Key referee_api_key = os.environ.get("REFEREE_API_KEY") ``` ## Core API Usage ### Health Check ```python import requests # Verify referee engine is running response = requests.get("http://localhost:8000/health") print(response.json()) # Expected: {"status": "ok"} ``` ### Start a Match ```python import requests import os headers = {} # Include API key if authentication is enabled if os.environ.get("REFEREE_API_KEY"): headers["X-API-Key"] = os.environ["REFEREE_API_KEY"] match_config = { "match_duration": 1800, "defense_phase_duration": 600, "llm_provider": "anthropic", "llm_base_url": "https://api.anthropic.com", "llm_api_key": os.environ.get("ANTHROPIC_API_KEY"), "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229" }, { "agent_id": "agent_2", "model": "claude-3-sonnet-20240229" } ] } response = requests.post( "http://localhost:8000/api/matches/start", json=match_config, headers=headers ) match_data = response.json() match_id = match_data["match_id"] print(f"Match started: {match_id}") ``` ### Monitor Match Status ```python import requests import time def monitor_match(match_id, api_key=None): headers = {"X-API-Key": api_key} if api_key else {} while True: response = requests.get( f"http://localhost:8000/api/matches/{match_id}/status", headers=headers ) status = response.json() print(f"Phase: {status['phase']}") print(f"Time remaining: {status['time_remaining']}s") print(f"Scoreboard: {status['scoreboard']}") if status['phase'] == 'finished': print("Match completed!") break time.sleep(10) # Usage monitor_match(match_id, os.environ.get("REFEREE_API_KEY")) ``` ### Stop a Match ```python import requests import os headers = {} if os.environ.get("REFEREE_API_KEY"): headers["X-API-Key"] = os.environ["REFEREE_API_KEY"] response = requests.post( f"http://localhost:8000/api/matches/{match_id}/stop", headers=headers ) print(response.json()) # {"status": "stopped", "match_id": "..."} ``` ## Custom Target Machine Creation ### Build a Custom Target ```dockerfile # custom-target/Dockerfile FROM ubuntu:22.04 # Install vulnerable services RUN apt-get update && apt-get install -y \ apache2 \ php \ mysql-server \ openssh-server # Copy vulnerable web application COPY ./webapp /var/www/html/ # Setup flag management COPY ./flag-service /opt/flag-service RUN chmod +x /opt/flag-service/refresh-flags.sh # Expose services EXPOSE 80 22 3306 # Start services CMD ["/opt/flag-service/start.sh"] ``` ```bash # Build and use custom target docker build -t openclaw/custom-target:v1 ./custom-target # Update match configuration to use custom target # In match_config: # "target_image": "openclaw/custom-target:v1" ``` ### Flag Management Script Example ```python # flag-service/refresh-flags.py import os import time import secrets FLAG_DIR = "/var/flags" REFRESH_INTERVAL = 300 # 5 minutes def generate_flag(): return f"FLAG{{{secrets.token_hex(16)}}}" def refresh_flags(): os.makedirs(FLAG_DIR, exist_ok=True) services = ["web", "ssh", "database"] for service in services: flag = generate_flag() flag_path = os.path.join(FLAG_DIR, f"{service}.flag") with open(flag_path, "w") as f: f.write(flag) os.chmod(flag_path, 0o644) print(f"Refreshed {service} flag: {flag}") if __name__ == "__main__": while True: refresh_flags() time.sleep(REFRESH_INTERVAL) ``` ## Custom Agent Development ### Agent Gateway Interface Agents communicate with the referee engine through a standardized protocol: ```python # agent/main.py import os import requests import json from anthropic import Anthropic class AWDAgent: def __init__(self): self.referee_url = os.environ.get("REFEREE_URL") self.agent_id = os.environ.get("AGENT_ID") self.api_key = os.environ.get("LLM_API_KEY") self.model = os.environ.get("LLM_MODEL") self.client = Anthropic(api_key=self.api_key) def register(self): """Signal READY status to referee""" requests.post( f"{self.referee_url}/agent/{self.agent_id}/ready", json={"status": "READY"} ) def get_phase(self): """Get current match phase""" response = requests.get( f"{self.referee_url}/agent/{self.agent_id}/phase" ) return response.json()["phase"] def defend(self, target_info): """Defense phase logic""" prompt = f"""You are defending a target machine with the following services: {json.dumps(target_info, indent=2)} Identify vulnerabilities and provide hardening commands.""" message = self.client.messages.create( model=self.model, max_tokens=2048, messages=[{"role": "user", "content": prompt}] ) return message.content[0].text def attack(self, targets): """Attack phase logic""" prompt = f"""You are attacking the following targets to capture flags: {json.dumps(targets, indent=2)} Generate exploit commands to capture flags.""" message = self.client.messages.create( model=self.model, max_tokens=2048, messages=[{"role": "user", "content": prompt}] ) return message.content[0].text def submit_flag(self, flag): """Submit captured flag""" response = requests.post( f"{self.referee_url}/agent/{self.agent_id}/submit", json={"flag": flag} ) return response.json() def run(self): self.register() while True: phase = self.get_phase() if phase == "defense": target_info = self.get_target_info() actions = self.defend(target_info) self.execute_commands(actions) elif phase == "attack": targets = self.get_targets() exploits = self.attack(targets) flags = self.execute_exploits(exploits) for flag in flags: result = self.submit_flag(flag) print(f"Flag submission: {result}") elif phase == "finished": break time.sleep(10) if __name__ == "__main__": agent = AWDAgent() agent.run() ``` ### Custom Agent Dockerfile ```dockerfile # agent/Dockerfile FROM python:3.11-alpine WORKDIR /app # Install dependencies RUN apk add --no-cache \ nmap \ curl \ netcat-openbsd \ git # Install Python packages COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy agent code COPY main.py . CMD ["python", "main.py"] ``` ## Troubleshooting ### Agent Not Returning READY **Symptom**: Match stuck waiting for agents to be ready. **Solution**: Check LLM API connectivity from within agent container. ```bash # Get agent container ID docker ps | grep agent_ # Exec into agent container docker exec -it <container_id> sh # Test API connectivity curl -v https://api.anthropic.com/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "content-type: application/json" \
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub