AEGIS
Air-gapped Evidence-Grade Inspection System — preflight network changes against a real digital twin, entirely inside your perimeter.
No cloud. No data egress. Ever. A self-hosted LLM proposes config inside the wall; the twin verifies; a human authorizes; only a sealed compliance badge leaves.
The air-gapped answer to cloud-by-architecture
AEGIS is a self-hosted Python tool that preflights network changes against a real containerlab digital twin entirely inside an air-gapped perimeter, then emits a tamper-evident, framework-mapped, examiner-ready evidence bundle.
It is the air-gapped answer to cloud-by-architecture tools like Forward Predict and NetPilot, serving regulated networks that legally cannot send topology or config off-prem.
It runs a guarded-agentic loop — a self-hosted LLM proposes config and every step afterward is deterministic verification — so the LLM proposes inside the wall, the twin verifies, a human authorizes, and only a sealed compliance badge ever leaves.
Guarded, verified, sealed
Every capability traces back to a single invariant: the LLM proposes, the pipeline deterministically verifies, and nothing crosses the wall but a sealed badge.
Inside the perimeter
Everything runs inside an air-gapped perimeter. The operator submits a change, a self-hosted Qwen3 proposes config, a throwaway containerlab twin verifies it, and an auditor consumes the sealed PDF — no actor or line ever reaches outside the wall. The codebase splits into four layers: an orchestrator that drives the loop, backends that abstract where work runs, evidence that seals and renders the output, and a promote layer that gates a verified bundle toward production.
No actor or config line ever reaches outside the air-gapped wall; the operator submits a change, a self-hosted Qwen3 proposes config, a throwaway containerlab twin verifies it, and only a sealed PDF badge leaves to the auditor.
flowchart LR
OP([Operator]):::actor
APP([Approver]):::actor
AUD([Auditor]):::actor
subgraph PERIM["Air-gapped perimeter - egress none"]
direction LR
AEGIS{{"AEGIS preflight + evidence engine"}}:::core
QWEN[/"Self-hosted Qwen3 - only AI dep"/]:::ai
TWIN[("containerlab twin - multi-vendor")]:::twin
DCN["DCN_Network_Tool :5757"]:::svc
end
PROD[("Production devices")]:::prod
OP -->|intent or config| AEGIS
APP -->|approval token| AEGIS
AEGIS -->|generate_config| QWEN
AEGIS -->|spawn apply converge| TWIN
AEGIS -.->|live tier| DCN
AEGIS -->|sealed PDF bundle| AUD
AEGIS -.->|gated dry-run| PROD
classDef actor fill:#475569,stroke:#94a3b8,color:#f8fafc
classDef core fill:#0d9488,stroke:#2dd4bf,color:#f0fdfa
classDef ai fill:#7c3aed,stroke:#a78bfa,color:#faf5ff
classDef twin fill:#059669,stroke:#34d399,color:#ecfdf5
classDef svc fill:#0ea5e9,stroke:#38bdf8,color:#f0f9ff
classDef prod fill:#9f1239,stroke:#fb7185,color:#fff1f2
class PERIM core
The orchestrator drives the loop, the backends abstract where work runs, evidence seals and renders the output, and promote gates a verified bundle toward production behind a dry-run connector.
flowchart TB
UI["serve.py + ui/preflight_screen.html"]:::edge
subgraph ORCH["core/orchestrator"]
PIPE["pipeline.py run_preflight"]:::core
GUARD["guards.py precheck + risk_tier"]:::core
ROLL["rollback.py build_rollback_plan"]:::core
end
subgraph BACK["core/backends Protocol"]
BASE["base.py Backend Protocol"]:::proto
SIM["simulator.py seeded"]:::svc
HTTP["http_backend.py :5757"]:::svc
end
subgraph EVID["evidence"]
BUND["bundler.py sha256 seal"]:::data
COMP["compliance.py crosswalk"]:::accent
PDF["pdf.py examiner PDF"]:::accent
end
subgraph PROM["core/promote"]
GATE["gate.py G1-G4"]:::accent
CONN["connectors.py DryRun"]:::edge
end
UI --> PIPE
PIPE --> GUARD
PIPE --> BASE
BASE --> SIM
BASE --> HTTP
PIPE --> COMP
PIPE --> ROLL
PIPE --> BUND
BUND --> PDF
BUND --> GATE
GATE --> CONN
classDef edge fill:#475569,stroke:#94a3b8,color:#f8fafc
classDef core fill:#0d9488,stroke:#2dd4bf,color:#f0fdfa
classDef proto fill:#7c3aed,stroke:#a78bfa,color:#faf5ff
classDef svc fill:#0ea5e9,stroke:#38bdf8,color:#f0f9ff
classDef data fill:#059669,stroke:#34d399,color:#ecfdf5
classDef accent fill:#d97706,stroke:#fbbf24,color:#fffbeb
One preflight run, end to end
The guard layer prechecks before any twin is spawned, the backend proposes and verifies against a throwaway twin, and the bundler seals the result — the twin is always torn down in a finally block.
sequenceDiagram
autonumber
actor Op as Operator
participant Srv as serve.py
participant Pipe as run_preflight
participant G as guards
participant B as Backend
participant Ev as bundler
Op->>Srv: POST /api/preflight/run intent, lab, frameworks
Srv->>Pipe: run_preflight(SimulatorBackend)
Pipe->>G: precheck_intent
alt unsafe input
G-->>Srv: PreflightError to HTTP 400
else valid
Pipe->>B: generate_config (only AI step)
Pipe->>B: batfish_check static analysis
Pipe->>B: spawn_twin + apply_and_converge
Pipe->>B: state_diff routes and sessions
Pipe->>G: risk_tier + approval_required
Pipe->>Ev: build_bundle sha256 seal, egress none
Note over Pipe,B: finally teardown_twin always
Ev-->>Srv: sealed JSON bundle
Srv-->>Op: bundle plus optional PDF
end
The verdict resolves to blocked, needs_approval, or ship_ready from batfish errors, twin convergence, and BGP regression; a promotable bundle then passes the four-rule Phase 2 gate, dry-run by default.
stateDiagram-v2
[*] --> Verdict
Verdict --> Blocked: batfish errors or BGP regression
Verdict --> NeedsApproval: medium or high risk
Verdict --> ShipReady: clean and low risk
Blocked --> [*]
NeedsApproval --> Gate: approver + token
ShipReady --> Gate
state Gate {
[*] --> G1
G1 --> G2: integrity re-verified
G2 --> G3: verdict promotable
G3 --> G4: approval token valid
G4 --> DryRun: safe default
G4 --> Live: explicit opt-in
}
Gate --> Record: sealed promotion record
Record --> [*]
The deterministic pipeline, step by step
Pure-stdlib core, no cloud
A backend-agnostic Python core, a single self-hosted LLM as the only AI dependency, and a real containerlab twin — assembled so an air-gapped profile can run with network_mode: none.
Modules & responsibilities
Each module maps to a real file in the repo. The orchestrator drives the loop, guards stay pure and auditable, backends abstract where work runs, and evidence seals and renders the proof.
Run it inside your perimeter
The community sim tier needs zero external dependencies. Bring up the dashboard, or carry a signed Docker tar across the gap and run fully air-gapped.
docker compose up # then open http://localhost:8088/preflight
pip install -r requirements.txt python -m aegis.serve # from the directory ABOVE aegis/
docker compose build && docker save aegis:local -o aegis-local.tar # online, once docker load -i aegis-local.tar docker compose -f docker-compose.yml -f docker-compose.airgap.yml up # network_mode: none
python -m aegis.tests.stress_test 25000 # pipeline invariants (8, adversarial) python -m aegis.tests.contract_test # HttpBackend parsers vs :5757 shapes python -m aegis.tests.pdf_test # evidence PDF validity python -m aegis.tests.promote_test # Phase 2 approval-gate safety