Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,7 @@ CybORG/Emulator/Logs/
CybORG/Emulator/logs/
CybORG/Emulator/Config/emulatorconfig.ini
docs/_build/
site/
dist

CybORG/Shared/Config/config.ini

CybORG/Emulator/AWS/Config/awsconfig.ini

*.swp
*.pstats

.ipynb_checkpoints/
docs/

.ruff_cache/
82 changes: 82 additions & 0 deletions DATASHEET.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Datasheet & Responsible Use — NetForge RL

Following *Datasheets for Datasets* (Gebru et al.) adapted for a simulated
benchmark environment. This accompanies a NeurIPS Datasets & Benchmarks submission.

## Motivation

- **Purpose.** NetForge is a research gym and benchmark for autonomous cyber
defense: train, evaluate, break, and compare Red/Blue agents. The simulator
is the engine; NetForge Arena is the standardized evaluation contract
(scenarios, seeds, hidden tests, capability probes, agent cards).
- **Gap addressed.** Existing cyber-RL environments are largely single-agent or
fixed-topology, and they rarely freeze a benchmark protocol. NetForge provides
procedural topologies, belief-state graph observations, a train/dev/hidden
split, scenario packs, risk-sensitive metrics, and a verified JAX throughput
backend.

## Composition

- **Instances.** Episodes are procedurally generated network topologies (100 hosts,
3–5 subnets, optional OT subnet) with per-host OS/CVE/service/credential profiles.
- **Generation.** `NetworkGenerator(seed)` is deterministic per seed. Training draws
from arbitrary seeds; evaluation (`evaluation_mode=True`) draws from a disjoint
held-out pool (seed offset 1000) never seen during training.
- **No personal data.** All hosts, IPs, credentials, and logs are synthetic. CVE
identifiers (e.g. MS17-010, CVE-2019-0708) reference public catalog entries used
only as abstract vulnerability labels; no exploit code is included.

## Collection / Construction

- **Dynamics.** Two backends share one action taxonomy. The full-fidelity PettingZoo
env (`environment/parallel_env.py`) carries action durations, an event queue, SIEM
telemetry, and command-list deltas. The vectorized JAX kernel
(`backends/jax/vector_env.py`) implements a reduced transition core and is verified
equivalent to its NumPy reference (`backends/reference.py`) by a trajectory-level
parity test that gates CI (`tests/parity/test_jax_reference_equivalence.py`). The
JAX kernel is a scalable subset, not a bit-equivalent replica of the full env.
- **Rewards.** Per-scenario decompositions; see `benchmarks/env_spec.py` for the full
table. Per-step rewards are small; the OT-safety scenarios (`ot_stuxnet`, and the
kinetic branch of `ransomware`) add a large ±10,000 terminal signal when a PLC is
physically destroyed, so catastrophic physical outcomes dominate the return.
`BaseScenario.normalized_reward` exposes a `tanh`-squashed value in `[-1, 1]` for
cross-scenario comparison.
- **Determinism.** Deterministic under a seed. A per-episode RNG on `GlobalNetworkState`
drives stochastic actions (exploit rolls, phishing, PLC overload); the SIEM logger,
event templates, topology engine, physics, and green agent are all reseeded on
`reset(seed)`. See `tests/parity/test_golden_trajectory.py`.

## Recommended Uses

- Benchmarking cooperative/competitive MARL algorithms under partial observability.
- Evaluating LLM agents as SOC operators (`benchmarks/llm_eval.py`).
- Studying generalization via the train/held-out topology split
(`benchmarks/run_benchmark.py --gap`).

## Limitations

- **It is a simulation.** Dynamics are abstracted and have **not** been validated
against real network telemetry or live red-team engagements. Results do not
transfer to operational systems without further study.
- **Abstracted exploits.** Exploit success is modeled via CVSS-weighted probabilities
and vulnerability flags, not real exploitation. CVE labels are not a fidelity claim.
- **No real C2 integration.** Live-fire orchestration against real frameworks is
intentionally out of scope and gated behind an unimplemented isolation policy.

