Hermes Lab Manager

Multi-profile AI orchestration for digital forensics & penetration testing — two labs, one machine, zero context pollution  ·  View on GitHub

HARD ROUTING RULE

The default profile never runs lab tools, starts containers, or checks targets. All lab work is dispatched to worker profiles:

Dispatch fails? Report the failure. Do not fall back to direct execution. The vaults make this structural: templates and scripts live behind LUKS — locked vault = ENOENT.

Quick Demo

One command checks both labs. Forensics: 20 checks (12 tools + 8 env) across 3 runtimes. Pentest: 14 services including Docker containers, WireGuard VPN, and LUKS vault.

$ bash check-labs

=== PENTEST ===
=== Results: 14 passed, 0 failed ===
✓ All services operational — ready for engagement

=== FORENSICS ===
=== Results: 20 passed, 0 failed ===
✓ All runtimes operational — ready for investigation
Hermes Lab Manager Architecture — Supervisor-Worker pattern

Hardware & Prerequisites

i7-11800HCPU (8C/16T)
30 GBRAM
468 GBNVMe SSD
Ubuntu 24.04+RECENT KERNEL
ComponentVersionPurpose
Hermes Agentv0.17.0AI orchestration — profiles, one-shot dispatch, skills
Dockerlatest stableContainer runtime for volatility3, plaso, MFT, pentest tools
VMware Workstation17.xSIFT Workstation VM (forensics native tools)
LUKS / cryptsetup2.7+Encrypted vaults for evidence and engagement data
WireGuard1.xVPN for pentest OPSEC ()
WeasyPrint62+HTML → PDF report generation
gh CLI2.xGitHub Pages deployment, repo management
Python3.14Report generation, screenshot automation, helper scripts

Profile System

Three Hermes profiles, each with its own persona (SOUL.md), skills, memory, config, and .env. Profiles sandbox $HOME — always use absolute paths.

ProfileDirectoryRoleTool Access
default ~/.hermes/ Manager — routes tasks, health checks, validates output Terminal, file, web, browser (NO forensics/pentest tools)
forensics ~/.hermes/profiles/forensics/ DFIR worker — memory, disk, network forensics Docker (vol3, plaso, MFT), MemProcFS, SIFT VM SSH
pentest ~/.hermes/profiles/pentest/ Pentest worker — recon, exploitation, reporting Docker (kali-web, kali-net, osint, neo4j), VPN

Creating a worker profile

hermes profile create forensics
hermes profile create pentest

Then copy ~/.hermes/.env to each profile directory so they have API keys.

Config example (forensics)

# ~/.hermes/profiles/forensics/config.yaml
agent:
  max_turns: 120
  tool_use_enforcement: true
terminal:
  backend: local          # MUST be local — profile needs host file access
  timeout: 600
model:
  default: 
  provider: 
memory:
  memory_enabled: true
approvals:
  mode: manual            # Never YOLO on evidence

LUKS Vault System

Both labs use LUKS-encrypted loop devices for at-rest encryption. Keyfiles stored at /home/user/.forensics-keyfile and /home/user/.pentest-keyfile (chmod 600). Forensics uses noauto in crypttab (manual mount only). Pentest vault does not survive reboot.

VaultFileSizeMountContents
Forensics /home/user/forensics.img 30 GB /home/user/forensics/ Cases, scripts, templates, tool catalog, evidence (read-only)
Pentest /home/user/pentest-vault.img 10 GB /home/user/pentest/ Engagements, keys, wordlists, Docker volumes, tool data
Design decision: Forensics vault uses noauto in /etc/crypttab. The vault only mounts when forensics-up.sh runs. When locked, templates and scripts are ENOENT — the default profile structurally cannot touch them. This is enforcement-by-design, not enforcement-by-policy.

Keyfile setup (one-time)

echo -n '<password>' > /home/user/.forensics-keyfile
chmod 600 /home/user/.forensics-keyfile

Manual mount (if automount fails)

sudo cryptsetup luksOpen --key-file /home/user/.forensics-keyfile \
    /home/user/forensics.img forensics_crypt
sudo mount /dev/mapper/forensics_crypt /home/user/forensics

Forensics Lab

Tool Inventory — 3 Runtimes, 20 Checks (12 tools + 8 env)

