
Antigena (Darktrace) → Aruba ClearPass CoA bridge — model-driven, real-time user/device quarantine. Zero SOC clicks. Hexagonal architecture, 82% test coverage.
Antigena (Darktrace) → Aruba ClearPass CoA bridge — model-driven, real-time user/device quarantine. Zero SOC clicks between detection and containment.
Sanitized reference implementation of a production NDR↔NAC integration pattern operated at financial-sector scale (multi-thousand endpoints, 24/7 SOC). Customer-specific bits replaced with synthetic fixtures; the architecture, decision flow, and operational patterns are the real ones.
The promise of NDR (Darktrace, ExtraHop, Vectra) is detection in seconds. The reality in most banks: detection in seconds, containment in hours — because the SOC handoff to NAC/firewall teams is manual.
This toolkit closes that gap by bridging Antigena (Darktrace's Autonomous Response module) to Aruba ClearPass via the ClearPass REST API. When a Darktrace model fires above a configurable severity threshold, the toolkit:
End-to-end median latency from model fire → quarantine VLAN active: under 5 seconds.
zero-touch-containment/
├── README.md ← You are here
├── LICENSE
├── .gitignore
├── docs/
│ ├── architecture.md ← Full architecture deep-dive + SOLID trace
│ └── lessons-learned.md ← 10 lessons from running this in prod
│
├── webhook/ ← Inbound HTTP layer (split by SRP)
│ ├── app.py ← FastAPI routes + lifespan only
│ ├── auth.py ← verify_hmac() — HMAC-SHA1 validation
│ ├── replay.py ← ReplayCache — LRU replay protection
│ └── models.py ← AntigenaEvent pydantic schema
│
├── engine/ ← YAML-driven decision engine
│ ├── decision.py ← DecisionEngine (depends on QuarantineReader Protocol)
│ ├── rules.py ← YAML loaders for mapping + allowlist
│ └── models.py ← Action + MappingRule + ActionKind
│
├── clearpass/ ← NAC adapter (implements CoAClient Protocol)
│ ├── client.py ← ClearPassClient — REST CoA-style ops
│ ├── ports.py ← CoAClient Protocol — port for any NAC backend
│ └── auth.py ← OAuth2 TokenCache
│
├── ledger/ ← SQLite ledger (implements 5 ports — ISP applied)
│ ├── store.py ← SqliteLedger — all-in-one implementation
│ ├── ports.py ← EventStore + QuarantineWriter + QuarantineReader
│ │ + ReleaseManager + HealthChecker (segregated)
│ └── schema.py ← SQL DDL constant
│
├── cli/ ← SOC operations CLI
│ └── soc.py ← `ztc release-expired` + planned commands
│
├── config/
│ ├── mapping.example.yaml ← Severity → action mapping
│ └── allowlist.example.yaml ← VIP / never-quarantine list
│
├── deploy/
│ ├── docker-compose.yml
│ ├── Dockerfile
│ └── .env.example
│
├── tests/ ← 60 tests covering every layer
│ ├── test_decision.py
│ ├── test_ledger.py
│ ├── test_webhook_helpers.py
│ ├── test_clearpass_client.py
│ ├── test_protocols.py ← Structural ISP/DIP compliance tests
│ └── fixtures/sample_event.json
│
├── requirements.txt
└── pyproject.toml
git clone https://gitlab.com/zimlama/zero-touch-containment.git
cd zero-touch-containment
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp config/mapping.example.yaml config/mapping.yaml
cp config/allowlist.example.yaml config/allowlist.yaml
cp deploy/.env.example .env # fill in CLEARPASS_HOST, OAUTH creds, HMAC secret
# Run the webhook receiver
uvicorn webhook.app:app --host 0.0.0.0 --port 8080
# In another shell: replay a sample event
curl -X POST http://localhost:8080/antigena \
-H "Content-Type: application/json" \
-H "X-Darktrace-Signature: sha1=$(echo -n @tests/fixtures/sample_event.json | openssl dgst -sha1 -hmac "$HMAC_SECRET" | awk '{print $2}')" \
--data @tests/fixtures/sample_event.json
The webhook validates HMAC-SHA1, runs the decision engine against mapping.yaml, and either:
┌──────────────┐ 1. webhook ┌──────────────────┐ 2. validate ┌──────────────────┐
│ Darktrace │ ──────────────▶ │ Webhook │ ───────────────▶ │ Decision │
│ Antigena │ HMAC-SHA1 │ receiver │ parse + auth │ engine │
│ fires model │ │ (FastAPI) │ │ (YAML-driven) │
└──────────────┘ └──────────────────┘ └─────────┬────────┘
│
▼
3. resolve action
(allowlist + rate limit)
│
┌───────────────────────┬───────────────────────┼────────────────────────┐
▼ ▼ ▼ ▼
┌──────────────┐ ┌────────────────┐ ┌──────────────┐ ┌─────────────┐
│ ClearPass │ │ SQLite │ │ Slack/Teams │ │ SIEM │
│ REST API │ │ ledger │ │ notification │ │ (structured │
│ - role swap │ │ - state │ │ │ │ logs) │
│ - disconnect │ │ - auto-release │ │ │ │ │
└──────────────┘ └────────────────┘ └──────────────┘ └─────────────┘
See docs/architecture.md for the full breakdown.
The patterns here came out of a multi-year NDR + NAC engagement at a Tier-1 LATAM financial institution:
The toolkit is the distilled, sanitized version of that integration. Model names, tenant IDs, ClearPass endpoints, IP plans replaced with synthetic equivalents.
docs/lessons-learned.md10 things I wish someone had told me before day one of an Antigena↔ClearPass production deployment — covering webhook reliability, ClearPass REST API quirks, the difference between role swap and disconnect, false-positive containment storms, and operator handoff design.
Hexagonal layering with explicit Protocol ports between concrete adapters and orchestration code:
See docs/architecture.md for the full breakdown.
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[test]"
HMAC_SECRET=test-secret python -m pytest tests/ -v
60 tests covering the decision engine, SQLite ledger, HMAC validation, replay cache, ClearPass client (async, respx-mocked), and structural Protocol compliance.
list, release, quarantine, audit (Tier-2)Leonardo Mejía — Senior Cybersecurity & SD-WAN Architect · 15+ years Zero Trust · Hybrid Cloud · NDR · Enterprise SD-WAN
MIT — see LICENSE.
The patterns in this repo are sanitized abstractions, not proprietary client code. Use freely; attribution appreciated.
| Layer | Tools |
|---|
| Language | Python 3.11+ |
| Web | FastAPI + Uvicorn (webhook receiver) |
| HTTP client | httpx (async) + tenacity (retry-with-backoff) |
| Auth | HMAC-SHA1 inbound (Darktrace) · OAuth2 client_credentials outbound (ClearPass) |
| Config | YAML — severity → action mapping + allowlist |
| State | SQLite + WAL — quarantine ledger + auto-release |
| Logging | structlog — JSON output for SIEM ingest |
| Testing | pytest + respx (httpx mock) + recorded fixtures |
| Deploy | Docker Compose, single-VM friendly |
| Principle | Implementation |
|---|
| SRP | webhook/ split into auth + replay + models + routing. clearpass/ split into client + auth + ports. ledger/ split into store + ports + schema. |
| OCP | New NAC backends implement CoAClient Protocol — no changes to webhook or engine. |
| LSP | Tests use in-memory fakes that satisfy the same Protocols. Pipeline behavior unchanged. |
| ISP | Ledger split into 5 segregated ports (EventStore, QuarantineWriter, QuarantineReader, ReleaseManager, HealthChecker). Webhook depends only on the first two; engine only on QuarantineReader. |
| DIP | webhook/app.py and engine/decision.py depend on Protocols, never on concrete classes. |