## Responsible Use (dual-use statement)

This environment trains both attacker and defender policies. It is released for
**defensive research and benchmarking**. The simulator contains no operational
exploit code, no malware, and no capability to act on real systems. Trained Red
policies operate only inside the simulator's abstract action space and confer no
real-world offensive capability. Users must not attempt to connect the environment
to real or production infrastructure. We encourage use aligned with coordinated
vulnerability disclosure norms.

## Maintenance

- **Versioning.** Environment changes that alter dynamics are reflected in the
parity reference and gated by CI; the golden-trajectory fingerprint test detects
unintended reward/termination drift.
- **Reproducibility.** Pin the package version and seeds; `benchmarks/` scripts emit
timestamped JSON results with mean ± CI95.
192 changes: 90 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,125 @@
<div align="center">
<img src="https://img.shields.io/badge/version-3.1.0-blue?style=for-the-badge" alt="Version 3.1.0"/>
<img src="https://img.shields.io/badge/Python-3.12+-blue?style=for-the-badge&logo=python" alt="Python 3.12+"/>
<img src="https://img.shields.io/badge/JAX-vmap%20%2B%20jit-orange?style=for-the-badge" alt="JAX"/>
<img src="https://img.shields.io/badge/PettingZoo-MARL-purple?style=for-the-badge" alt="PettingZoo"/>
<img src="https://img.shields.io/badge/MITRE_ATT%26CK-Mapped-red?style=for-the-badge" alt="MITRE ATT&CK"/>
<img src="docs/_static/figures/mark.svg" width="96" alt="NetForge">

# NetForge

**Cybersecurity gym for reinforcement learning**

Red attacks a network. Blue contains it from SIEM, not from an oracle.
PettingZoo (1 Red + 3 Blue) or Gymnasium (one Blue vs scripted Red).

**Python 3.12+** · **PettingZoo** · **Gymnasium** · **Not on PyPI**

