Inspiration

Security Operations Centers are drowning in alerts. A single SOC analyst can face hundreds of log entries a day, and every one of them demands the same three questions: How bad is this? What technique is being used? What do I do next?

Most tools either dump raw logs on analysts with no context, or wrap an LLM around a chatbot with no grounding in real threat intelligence. I wanted to build something in between — a tool that reasons like a junior analyst, backed by real MITRE ATT&CK data, not just a language model guessing at security concepts.

GhostPulse IR Copilot started as an earlier no-code prototype I built to explore this idea. This version is a complete, from-scratch rebuild — real backend, real matching logic, and a real AI reasoning pipeline.

What it does

GhostPulse IR Copilot takes a raw log line, alert text, or structured JSON payload and turns it into a complete incident triage report in seconds:

  • Local MITRE ATT&CK matching — indicator-based keyword matching against a curated dataset of real ATT&CK techniques, so technique identification doesn't depend on the LLM getting it right
  • AI-powered reasoning — Groq-hosted Llama 3.3 70B analyzes the alert alongside the matched techniques to produce a severity rating (Critical/High/Medium/Low), a plain-English explanation of why, and concrete next actions
  • One-click IR ticket drafting — turns the full analysis into a copy-pasteable incident report, formatted and ready to paste into Jira, ServiceNow, or any ticketing system
  • Graceful degradation — if the AI service is unavailable, the tool falls back to a heuristic triage mode instead of failing outright, so it's never fully offline

How I built it

The stack is deliberately minimal:

  • Go (standard library net/http) for the backend — no framework overhead, single binary deployment
  • HTMX for the frontend — dynamic, partial-page updates without writing a line of JavaScript framework code
  • Tailwind CDN for styling — a dark, analyst-friendly UI with no build step
  • Groq API (Llama 3.3 70B) for the reasoning layer — fast inference, structured JSON output

I built it using a vertical-slicing approach: each development phase shipped a complete, testable feature end-to-end rather than building isolated layers. Phase 1 was a working input pipeline, Phase 2 added local MITRE matching, Phase 3 wired in the LLM, Phase 4 added ticket drafting, and Phase 5 was a full polish pass — dark theme, error handling, example alerts, and documentation.

Challenges I ran into

  • Balancing local logic vs. LLM reasoning. Letting the LLM guess MITRE techniques on its own risked hallucinated or inconsistent mappings. Solving this meant doing technique matching locally first, against real ATT&CK data, and only handing the matched techniques to the LLM for reasoning — not asking it to invent the mapping itself.
  • Structured output reliability. LLMs don't always return clean JSON on the first try. I built in a retry path with a stricter prompt if the first parse fails, so the pipeline degrades gracefully instead of crashing.
  • Keeping it a real tool, not a wrapper. It was tempting to just pipe everything straight to the LLM. Building the local MITRE dataset and matching logic first — before ever calling the AI — was what made this feel like an actual security tool rather than a prompt with a UI on top.

What I learned

Building this reinforced that the most useful AI security tools aren't the ones that trust the model the most — they're the ones that give the model the least room to be wrong. Grounding the LLM's reasoning in locally verified data, rather than asking it to do everything from scratch, made the output dramatically more reliable and trustworthy for a real analyst workflow.

Built With

Share this project:

Updates

Submission history