RuntimeToolVersionAccess
Docker (host)volatility32.7.0forensics-vol3.sh CASE plugin
Docker (host)plaso20240512Timeline generation
Docker (host)analyzeMFT1.2.0.0MFT parsing
Docker (host)MemProcFS5.17+Memory dump → virtual filesystem mount
SIFT VM (SSH)Sleuth Kit4.12+sift-exec.sh "fls/icat/istat ..."
SIFT VM (SSH)TShark3.6.2Network capture analysis
SIFT VM (SSH)RegRipper3.0+Registry hive parsing
SIFT VM (SSH)foremost1.5.7File carving
SIFT VM (SSH)dc3dd7.3+Forensic imaging with hashing
SIFT VM (SSH)hashdeep4.4Known-good hash comparison
SIFT VM (SSH)photorec7.2+Photo/file recovery
SIFT VM (SSH)ddrescue1.27+Damaged disk recovery

SIFT VM

SIFT Workstation VM runs on VMware Workstation with NAT (vmnet8) networking — static IP , SSH on port 22. Bridged networking over WiFi causes DHCP lease expiration and IP drift between sessions — NAT is the fix. The SSH wrapper script (sift-exec.sh) handles the absolute key path requirement (profiles sandbox $HOME so ~/.ssh/ resolves wrong). Cold boot: vmrun -T ws start ~/vmware/SIFT/SIFT.vmx nogui (25–45s for SSH).

Bring-up (one command, ~60s)

bash /home/user/forensics/scripts/forensics-up.sh
# Opens LUKS → starts SIFT VM → waits for SSH → checks Docker → runs canary → reports status

New case (one command)

CASE_ID=$(bash /home/user/forensics/scripts/forensics-case.sh "Case Description")

Analysis workflow

# Register evidence (hash → verify → chmod → evidence.json → audit)
bash /home/user/forensics/scripts/forensics-register.sh $CASE ~/dump.mem "source_url" "sha256"

# Run volatility3
bash /home/user/forensics/scripts/forensics-vol3.sh $CASE windows.pslist.PsList
bash /home/user/forensics/scripts/forensics-vol3.sh $CASE windows.netscan.NetScan

# Mount MemProcFS
bash /home/user/forensics/scripts/forensics-mount.sh $CASE

# Record findings
bash /home/user/forensics/scripts/forensics-find.sh $CASE "Title" HIGH "tool" "cmd" "EVID" "raw" "finding"

# Screenshots of raw tool output
python3 /home/user/forensics/scripts/forensics-screenshots.py /home/user/forensics/cases/$CASE

# Generate reports (data-first + timeline)
bash /home/user/forensics/scripts/forensics-report.sh $CASE --html
bash /home/user/forensics/scripts/forensics-report.sh $CASE --pdf

Report templates

TemplateStyleUse Case
data-first-report.html White + ink, 01–10 numbered sections, sidebar nav, finding cards, data-table timeline, 15px exec summary Corporate delivery, print/PDF, legal review, client handoff
timeline-report.html Dark theme, visual swimlane timeline, color-coded dots Interactive viewing, GitHub Pages demo
Design rules (user-enforced): Zero emoji. Colored CSS squares for section markers. Monospace text tags [MALWARE] [C2] for timeline events. Prominent exec summary with gradient callout + thick blue left border. Appendix references PNG screenshots, not inlined text. Reports generated from structured JSON (findings.json + evidence.json + timeline.json), not hand-written.

Shutdown

bash /home/user/forensics/scripts/forensics-down.sh
# Unmounts MemProcFS → stops SIFT VM → locks LUKS

Pentest Lab

Docker Containers

ServiceImageNetworkPurpose
kali-webkalilinux/kali-rollinghostWeb app testing (Burp, ZAP, ffuf, sqlmap)
kali-netkalilinux/kali-rollinghostNetwork scanning (nmap, masscan, crackmapexec)
osint-toolskalilinux/kali-rollingbridgeOSINT (theHarvester, amass, subfinder)
neo4jneo4j:5-communitybridgeBloodHound graph database
Host networking required: nmap raw sockets, crackmapexec SMB, and responder need network_mode: host. Docker Desktop users: set up a Linux VM with bridged networking.

Vault layout

/home/user/pentest/
├── engagements/        # Per-engagement: findings, reports, screenshots
├── keys/               # SSH keys, API tokens
├── wordlists/          # SecLists, custom
├── tools/              # Standalone tool binaries
└── docker/
    └── volumes/        # neo4j data, persistent tool storage

Bring-up

bash /home/user/pentest-repo/scripts/pentest-up.sh
# Mounts LUKS vault → starts Docker containers → verifies VPN → runs canary

VPN (WireGuard)