[Docs](https://reforcemind.github.io/NetForge_RL/) ·
[Start](https://reforcemind.github.io/NetForge_RL/getting-started.html) ·
[Python](https://reforcemind.github.io/NetForge_RL/python-quickstart.html) ·
[Cyber](https://reforcemind.github.io/NetForge_RL/cybersec/overview.html) ·
[Contributing](CONTRIBUTING.md)

<p>
<img src="docs/_static/figures/purpose.svg" width="920" alt="Red, Blue, and the network">
</p>
</div>

<h1 align="center">NetForge RL</h1>

<p align="center">Multi-agent cybersecurity environment for RL research. Red team vs Blue team on generated networks.</p>

---

## Why NetForge

- **Standardized API** — PettingZoo `ParallelEnv`, Gymnasium spaces, conformance-tested.
A `gymnasium.Env` single-agent facade (`NetForgeSingleAgentEnv`) drops straight into
Stable-Baselines3 or CleanRL.
- **Partial observability that means something** — Blue reads a filtered, optionally
*delayed* SIEM feed; Red must recon a host before it can exploit it.
- **Real telemetry** — actions emit real Windows/Sysmon event XML, encoded into
observations by an NLP pipeline. Point an OpenAI, Anthropic, Google, or vLLM client at
the raw logs and let it play SOC analyst.
- **MITRE ATT&CK aligned** — actions carry ATT&CK technique IDs, and CVE identifiers are
used as abstract vulnerability labels (no real exploit code); every episode reports which
ATT&CK techniques Red actually exercised.
- **Reproducible to the bit** — a fixed seed replays observations, SIEM embeddings, infos,
and rewards identically. Test-guaranteed, not just claimed.
- **Tunable difficulty** — named `easy` / `medium` / `hard` presets plus a frozen held-out
evaluation split, so results are comparable across runs.
- **Diagnostic probes + capability cards** — 6 targeted probes (memory, attention,
temporal, precision, safety, generalization) score *what* a policy can and can't do,
summarized as a per-policy radar chart.
- **Deception as a mechanic** — decoys and honeytokens with a `deception_efficacy` metric
quantifying how much of Red's effort was wasted on traps.
- **Optional graph observations** — an experimental wrapper exposes hosts as nodes and
reachability as edges (fog-of-war aware); the benchmarked default is the fixed-shape array.
- **Self-play & Elo** — a population tournament rates every red and blue policy on one
shared Elo ladder.
- **Fast** — the JAX backend reaches **~2.5×10⁵ env-steps/s (~1.0M agent-steps/s)** at batch
4096 on CPU. It runs a reduced transition core with an in-kernel scalar alert (not the full
SIEM text pipeline), so it is a throughput surrogate, not a replica of the Python engine.
- **Trained, not just scripted, baselines** — a JIT-fused IPPO trainer whose entire
rollout runs on-device; a committed run learns mean reward 0.06 → 0.71 on `ransomware`.

## Install
## 📰 News

```bash
pip install 'netforge_rl[jax] @ git+https://github.com/reforcemind/NetForge_RL'
```
**🗓️ September 2026**

- 🛡️ **20** — Gym ids: PettingZoo `netforge/ransomware-v4` (1 Red + 3 Blue) and Gymnasium `NetForge/Blue-v4`. Blue trains on SIEM belief graphs, not the true map.
- 📟 **20** — `netforge` CLI: `run`, `evaluate`, `questions`, HTML replay. Packs for hospital, cloud, APT, IoT, OT.
- 🏗️ **20** — Arena train / dev / hidden splits. Typed `EnvConfig`. Sphinx docs, same kit as [FlowEdge](https://github.com/reforcemind/FlowEdge).

🏷️ [Changelog](docs/changelog.md) · 📘 [Docs](https://reforcemind.github.io/NetForge_RL/)

***

## The problem

A defender does not get the true compromise map. The SOC sees Sysmon-like logs
that can be late, dropped, or noisy. Red starts blind and only sees hosts it has
discovered. Exploits and isolates take ticks, not one step.

A gym that hands Blue an oracle, pays for isolating the whole net, or scores
mean reward against one scripted Red is training the wrong job.

Extras: `jax` (vectorized backend), `render` (visualization), `finetune` (LLM PEFT),
`rllib` (Ray multi-agent training). See the
[install guide](https://reforcemind.github.io/NetForge_RL/quickstart/) for the full list.
## What NetForge does

## Quick start
Each tick, agents pick `[action_type, host_index]`. Actions run, conflicts
resolve, SIEM fires, Blue obs update from the buffer.

**Red** — discover, exploit CVEs, escalate, exfil, or hit a PLC.
**Blue** — isolate, ACL, restore, decoys (`169.254.x.x`). Quiet Red may never
show up in logs.
**Kinetic** — `OverloadPLC` can end the episode for Blue.

```python
from netforge_rl.environment import make_env
import netforge_rl
import gymnasium as gym
from pettingzoo import make

env = make_env('medium', scenario_type='ransomware', seed=0)
env = make('parallel', 'netforge/ransomware-v4', max_ticks=80)
obs, infos = env.reset(seed=0)
while env.agents:
actions = {a: env.action_space(a).sample() for a in env.agents}
obs, rewards, term, trunc, infos = env.step(actions)
if all(term.values()) or all(trunc.values()):
break
blue = gym.make('NetForge/Blue-v4', max_ticks=80)
```

### JAX vectorized (4096 environments)
<p align="center">
<img src="docs/_static/figures/workflow.svg" width="920" alt="reset, observe SIEM, act, next tick">
</p>

```python
import jax
from netforge_rl.backends.jax import VectorEnvSpec
from netforge_rl.bridges.jaxmarl import JaxMARLEnv, random_action_dict

env = JaxMARLEnv(spec=VectorEnvSpec(n_hosts=100, n_red=1, n_blue=3), batch_size=4096)
key = jax.random.PRNGKey(0)
obs, state = env.reset(key)
obs, state, reward, done, info = env.step(key, state, random_action_dict(env, key))
```
## Why this, not the usual stack

### LLM as a Blue agent
<p align="center">
<img src="docs/_static/figures/why-this.svg" width="920" alt="SOC view vs god-mode, delayed logs, SLA vs isolate-all">
</p>

```python
from netforge_rl.semantic import state_to_text, parse_action
Blue never sees the true map. Logs can lag. Isolate-everything wrecks SLA.
Eval uses a Red population, not one campaign. Trainers (MAPPO / QMIX / …) stay
in your repo.

prompt = state_to_text(env.to_envstate(), agent_id='blue_dmz')
# send prompt to your model, then:
action_idx = parse_action(model_reply, 'blue_dmz', sorted(env.global_state.all_hosts))
```
## First run

Not on PyPI. Python 3.12+.

See the [Quick Start Guide](https://reforcemind.github.io/NetForge_RL/quickstart/) for
difficulty presets, baselines, diagnostics, and the Gymnasium single-agent wrapper.
```bash
python -m pip install 'netforge-rl @ git+https://github.com/reforcemind/NetForge_RL'
netforge run hospital_ransomware --replay replay.html
```

## The five scenarios
From a clone:

| Scenario | Red objective | Blue objective | Terminal condition |
|---|---|---|---|
| `ransomware` | Compromise Corporate + Secure | Contain, restore, avoid downtime | all Corporate/Secure compromised, or PLC kinetic |
| `apt_espionage` | Stealthy persistence + exfiltration | Detect and isolate every foothold | every infected host isolated |
| `cloud_hybrid` | Breach the Secure enclave | Protect the Secure subnet SLA | every Secure host compromised |
| `iot_grid` | Take the grid controllers | Keep controllers healthy | all controllers compromised |
| `ot_stuxnet` | Drive a PLC to kinetic destruction | Prevent physical damage | any PLC kinetic destruction |
```bash
git clone https://github.com/reforcemind/NetForge_RL.git
cd NetForge_RL
pip install -e ".[dev]"
netforge run ransomware --seed 0 --max-ticks 40
```

## Package layout
```bash
python -m netforge --help
```

| Package | Purpose |
| Piece | |
|---|---|
| `environment/` | PettingZoo `NetForgeRLEnv`, difficulty presets, curriculum, Gymnasium facade |
| `scenarios/` | 5 reward/objective families sharing one `BaseScenario` |
| `actions/red`, `actions/blue` | ATT&CK-aligned capabilities + technique mapping |
| `siem/`, `nlp/` | Sysmon/Windows log synthesis, NLP encoding, OCSF-style export |
| `backends/jax/` | Vectorized `vmap`/`jit` transition kernel + NumPy reference |
| `baselines/` | Random, heuristic, kill-chain red, JAX IPPO |
| `diagnostics/` | Capability probes, oracle information-asymmetry, capability cards |
| `bridges/` | RLlib, JaxMARL, CleanRL, DLPack adapters |
| `semantic/` | LLM SOC agents, prompt grammars, fine-tuning recipes |
| Agents | `red_operator`, `blue_dmz`, `blue_internal`, `blue_restricted` |
| Action | `MultiDiscrete([32, 100])`, mask `int8[132]` |
| Blue obs | vector + SIEM embedding + belief graph |
| Families | ransomware, APT, cloud, IoT, OT/Stuxnet |
| Trainers | your code. Not bundled. |

Gate: `scripts/verify_all.sh` or `scripts/verify_local.ps1`. GitHub Actions is ruff + pytest + Sphinx. `docs.yml` deploys the site to GitHub Pages on `main`.

## Citation

```bibtex
@misc{jankowski2026netforgerlmultiagentsimulation,
title={NetForge RL: A Multi-Agent Simulation Environment for Cyber Defense with Durative Actions},
title={NetForge RL: A Multi-Agent Simulation Environment for Cyber Defense with Durative Actions},
author={Igor Jankowski},
year={2026},
eprint={2604.09523},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2604.09523},
url={https://arxiv.org/abs/2604.09523},
}
```

## License

MIT — see [LICENSE](LICENSE).
MIT, with CybORG / DSTG notices in [LICENSE](LICENSE).
Loading