OpenSecOpsEnv2 / README.md
SapphireGaze429's picture
Please work
b595345
|
Raw
History Blame Contribute Delete
15.9 kB
---
title: OpenSecOpsEnv
emoji: πŸ”
colorFrom: blue
colorTo: green
sdk: docker
app_port: 8000
tags:
- openenv
- reinforcement-learning
- secops
- incident-response
- multi-agent
- grpo
- curriculum-learning
---
# πŸ” OpenSecOpsEnv β€” AI Security Engineer That Learns to Beat Cyberattacks
> **A multi-agent adversarial OpenEnv environment where a GRPO-trained Qwen2.5-7B must resolve real production security incidents β€” while a live Attacker agent actively tries to sabotage the investigation with injected false alerts and corrupted metrics.**
[![OpenEnv](https://img.shields.io/badge/OpenEnv-compliant-blue)](https://github.com/openenv/openenv)
[![HF Space](https://img.shields.io/badge/πŸ€—_HF_Space-Live_Demo-orange)](https://huggingface.co/spaces/SapphireGaze429/opensecops-grpo-training)
[![Model](https://img.shields.io/badge/πŸ€—_Trained_Model-Qwen2.5--7B--GRPO-green)](https://huggingface.co/SapphireGaze429/opensecops-qwen2.5-7b-grpo)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-green.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
---
## 🎬 The Problem
Every hour a security incident goes unresolved costs thousands of dollars and puts user data at risk. The on-call engineer gets paged at 3AM and stares at a wall of contradictory alerts:
```
[CRITICAL] cache Β· memory 82% ← FAKE β€” planted by the attacker
[WARNING] db Β· CPU 82% ← real noise
[CRITICAL] auth Β· memory 89% ← real signal
[WARNING] db Β· Outbound to 10.0.0.99 ← THE REAL ATTACK
```
A junior engineer panics and restarts the cache service. The real exfiltration continues for 40 more minutes. **4GB of customer data is gone.**
**Can a language model learn to not make that mistake β€” even under active adversarial sabotage?**
---
## πŸ“Š Results β€” GRPO Training on OpenSecOpsEnv
We fine-tuned **Qwen2.5-7B-Instruct** using **GRPO** for 500 steps on our environment's reward signal.
![Training Results β€” Reward curve, GRPO loss, and Before vs After scores](./training_results.png)
*Left: Per-step reward rises from ~0.10 (random) to stable ~0.20 (trained). Centre: GRPO policy loss rising = gradient actively learning reward differences between candidate actions. Right: Episode scores improve 86–245% across all 4 tasks.*
| Task | Difficulty | Untrained | GRPO-Trained | Improvement |
|------|-----------|-----------|--------------|-------------|
| Memory Leak | Easy | 0.51 | **0.95** | +86% |
| DDoS Cascade | Medium | 0.35 | **0.87** | +149% |
| Bad Deployment | Medium-Hard | 0.31 | **0.81** | +161% |
| **Data Exfiltration** | **Hard** | **0.22** | **0.76** | **+245%** |
> **The hardest task shows the most dramatic improvement.** The untrained model scores 0.22 β€” essentially random. After GRPO, it reaches 0.76: reliably ignoring the attacker's planted false alert, identifying the real exfiltration, and submitting the correct diagnosis.
**Why the reward curve plateaus at ~0.20/step:** Most steps are neutral investigations (+0.0 reward). Terminal rewards (+1.0 correct diagnosis, -1.0 wrong) only fire once per episode. Episode-level score (the table above) is the right metric β€” and it shows 2–4Γ— improvement across every difficulty level.
**Why the loss curve rises:** In GRPO, rising policy loss means the gradient is active β€” the model is differentiating between candidate action sequences and updating weights based on environment feedback. This is the expected healthy training signature.
---
## πŸ—οΈ Environment Architecture
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ OpenSecOpsEnv β”‚
β”‚ β”‚
β”‚ Production Microservices (Partially Observable) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ gateway │──▢│ api │──▢│ cache │──▢│ db β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ └──────────────────────────▢ auth β”‚
β”‚ β”‚
β”‚ πŸ”΄ Red Agent (Attacker) β€” adaptive adversarial (theory-of-mind) β”‚
β”‚ Β· counter_investigate: Blue queries db β†’ Red plants alert on authβ”‚
β”‚ Β· amplify_attack : boosts attack before Blue can contain it β”‚
β”‚ Β· accelerate_spread : spreads to services Blue hasn't checked β”‚
β”‚ Β· corrupt_metric : spikes a service Blue already looked at β”‚
β”‚ Β· inject_noise : misleading log entries (default) β”‚
β”‚ β”‚
β”‚ πŸ”΅ Blue Agent (Defender) β€” your trained Qwen2.5-7B-GRPO β”‚
β”‚ Β· query_logs : read service logs β”‚
β”‚ Β· inspect_metrics : view all service metrics β”‚
β”‚ Β· run_security_scan : deep scan a service β”‚
β”‚ Β· restart_service : restart a crashing service β”‚
β”‚ Β· scale_service : scale replicas β”‚
β”‚ Β· block_ip : block an attacking IP β”‚
β”‚ Β· rollback_deployment: revert a bad deployment β”‚
β”‚ Β· isolate_service : cut a service from the network β”‚
β”‚ Β· submit_diagnosis : final answer (root cause label) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
**Core design principles:**
1. **Partial observability** β€” root cause and attack progress are **never directly visible**
2. **Dense rewards** β€” non-zero signal at every step (not binary success/fail)
3. **Action consequences** β€” wrong isolations/restarts harm the system (negative rewards)
4. **Adversarial noise** β€” Red Agent corrupts observations in real time
5. **Random seeds** β€” different starting states every episode; no memorization possible
6. **Reproducible grading** β€” weighted composite score across 3 components
---
## πŸ€– What Makes This Novel
### 1. True Multi-Agent Adversarial Competition
The Red Agent and Blue Agent share the **same live environment state**. Red's `create_false_alert` action literally appends a new alert to the observation the Blue Agent will see next step. This is not simulated interference β€” it's real shared state mutation. The Blue Agent must reason about WHY an alert might be adversarially planted.
### 2. Curriculum Self-Improvement (5 Levels)
The Blue Agent starts at Level 1 and **automatically earns harder scenarios** as it improves:
```
Level 1: easy_memory_leak β†’ avg score β‰₯ 0.65 over 5 episodes
Level 2: + medium_ddos_cascade β†’ avg score β‰₯ 0.70
Level 3: + medium_hard_bad_deployment β†’ avg score β‰₯ 0.72
Level 4: + hard_data_exfiltration β†’ avg score β‰₯ 0.75
Level 5: hard_data_exfiltration only β†’ expert-level only
```
### 3. Designed to Foil Shortcuts
- **You can't guess the answer** β€” wrong diagnosis gives -1.0, ends episode with ~0 score
- **You can't spam safe actions** β€” every step costs -0.02, step limit enforced
- **You can't ignore the Red Agent** β€” false alerts actively mislead if the defender doesn't reason carefully
- **Each run is different** β€” random seed jitter on all starting metrics prevents memorization
---
## πŸ† Reward Function
Dense rewards at **every step** (can't be gamed with binary success):
| Event | Reward | Why |
|-------|--------|-----|
| Investigate affected service (logs/metrics) | **+0.20** | Reward targeted investigation |
| Security scan on affected service | **+0.30** | Reward hypothesis-driven scanning |
| Correct mitigation (right service/IP) | **+0.50** | Reward precise action |
| Correct final diagnosis | **+1.00** | Maximum reward |
| Irrelevant investigation | **-0.05** | Discourage scatter-gun approach |
| Ineffective mitigation | **-0.10** | Penalise wasted actions |
| Harmful action (wrong isolate/IP) | **-0.50** | Hard penalty: making things worse |
| Wrong final diagnosis | **-1.00** | Maximum penalty |
| Per-step cost | **-0.02** | Efficiency pressure |
### Episode Grader
```
score = 0.5 Γ— diagnosis_correct
+ 0.3 Γ— action_efficiency
+ 0.2 Γ— investigation_quality
```
---
## 🎯 4 Tasks β€” Increasing Difficulty
### Task 1 β€” EASY: Memory Leak in auth
- **What's happening:** `auth` service has a progressive memory leak
- **What you see:** Memory rising, latency climbing
- **Correct response:** `query_logs(auth)` β†’ `restart_service(auth)` β†’ `submit_diagnosis(infra_failure:memory_leak)`
- **Noise:** 5% β€” clear signals
### Task 2 β€” MEDIUM: DDoS Cascade Attack
- **What's happening:** Two external IPs flooding `gateway` β†’ cascading to `api` β†’ `auth`
- **What you see:** High error rates across 3 services simultaneously
- **Correct response:** Review gateway logs, block both IPs, scale `api`
- **Noise:** 25% β€” ambiguous multi-service signals
### Task 3 β€” MEDIUM-HARD: Bad Deployment
- **What's happening:** `api` v2.4.1 pushed invalid Redis config β†’ reconnect storm
- **What you see:** `cache` high CPU (gateway alert misdirects you here)
- **Correct response:** Identify deployment timestamp correlation, rollback `api`
- **Noise:** 35% β€” false gateway alert distracts
### Task 4 β€” HARD: Data Exfiltration (Disguised)
- **What's happening:** Compromised `reports_bot` service account exfiltrating 4GB+ via `db`
- **What you see:** Fake CRITICAL cache alert (planted by Red Agent) + subtle db outbound traffic
- **Correct response:** Ignore cache, scan `db`, identify `reports_bot`, isolate `db`, block `10.0.0.99`
- **Noise:** **55%** β€” plus active Red Agent spreading attack and amplifying it
---
## πŸš€ Live Demo Dashboard
▢️ **[Launch Dashboard](https://huggingface.co/spaces/SapphireGaze429/opensecops-grpo-training)**
Three modes:
**Agent Tab:** Watch your trained Qwen2.5-7B-GRPO investigate and resolve incidents in real time. Toggle between Trained vs Baseline (untrained) to see the contrast. Every action card shows the raw JSON the model generated β€” verifiable live inference, not a replay.
**Battle Tab:** Live Red vs Blue adversarial stream. Watch the attacker inject fake alerts mid-episode. Watch the trained model resist the mislead and correctly identify the real attack vector. Score tracked per-round with Defender Advantage and Attack Suppression metrics.
**Learning Tab:** Curriculum progress across sessions. As you run episodes, scores are tracked server-side, rolling averages computed, and level-up events recorded.
---
## πŸ§ͺ Training β€” Reproducible Notebook
▢️ **[colab_training.ipynb](./colab_training.ipynb)** β€” Full GRPO training on HF Spaces (A100)
```python
# Core reward function β€” wraps the environment directly
def secops_reward_fn(prompts, completions, **kwargs):
rewards = []
for completion, task_id in zip(completions, task_ids):
action = parse_action(completion) # Parse JSON from LLM output
if action is None:
rewards.append(-0.5) # JSON format penalty
continue
env = OpenSecOpsEnv()
env.reset(task_id)
_, reward, _, _ = env.step(action) # Execute in environment
rewards.append(float(reward) - 0.02) # Apply step cost
return rewards
trainer = GRPOTrainer(
model=model,
args=GRPOConfig(num_generations=4, max_new_tokens=128, temperature=0.9),
reward_funcs=secops_reward_fn,
train_dataset=dataset,
)
trainer.train()
```
**Setup:** Qwen2.5-7B-Instruct + Unsloth 4-bit + LoRA (r=16) + TRL GRPOTrainer. Merged to 16-bit for clean production deployment. Tracked with W&B.
---
## πŸ“¦ Project Structure
```
β”œβ”€β”€ colab_training.ipynb # ← Full GRPO training (run this)
β”œβ”€β”€ opensecops_env/
β”‚ β”œβ”€β”€ env.py # Core OpenEnv environment (reset/step/state)
β”‚ β”œβ”€β”€ grader.py # Multi-component grader [0,1]
β”‚ β”œβ”€β”€ models.py # SecOpsAction, Observation, HiddenState
β”‚ β”œβ”€β”€ tasks/task_definitions.py # 4 incident configs with full metadata
β”‚ └── server/app.py # FastAPI + SSE streams + live dashboard
β”œβ”€β”€ tests/test_opensecops.py # 33 unit tests (all passing)
β”œβ”€β”€ hf_blog_post.md # Full technical writeup
β”œβ”€β”€ DASHBOARD_GUIDE.md # Plain-English dashboard explanation
β”œβ”€β”€ TECHNICAL_ANALYSIS.md # Full pipeline + theme alignment analysis
β”œβ”€β”€ openenv.yaml # OpenEnv manifest
β”œβ”€β”€ Dockerfile
└── requirements.txt
```
---
## πŸƒ Quick Start
```bash
# Install
pip install -e ".[dev]"
# Run test suite (33 tests)
pytest tests/ -v
# Start server (auto-loads .env for HF_TOKEN)
uvicorn opensecops_env.server.app:app --host 0.0.0.0 --port 8000
# Open dashboard
open http://localhost:8000/dashboard
# Test live AI endpoint
open http://localhost:8000/debug/ai
```
**Environment variables (.env file):**
```
HF_TOKEN=hf_xxxx # Required for live AI inference
TRAINED_MODEL_ENDPOINT=https://... # Override default endpoint
```
### Docker
```bash
docker build -t opensecops-env:latest .
docker run -p 8000:8000 -e HF_TOKEN=hf_xxxx opensecops-env:latest
```
---
## πŸ”— All Resources
| Resource | Link |
|----------|------|
| πŸ€— HF Space (Live Demo + Training) | [SapphireGaze429/opensecops-grpo-training](https://huggingface.co/spaces/SapphireGaze429/opensecops-grpo-training) |
| 🧠 Trained Model | [SapphireGaze429/opensecops-qwen2.5-7b-grpo](https://huggingface.co/SapphireGaze429/opensecops-qwen2.5-7b-grpo) |
| πŸ““ Training Notebook | [colab_training.ipynb](./colab_training.ipynb) |
| πŸ“Š Training Plots | [training_results.png](https://huggingface.co/SapphireGaze429/opensecops-qwen2.5-7b-grpo/resolve/main/training_results.png) |
| πŸ“ Full Blog Post | [hf_blog_post.md](./hf_blog_post.md) |
| πŸ“– Dashboard Guide | [DASHBOARD_GUIDE.md](./DASHBOARD_GUIDE.md) |
| πŸ”¬ Technical Analysis | [TECHNICAL_ANALYSIS.md](./TECHNICAL_ANALYSIS.md) |
---
## πŸ† Scoring Criteria Alignment
| Criterion | Weight | How We Address It |
|-----------|--------|------------------|
| **Environment Innovation** | 40% | Multi-agent adversarial with shared live state; partial observability; 55% adversarial noise; curriculum self-improvement; dense reward with action consequences |
| **Storytelling** | 30% | Live dashboard with real AI output; before/after demo; Battle Mode with visible attacker vs defender; Dashboard Guide + Blog Post |
| **Showing Improvement** | 20% | +245% on hardest task; reward and loss curves; before/after bar chart across all 4 difficulty levels |
| **Reward + Training Pipeline** | 10% | Dense multi-component reward; GRPO with environment-derived signal; reproducible notebook; W&B tracking |
---
## πŸ“œ License
MIT License β€” see [LICENSE](LICENSE).
*Built for the OpenEnv Hackathon Round 2. Every dashboard action is live model inference against the HF Inference Endpoint β€” no mock data, no pre-scripted replays.*