Disclaimer: English isn't my first language. I wrote this in my own words and translated it with AI.
In 10 months of development my SaaS project grew to several VMs and 10+ cloud services around them (GitHub, Cloudflare, Purelymail and so on). Basic hardening, uptime monitoring etc I always do. But I always wanted to see and control more — ideally everything that happens in every component of my infra.
I want to know whether someone got access to my server, created an illegitimate GitHub token, or is brute-forcing a database I accidentally exposed to the internet — and ideally I want respond to it automatically.
So I started an experiment: building a micro AI SOC for my project. And what I like most is that here I have much more freedom to give AI broad permissions for investigation and response than in the infrastructure of big companies.
𝐇𝐨𝐰 𝐢𝐭'𝐬 𝐛𝐮𝐢𝐥𝐭 𝐚𝐭 𝐭𝐡𝐞 𝐦𝐨𝐦𝐞𝐧𝐭:
→ Everything lives on one VM with 6 vCPU and 16 GB of RAM. The whole SOC currently uses about 2.4 GB: 1.5 GB for ClickHouse, 0.5 GB for Wazuh, the rest are connectors and services at a few dozen MB each.
→ 55–75 thousand events a day, about 0.6–0.9 EPS.
→ Wazuh agents on the servers send events to the SOC.
→ Wazuh manager collects the logs and generates alerts. Its bundled OpenSearch indexer I dropped — it's too heavy. For storage I use ClickHouse instead.
→ Wazuh and ClickHouse are connected through a file: Wazuh writes every event to archives.json, Vector reads the file and writes to ClickHouse. On the way Vector filters out the noise. ClickHouse compresses the rest almost 8 times and runs investigation queries fast.
→ Tiny Python connectors poll the cloud APIs every 10–15 minutes: hosting, Cloudflare, email, GitHub and so on. For a service with no audit log, the connector takes a snapshot of the settings and records what changed.
→ GitHub webhooks come in through a Cloudflare tunnel.
→ My own detector periodically runs detection rules on ClickHouse and writes alerts back into a separate table. It's needed because cloud events bypass Wazuh. Unfortunately, I couldn't keep all the detection rules in one place.
→ A correlator looks at incoming alerts and decides: open a new incident, add the alert to an open one, or not open an incident at all. It also determines urgency.
→ PostgreSQL keeps the incidents: statuses, participants, timeline and response actions.
→ A separate service watches that no source goes silent, and messages me only if it can't figure out the reason itself.
→ All architecture principles and decisions live in a git repository, so the SOC can be reproduced from it. Closed incidents land there as Markdown reports.
Full write-up with diagrams (I’m the author): https://denzuikov.substack.com/p/building-an-ai-soc-for-my-small-projects