WireGuard interface wg0 connects to . Detection pitfall: /sys/class/net/wg0/operstate reports "unknown", not "up". Check with != "down" — any non-down state is active.

Report generation

python3 /home/user/pentest-repo/scripts/build-report.py \
    --engagement-dir /home/user/pentest/engagements/<name> \
    --output-pdf report.pdf --output-html report.html

Dark gradient cover · 4-category scorecards · findings heatmap · inline evidence screenshots · business-first descriptions · observed controls with values · remediation checklist · A4 portrait print-native

Dispatch System

The dispatch mechanism is Hermes Agent's one-shot mode (-z / --oneshot). Each call boots the profile fresh, loads its SOUL + skills + memory, executes the task, prints the result, and exits. No conversational state carries between dispatches.

Foreground dispatch (~60s — canaries, single-phase tasks)

hermes -z "Run canary and report pass/fail." --profile forensics

Background dispatch (8–12 min — full engagements)

Foreground hermes -z has a 600-second hard limit. Full pentest engagements and multi-phase forensics analyses WILL time out. Always use background mode with notify_on_complete=true for full engagements.
# In terminal tool: background=true, notify_on_complete=true
hermes -z "Run full pentest engagement against example.com.
  Scope: example.com and *.example.com. Run canary first.
  Execute all 7 workflow phases including report generation.
  Report the PDF path when done." --profile pentest

Prompt construction checklist

ElementExampleWhy
Absolute paths/home/user/Downloads/dump.memProfiles sandbox $HOME
Canary firstRun canary first, report degraded toolsCatch tool failures before evidence analysis
Scope boundariesScope: example.com and *.example.comPrevent scope creep
Output requestReport the PDF path when doneManager knows where to find artifacts
BrevityKeep it shortWorker profile skills fill in the workflow

Health Check

bash /home/user/.hermes/scripts/check-labs
=== PENTEST ===
=== Results: 14 passed, 0 failed ===
✓ All services operational — ready for engagement

=== FORENSICS ===
=== Results: 20 passed, 0 failed ===
✓ All runtimes operational — ready for investigation

One command, both canaries. Forensics checks 3 runtimes (Docker, SIFT VM, MemProcFS) across 20 checks (12 tools + 8 env). Pentest checks 14 services (Docker, VPN, LUKS, tools). Degraded tools are marked for triage-only; the agent handles recovery reasoning.

Dispatch verification (first-time setup)

# Verify CLI one-shot mode
hermes --help | grep '\-z'

# Test basic dispatch
hermes -z "Say the hostname and exit." --profile forensics
hermes -z "Say the hostname and exit." --profile pentest

# Full canary dispatch
hermes -z "Run the session canary and report pass/fail." --profile forensics
hermes -z "Run the pentest canary and report pass/fail." --profile pentest

Folder Layout

PathWhatGate
/home/user/.hermes/profiles/forensics/Forensics profile — SOUL, skills, config, .envNone
/home/user/.hermes/profiles/pentest/Pentest profile — SOUL, skills, config, .envNone
/home/user/.hermes/scripts/check-labs5-line health check — runs both canariesNone
/home/user/.hermes/skills/devops/lab-manager/Manager skill — routing rules, dispatch, pitfallsNone
/home/user/forensics/LUKS mount — cases, scripts, templates, toolsKeyfile
/home/user/forensics/cases/INC-YYYY-MMDD-NNNN/Per-case: evidence, raw/, reports/, findings.json, audit/Vault mount
/home/user/forensics/scripts/Automation: canary, sift-exec, up/down, report, vol3, find, case, register, mount, screenshotsVault mount
/home/user/forensics/templates/Report templates (data-first + timeline)Vault mount
/home/user/forensics/tools/tool-catalog.yamlTool registry — versions, entrypoints, pitfallsVault mount
/home/user/forensics/fixtures/Known-good test fixtures for canary validationVault mount
/home/user/pentest/LUKS mount — engagements, keys, wordlists, Docker volumesKeyfile
/home/user/pentest-repo/Scripts and skills — git-tracked, outside vaultNone
/home/user/pentest-repo/scripts/pentest-canary.sh14 checksNone
/home/user/pentest-repo/scripts/pentest-up.shContainer + VPN startupNone
/home/user/pentest-repo/scripts/pentest-down.shGraceful shutdownNone
/home/user/pentest-repo/scripts/build-report.pyAutomated pentest report generationNone
/home/user/pentest/docker/Docker Compose + per-container build contextsVault mount
/home/user/vmware/SIFT/SIFT Workstation VM filesNone
/home/user/hermes-forensics-lab/Public repo — README, sample reports, docsNone
/home/user/hermes-lab-management-dashboard/Public repo — boot flow, tray launcher, architecture diagramNone

