CSX has seen the simulated loop. The next cut is the real one: real Linux hosts running real platform software with real, exportable vulnerabilities — scanned by a real scanner, patched by real Ansible, and re-scanned to prove the fix. No CSX systems touched. Everything stands up in our environment, resets in seconds, and runs end-to-end through the same twelve agents.
"Instead of, like earlier, we demonstrated actual simulation — instead, we have real software, and in real time how it's scanning, get the scanner, and how the patching is done, everything end-to-end."
"The exact same thing what you are doing on the OS level — we wanted to perform that on the platform level."
"A clean environment outside" — avoids CSX security approvals and access questions.
"Any Linux platform, any version… default installation for some of our products" — Liberty, Tomcat, open-source middleware.
"Right now, we use Ansible." Some products patch via vendor scripts.
"Qualys or some scanner reports vulnerabilities… the approval process… how the patching is done, end-to-end."
Was: a scenario engine minted synthetic MCR-SIM-* findings on a timer.
Now: a real scanner fingerprints real running software and reports real CVEs with real CVSS, EPSS, and KEV status.
Was: the Executor wrote a fake play_recap after a time.sleep().
Now: the Executor runs a real ansible-playbook over SSH that actually upgrades the software on the target host.
Was: the loop "closed" because the FSM said so.
Now: the Verifier triggers a real re-scan; the CVE is gone because the version is genuinely patched. Truth, not assertion.
target-tomcat — Apache Tomcat 9.0.30 on Debiantarget-liberty — Open Liberty (WebSphere family), older pintarget-log4shell — Java app bundling log4j-core 2.14target-linux — stale OS packages (openssl, etc.)scanner — Trivy engine (default): reads versions, emits FixedVersionVulnerabilityFindingapi + console — twelve agents, policy gate, consoleansible-control — ansible-core, playbooks, SSH keyspostgres · redis — already in the stackOne docker-compose.poc.yml overlay extends the existing stack. Targets sit on an isolated bridge network; no host other than ours is reachable. Ports chosen outside the in-use block (targets internal-only; OpenVAS UI :9392, AWX :8095 if enabled).
| Target | Pinned version | Headline CVE | Sev | Real remediation (Ansible) | Verify |
|---|---|---|---|---|---|
| Apache Tomcat target-tomcat |
9.0.30 |
CVE-2020-1938 "Ghostcat" — AJP file read / inclusion |
9.8 | Upgrade distribution to 9.0.x (fixed ≥ 9.0.31); reload service |
Re-scan: version now ≥ fix → finding clears |
| Open Liberty target-liberty |
older pin* | Liberty runtime advisory (SSRF / info-disclosure class) | High | Bump Liberty runtime to fixed release; restart server | Re-scan: runtime build ≥ fix → clears |
| Log4Shell app target-log4shell |
log4j-core 2.14 |
CVE-2021-44228 "Log4Shell" — JNDI RCE |
10.0 | Replace jar with 2.17.1; restart app |
Re-scan: jar hash/version → clears (drama: KEV + ransomware-linked) |
| Linux base target-linux |
stale openssl |
CVE-2022-0778 — BN_mod_sqrt() infinite loop (DoS) |
High | ansible apt/dnf upgrade openssl |
Re-scan: package version ≥ fix → clears |
*Exact Open Liberty pin and its reported CVE set are fixed at lab-build time against the live scanner output, so we present only what the scanner genuinely reports — no claimed CVE we can't show on screen.
Fingerprints the running middleware and OS packages, maps to CVEs with CVSS/severity, and — critically — emits a FixedVersion per finding.
Deterministic, fast, repeatable. The same scan returns the same findings every demo. That reliability is what wins the room.
A true authenticated network vulnerability scanner — the closest open-source analog to Qualys. Same shape of output, more "scanner theater," heavier and slower.
We wire it as a second connector for buyers who want to watch a network scan run.
In a real deployment Mythal reads CSX's existing Qualys. The connector is the same shape — trigger / poll / normalize — so the POC connector and the production connector are interchangeable.
FixedVersion field feeds two agents at once: the Patch Hunter reports the fix without guessing, and the Executor's Ansible playbook gets its exact target version from the same field. The fix the scanner names is the fix Ansible installs — closed, grounded, no hand-waving.The Executor agent stops simulating. On an approved plan it invokes a real ansible-playbook from the ansible-control container against the target over SSH. The play's real play_recap (ok/changed/failed) lands in the executions row and streams to the console plan-detail page exactly as today.
One playbook per software class — Tomcat upgrade, Liberty bump, jar swap, OS package update — parameterized by the FixedVersion the scanner reported.
Stretch: route through AWX (open-source Ansible Automation Platform) so the Integrations screen shows a real job-template launch and the Executor calls the AWX REST API — the same pattern CSX would use with Ansible Automation Platform in production.
FixedVersionansible-playbookOn the console, every step above appears in real time on the Agent Activity timeline and the plan Kanban — the same audit theatre as today, now backed by real scanner JSON and real Ansible recaps.
Between step 07 and 08 the version on the box genuinely changes. The re-scan is not staged — it queries the same Trivy engine and the finding is simply no longer there.
make poc-reset tears the targets back to their vulnerable pin and clears Mythal state in under 30 seconds. Run the whole loop again, live, on demand.
| Edge | Today (simulated) | POC (real) | Where |
|---|---|---|---|
| Scanner in | scenario engine mints MCR-SIM-* | ScannerConnector: trigger Trivy/OpenVAS, parse JSON, call ingest_finding() with real CVEs | packages/connectors/scanner/ + routes/scan.py |
| Patch lookup | static fix strings | Patch Hunter consumes scanner FixedVersion; OS feeds for distro packages | agents/patch_hunter/ |
| Executor out | time.sleep() + fake recap | AnsibleExecutor: real ansible-playbook (or AWX API), real recap into executions | agents/executor/ + connectors/ansible/ |
| Integrations health | hardcoded _INTEGRATIONS list | live probes: scanner reachable, Ansible reachable, NVD/KEV reachable, targets up | routes/integrations.py |
The Integrations page renders a fixed list of twenty-two connectors with "status":"healthy" baked in. Impressive breadth, but none of it is probed.
For an investor flyover that's fine. For a CISO POC, a fabricated health light is a credibility risk the moment someone asks "is that real?"
Each connector in scope reports actual health from a real probe:
Connectors we haven't wired stay clearly marked not_configured — honest beats impressive.
Run the scan live. CVE-2020-1938 lands on target-tomcat, KEV-listed, CVSS 9.8. Agents enrich, plan, you approve, Ansible upgrades Tomcat, re-scan clears it. ~3–4 min, fully real.
CVE-2021-44228, CVSS 10.0, ransomware-linked in KEV. Show the platform reprioritize, fast-track approval, swap the jar, and verify. The CVE everyone in the room already fears.
The WebSphere-family story CSX named. Liberty runtime bump and an openssl OS update via Ansible — two more real loops, proving it's a pattern, not a one-off trick.
Author docker-compose.poc.yml: four vulnerable target containers (Tomcat 9.0.30, Open Liberty, Log4Shell app, stale-OS Linux), SSH-enabled, isolated bridge network. Confirm each boots and is reachable.
Stand up Trivy as a scan service; build ScannerConnector + /api/scan/run; parse JSON into real VulnerabilityFinding events. Findings appear on the console for real software. (OpenVAS as time permits.)
ansible-control container + four playbooks parameterized by FixedVersion. Rewire the Executor to run real plays. Confirm a patch actually upgrades a target.
Verifier triggers real re-scan; finding clears; FSM reaches CLOSED on truth. Replace Integrations health with live probes. Wire the three scenarios + make poc-reset.
Dry-run all three scenarios end-to-end, tune timings, confirm sub-30s reset, write the demo runbook addendum. Ship to CSX.
AWX and OpenVAS are stretch items layered after the core loop is green — they raise production fidelity but are not on the critical path to "real end-to-end."
Targets live on a private bridge network. Nothing routes to CSX. Vulnerable containers expose no ports to the host beyond what the demo needs.
Pinned image digests + Trivy's stable DB snapshot mean the same findings every run. No flaky live-internet dependency in the hot path.
Every playbook snapshots before it changes anything. make poc-reset restores the vulnerable baseline in seconds.
Scanner output and advisory text stay untrusted input — wrapped and classified, never executed as instructions. The existing prompt-injection harness still applies.
Lead with Trivy for reliability, or invest the extra day in OpenVAS for the authentic "watch a network scan" moment? Recommended: Trivy core, OpenVAS as stretch.
Bare ansible-core (fast, real) or AWX (production-grade UI/API, +1 day)? Recommended: ansible-core for the loop, AWX if CSX wants to see the platform.
Keep Log4Shell as the drama scenario, or swap for another CSX-named product if one is available open-source? Recommended: keep Log4Shell — it's KEV, it's CVSS 10, it lands.