ENGINEERING JOURNAL · AUGUST 2026

Building the Cyber Operations Center Engineering Program

The biggest change wasn't installing another security tool. It was deciding that every part of the lab had to belong to the same system—and that “finished” had to mean more than “it runs.”

I had already built pieces of a security lab before this program existed. There were networking projects, monitoring tools, backup work and a home SOC. They taught me a lot, but they also accumulated the kind of problems that are easy to ignore in a personal lab: undocumented dependencies, configuration drift and screenshots that showed a dashboard without proving the system behind it.

I reached a point where adding one more service would have made the environment bigger, but not necessarily better. I wanted to know what was actually running, why it was there, how I had validated it and how I would recover it if the next change went badly. That is why I stopped treating the work as a collection of projects and started the Cyber Operations Center Engineering Program.

I chose to rebuild instead of patching around the past

The first difficult decision was a clean-slate rebuild. Incremental repair would have been easier in the short term, but it would also have carried forward things I could no longer explain confidently. I kept the reviewed exports, inventories, evidence and lessons I needed, then rebuilt from a documented baseline.

That made the early work slower. Before wiping anything, I needed an inventory, backups and a recovery path. It also gave the later phases a much better foundation. Every service added after that point had a place in the architecture and a record of how it was tested.

I moved backup and recovery earlier than a neat roadmap might suggest. Losing a configuration after weeks of work is a convincing lesson, but not one I needed to repeat. The resulting backup phase covers approved server data, a Windows workstation and a laptop, with encrypted versioned snapshots and real restore tests. A successful backup message is useful; getting the files back and comparing them is what made me trust it.

What is actually built now

The completed foundation runs on an Ubuntu server named Atlas. Docker and Dockge provide the container platform, while Caddy keeps the management interfaces behind private HTTPS access. WireGuard is the remote entry point, and the firewall limits management access to approved local and VPN paths.

The network and security layer now includes Wazuh monitoring, Pi-hole DNS filtering and scheduled ClamAV scanning. I validated the malware path with the harmless EICAR test file and confirmed that the event reached Wazuh. Suricata was introduced carefully after an early capture attempt disrupted the temporary wireless path, and the current wireless design still limits broader packet visibility. Calling that limitation out is more useful than pretending every installed component has perfect coverage.

NET-WATCH adds network visibility and service controls. The telemetry phase added Zeek metadata, Prometheus metrics, Grafana dashboards and Graylog aggregation for operational logs that do not belong in Wazuh. The most important result is not the number of dashboards. It is that DNS activity, host and container health, backup status, security alert volume and application logs now have defined places to go.

Endpoint engineering is also complete for the current scope: a Windows 11 laptop, a legacy Windows 10 workstation, a Galaxy S25 and a Galaxy Tab A11. Each platform has its own documented baseline and exceptions. The next workstation migration is still planned work, and the later detection, response, automation and cloud phases have not started.

The failures became part of the design

One of the more useful moments came when I tried to start Suricata capture on the server's temporary wireless interface. The configuration checked out, but the interface lost usable connectivity. That took SSH and the web dashboards with it. I recovered from the local console and left Suricata disabled until there is a wired capture path.

That was a good reminder that a valid configuration is not the same as a safe production change. It also reinforced why remote network work needs a local recovery option and why controls should be introduced in stages.

DNS produced its own lesson. After changing the server address, old bookmarks stopped resolving because of a stale hosts-file entry on the administrative workstation. The server was fine; the forgotten local override was the problem. These are small failures, but they are exactly the parts I want to remember because they change how I approach the next build.

Documentation is part of the build

I used to think of documentation as the work I would do after the technical part was finished. This program forced me to treat it as a control of its own. Each phase now has objectives, implementation notes, validation, security considerations, evidence boundaries and lessons learned. Architecture decisions record why I accepted a tradeoff instead of leaving the reasoning buried in a terminal history.

That also means being careful about what I publish. The repository can show that a control was tested without exposing private addresses, device identifiers, keys, credentials or raw logs. Learning to produce useful evidence without turning the portfolio into a map of the environment has been part of the engineering work.

What I would do differently now

I would start with governance, recovery and evidence much sooner. I would be more suspicious of any milestone defined only by installation, and I would separate “configured,” “validated” and “operational” from the beginning. I would also resist adding a tool until I could explain what data it owns and how it fits with the tools already there.

The program is still in active development, but it finally has a trustworthy foundation. More importantly, I can point to the repository and show not only what I built, but where it failed, what remains limited and what evidence allowed me to call each completed phase complete. That is the part of the project I am proudest of.

Explore the COC Engineering Program on GitHub

← Back to the engineering journal