title: How We Used FalkorDB to Make a Security Alert Explain Itself
published: true
tags: falkordb, ai, security, hackathon
Our entry for Graph Hacks by WeMakeDevs × FalkorDB.
Where this started
Picture a security analyst looking at an alert that says "suspicious network activity on a workstation." Is that nothing, or is it the middle of an attack? The alert alone can't tell you. What helps is context: whose machine is it, what has it been involved in before, and is any of that linked to an incident someone already confirmed?
That's really a question about connections, so we built GraphGuard around a graph database, FalkorDB.
What we built
GraphGuard is a small security investigation tool. There's a Streamlit page you click around in, a FastAPI backend, an agent that runs the investigation, and FalkorDB running in one Docker container.
The data is all made up: users, devices, IP addresses, alerts, incidents and evidence, about 76 nodes and 81 relationships to start with. The links look like this:
(User)-[:USED]->(Device)
(Device)-[:INVOLVED_IN]->(Alert)
(Alert)-[:ASSOCIATED_WITH]->(Incident)
(Incident)-[:SUPPORTED_BY]->(Evidence)
The agent has four graph tools: one to fetch a node, one to walk outwards up to two hops, one to find past incidents that share an entity with the alert, and one to save the finished investigation back into the graph.
What the graph actually does
When we investigated alert_004, the traversal turned up this path:
alert_004 → user_eve → dev_w005 → evidence → inc_001 → alert_001
You can read that like a short story. The same user and device sit next to a confirmed credential-theft incident and an earlier alert. The risk score comes from the alert's own severity plus what the graph turns up (devices, confirmed incidents, evidence, earlier investigations), and suggestions like "isolate device dev_w005" come from the entities the traversal found.
Memory
Every investigation gets saved into FalkorDB. When we ran alert_004 again later, the tool pulled up four earlier investigations as context. Nothing is kept in the app's memory, it's all stored in the graph, so it's still there after a restart.
One thing that broke
Our first query used last(r) on variable-length paths, and FalkorDB didn't accept it. We swapped it for separate depth-1 and depth-2 queries. A scratch file, tmp_debug.py, is still in the repo from that debugging.
What it isn't
I'd rather be upfront about this:
- The demo runs in a deterministic mode. It runs real graph queries but doesn't call an LLM. There's an Anthropic mode in the code that we haven't tested.
- The risk score is a simple heuristic, not tuned on real security data.
- Two alerts can differ in risk partly because of their own severity, not only because of how they're connected.
- The data is tiny and synthetic, and there's no authentication. It's a local demo.
About us
We're AI students, and this project was a team effort. Working through GraphGuard, from the graph model to the investigation flow, taught us a lot about how graph databases can give an agent real context. It was a fun project to learn from.
Try it
Start FalkorDB with docker compose up -d, load the data, then start the backend and frontend. Setup steps and the graph schema are in the repo: https://github.com/AJ615/graphguard
Top comments (1)
Proud to be part of the GraphGuard project! Building this project was a valuable learning experience, especially in exploring how FalkorDB and graph-based relationships can help make security alerts more explainable. Collaborating with the team helped us strengthen our technical skills and understand the practical applications of AI and graph databases in cybersecurity. Excited to keep learning and building!