July 13, 2026
Turning my Open Source Security Tool into a SaaS Product
Week 1 of turning ChainFire into a SaaS product

By Aleksa Zatezalo
4 min read
I'm starting a public build log. Every week (roughly), I'll document what I shipped, what broke, and what I decided not to build yet, as I try to turn ChainFire, an open source security scanner I wrote, into something closer to a real product.
This is Week 1.
What ChainFire is
ChainFire is a web-based security testing platform that chains together two tools most AppSec engineers already know: Semgrep for static analysis and Nuclei for dynamic, over-the-wire probing. The idea is simple — Semgrep finds a suspicious pattern in source code (say, an unsafe pickle.loads() call), and that finding automatically drives which Nuclei templates get run against the live application. Static analysis picks the lock; dynamic analysis walks through the door and confirms it's actually open.
Concretely, it gives you:
- Chained Scan mode — Semgrep's full ruleset plus your own custom rules run against source, findings get tokenized and mapped to Nuclei tags through a keyword table (
pickle→rce,sqli→sqli/time-based-sqli, and so on), and Nuclei only fires the templates that match. If Semgrep finds nothing, Nuclei doesn't run at all — no noisy blind spraying of every template. - Custom Rules mode — for when you already know exactly which Semgrep rule and which Nuclei template you want to pair, with no automatic mapping in between.
- Scheduled scans — recurring runs from every 15 minutes to every 7 days, fired by a background thread that checks for due schedules.
- Agentic exploit generation — click a Nuclei finding and an AI agent (built on Claude) probes the target and writes a self-contained, non-destructive Python exploit script you can download. This runs in the background so you can navigate away and come back to it later.
- Resource management for rules, templates, and wordlists, PDF report export, and a basic session-based auth system with admin approval and security-question password reset.
Under the hood it's a two-container Docker Compose stack: a React frontend served by nginx, and a Django REST backend that wraps the Semgrep and Nuclei binaries and runs scans as background threads so the API stays responsive.
Why I built it
I built ChainFire because I kept doing the same manual dance during white box penetration tests: run Semgrep, squint at the findings, manually decide which Nuclei templates were even relevant, run those separately, and then stitch the two result sets together myself to figure out which static findings were actually reachable and exploitable at runtime versus which were theoretical. That correlation step — "this code smell is real because I can trigger it over HTTP" — is where a lot of the actual validation work happens, and it was entirely manual.
ChainFire automates that correlation. I use it today to hunt for and validate findings during white box engagements: point it at a codebase and a running instance of the same app, let the chained scan connect static patterns to live behavior, and use the exploit generation feature to turn a Nuclei hit into a proof-of-concept I can hand to a client instead of a line item that says "possibly exploitable."
That's the tool as it exists today: a solid local proof of concept for a single tester working on a single engagement.
Where I want to take it
The long-term shape I have in mind is bigger than a personal pentesting utility. Two directions I'm actively thinking about:
- A DAST that runs organization-wide across GitHub PRs — instead of a tester manually pointing ChainFire at one repo and one target, it hooks into an org's GitHub, runs the chained scan against every PR (or every repo) automatically, and surfaces validated, exploit-confirmed findings before code merges.
- A CTEM (Continuous Threat Exposure Management) tool — a persistent, scheduled, org-wide version of what the scheduler already does at the single-scan level, giving a security team continuous validated visibility into what's actually exploitable across their attack surface, not just a point-in-time report.
Both of those require the same next foundational step: ChainFire has to stop being a single-user local tool and become a multi-tenant product. That's the actual subject of this build log — I want to document the unglamorous but necessary work of turning a working local POC into something that can hold more than one organization's data safely.
Where things stand right now
The current state is a genuine, working local proof of concept:
- Chained and custom-rule scanning against local source and live targets
- Custom-configured Semgrep rules, Nuclei templates, and wordlists, editable in the browser
- Scheduled scans via a background polling thread
- A basic authentication system: session-based login, first-user-becomes-admin, admin approval for everyone else, and security-question-based password reset
It's genuinely useful in its current form — I've used it on real engagements — but the auth model is intentionally minimal (single-tenant, one shared instance, no organizations) and everything assumes one trusted operator running it on localhost or behind a VPN. That's fine for a solo tester. It's not fine for a product other people's security teams would run.
What's next: Phase 2
The next phase of work is entirely about the infrastructure a real multi-tenant product needs before any of the DAST/CTEM feature work makes sense. In rough priority order:
- Proper multi-tenant authentication with SSO integration — moving off the current single shared-instance session auth toward organization-scoped accounts, with SSO so teams can plug in their existing identity provider instead of managing yet another password.
- Invite links for organizations — replacing the current "first user becomes admin, everyone else waits for manual approval" flow with a proper invite-link system so an org admin can bring teammates in directly.
- Email-based password reset — the current security-question reset is a reasonable stopgap for a single local install, but it doesn't scale to a real user base and isn't a pattern I want in a product. This becomes a standard token-based reset flow delivered over email.
- Jira ticket creation — letting a validated finding turn directly into a Jira ticket in the team's own project, so ChainFire output plugs into an existing triage workflow instead of living only inside the app.
- Proper RBAC — real role-based access control at the organization level (think: admin, analyst, read-only) instead of the current binary "admin vs. approved user" model.
- Use OpenGrep instead of SemGrep — and use it's feature to implement taint tracking.
None of these are the interesting security engineering — Semgrep-Nuclei correlation, tag mapping, agentic exploit generation, that's the part I already enjoy building. This next phase is the boring, necessary plumbing that has to exist before I can honestly call this a SaaS product instead of a really good local tool. I'd rather build it in the open and be honest about that than skip straight to features that assume a foundation I haven't built yet.
If you want to follow along or poke at the code as it evolves, the repo is here: github.com/AleksaZatezalo/ChainFire.
Week 2: multi-tenancy and SSO.