Replicating This Setup

Step 1: Prerequisites

# Ubuntu 24.04+ with Docker, VMware, Hermes Agent
sudo apt install -y docker.io docker-compose-v2 wireguard-tools cryptsetup pandoc weasyprint
pip install psutil       # for desktop widget

Step 2: Clone the lab repos

git clone https://github.com/jayelbotvibe-web/hermes-forensics-lab.git ~/hermes-forensics-lab
git clone https://github.com/jayelbotvibe-web/hermes-pentest-lab.git ~/pentest-repo

Step 3: Create LUKS vaults

# Forensics vault (30 GB)
dd if=/dev/zero of=/home/user/forensics.img bs=1M count=30720
sudo cryptsetup luksFormat /home/user/forensics.img
sudo cryptsetup luksOpen /home/user/forensics.img forensics_crypt
sudo mkfs.ext4 /dev/mapper/forensics_crypt
sudo mount /dev/mapper/forensics_crypt /home/user/forensics
sudo chown $USER:$USER /home/user/forensics

# Pentest vault (10 GB)
dd if=/dev/zero of=/home/user/pentest-vault.img bs=1M count=10240
sudo cryptsetup luksFormat /home/user/pentest-vault.img
sudo cryptsetup luksOpen /home/user/pentest-vault.img pentest-vault
sudo mkfs.ext4 /dev/mapper/pentest-vault
sudo mount /dev/mapper/pentest-vault /home/user/pentest
sudo chown $USER:$USER /home/user/pentest

Step 4: Set up keyfiles (passwordless mount)

echo -n '<password>' > /home/user/.forensics-keyfile
echo -n '<password>' > /home/user/.pentest-keyfile
chmod 600 /home/user/.forensics-keyfile /home/user/.pentest-keyfile

# Add forensics to crypttab (noauto — manual mount only)
echo "forensics_crypt /home/user/forensics.img /home/user/.forensics-keyfile luks,noauto" | \
  sudo tee -a /etc/crypttab

Step 5: Set up SIFT VM

# Download SIFT OVA from SANS Portal, import into VMware
# Configure NAT networking (vmnet8) with static IP 
# SSH key copy: ssh-copy-id user@

Step 6: Build Docker images

# Forensics tools
docker build -t forensics-volatility3:2.7.0 ~/hermes-forensics-lab/tools/volatility/
docker build -t forensics-plaso:20240512 ~/hermes-forensics-lab/tools/plaso/
docker build -t forensics-mft-tools:1.2.0.0 ~/hermes-forensics-lab/tools/mft-tools/

# Pentest tools
cd ~/pentest-repo/docker && docker compose build

Step 7: Create Hermes profiles

hermes profile create forensics
hermes profile create pentest

# Copy API keys
cp ~/.hermes/.env ~/.hermes/profiles/forensics/.env
cp ~/.hermes/.env ~/.hermes/profiles/pentest/.env

Step 8: Install lab-manager skill

mkdir -p ~/.hermes/skills/devops/lab-manager
# Copy SKILL.md from this repo or the hermes-lab-manager repo

Step 9: Install health check

cat > ~/.hermes/scripts/check-labs << 'EOF'
#!/bin/bash
set -e
echo "=== PENTEST ===" && bash /home/user/pentest-repo/scripts/pentest-canary.sh 2>&1 | tail -3
echo "" && echo "=== FORENSICS ===" && bash /home/user/forensics/scripts/session-canary.sh 2>&1 | tail -3
EOF
chmod +x ~/.hermes/scripts/check-labs

Step 10: Verify

bash ~/.hermes/scripts/check-labs
hermes -z "Run canary and report pass/fail." --profile forensics
hermes -z "Run canary and report pass/fail." --profile pentest

Daily Workflow

# 1. Check both labs
bash ~/.hermes/scripts/check-labs

# 2. Route a forensic task
hermes -z "Run canary. Analyze network capture at /home/user/Downloads/capture.pcap.
  Use tshark on SIFT VM. Open a case, register evidence, identify IOCs.
  Generate data-first report with screenshots. Report summary when done."
  --profile forensics

# 3. Route a pentest task
hermes -z "Run canary. Passive OSINT on example.com. Zero packets.
  Use theHarvester, crt.sh. Return subdomains, emails, exposed tech.
  No active scanning." --profile pentest
↑ Back to top